1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrGpuResourceCacheAccess_DEFINED
9 #define GrGpuResourceCacheAccess_DEFINED
10 
11 #include "GrGpuResource.h"
12 #include "GrGpuResourcePriv.h"
13 
14 namespace skiatest {
15     class Reporter;
16 }
17 
18 /**
19  * This class allows GrResourceCache increased privileged access to GrGpuResource objects.
20  */
21 class GrGpuResource::CacheAccess {
22 private:
23     /**
24      * Is the resource currently cached as scratch? This means it is cached, has a valid scratch
25      * key, and does not have a unique key.
26      */
27     bool isScratch() const {
28         return !fResource->getUniqueKey().isValid() && fResource->fScratchKey.isValid() &&
29                GrBudgetedType::kBudgeted == fResource->resourcePriv().budgetedType();
30     }
31 
32     /**
33      * Called by the cache to delete the resource under normal circumstances.
34      */
35     void release() {
36         fResource->release();
37         if (!fResource->hasRefOrPendingIO()) {
38             delete fResource;
39         }
40     }
41 
42     /**
43      * Called by the cache to delete the resource when the backend 3D context is no longer valid.
44      */
45     void abandon() {
46         fResource->abandon();
47         if (!fResource->hasRefOrPendingIO()) {
48             delete fResource;
49         }
50     }
51 
52     /** Called by the cache to assign a new unique key. */
53     void setUniqueKey(const GrUniqueKey& key) { fResource->fUniqueKey = key; }
54 
55     /** Called by the cache to make the unique key invalid. */
56     void removeUniqueKey() { fResource->fUniqueKey.reset(); }
57 
58     uint32_t timestamp() const { return fResource->fTimestamp; }
59     void setTimestamp(uint32_t ts) { fResource->fTimestamp = ts; }
60 
61     void setTimeWhenResourceBecomePurgeable() {
62         SkASSERT(fResource->isPurgeable());
63         fResource->fTimeWhenBecamePurgeable = GrStdSteadyClock::now();
64     }
65     /**
66      * Called by the cache to determine whether this resource should be purged based on the length
67      * of time it has been available for purging.
68      */
69     GrStdSteadyClock::time_point timeWhenResourceBecamePurgeable() {
70         SkASSERT(fResource->isPurgeable());
71         return fResource->fTimeWhenBecamePurgeable;
72     }
73 
74     int* accessCacheIndex() const { return &fResource->fCacheArrayIndex; }
75 
76     CacheAccess(GrGpuResource* resource) : fResource(resource) {}
77     CacheAccess(const CacheAccess& that) : fResource(that.fResource) {}
78     CacheAccess& operator=(const CacheAccess&); // unimpl
79 
80     // No taking addresses of this type.
81     const CacheAccess* operator&() const;
82     CacheAccess* operator&();
83 
84     GrGpuResource* fResource;
85 
86     friend class GrGpuResource; // to construct/copy this type.
87     friend class GrResourceCache; // to use this type
88     friend void test_unbudgeted_to_scratch(skiatest::Reporter* reporter); // for unit testing
89 };
90 
91 inline GrGpuResource::CacheAccess GrGpuResource::cacheAccess() { return CacheAccess(this); }
92 
93 inline const GrGpuResource::CacheAccess GrGpuResource::cacheAccess() const {
94     return CacheAccess(const_cast<GrGpuResource*>(this));
95 }
96 
97 #endif
98