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 "include/gpu/GrGpuResource.h"
12 #include "src/gpu/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     /** The cache is allowed to go from no refs to 1 ref. */
ref()24     void ref() { fResource->addInitialRef(); }
25 
26     /**
27      * Is the resource currently cached as scratch? This means it is cached, has a valid scratch
28      * key, and does not have a unique key.
29      */
isScratch()30     bool isScratch() const {
31         return !fResource->getUniqueKey().isValid() && fResource->fScratchKey.isValid() &&
32                GrBudgetedType::kBudgeted == fResource->resourcePriv().budgetedType();
33     }
34 
35     /**
36      * Called by the cache to delete the resource under normal circumstances.
37      */
release()38     void release() {
39         fResource->release();
40         if (!fResource->hasRef()) {
41             delete fResource;
42         }
43     }
44 
45     /**
46      * Called by the cache to delete the resource when the backend 3D context is no longer valid.
47      */
abandon()48     void abandon() {
49         fResource->abandon();
50         if (!fResource->hasRef()) {
51             delete fResource;
52         }
53     }
54 
55     /** Called by the cache to assign a new unique key. */
setUniqueKey(const GrUniqueKey & key)56     void setUniqueKey(const GrUniqueKey& key) { fResource->fUniqueKey = key; }
57 
58     /** Is the resource ref'ed */
hasRef()59     bool hasRef() const { return fResource->hasRef(); }
60 
61     /** Called by the cache to make the unique key invalid. */
removeUniqueKey()62     void removeUniqueKey() { fResource->fUniqueKey.reset(); }
63 
timestamp()64     uint32_t timestamp() const { return fResource->fTimestamp; }
setTimestamp(uint32_t ts)65     void setTimestamp(uint32_t ts) { fResource->fTimestamp = ts; }
66 
setTimeWhenResourceBecomePurgeable()67     void setTimeWhenResourceBecomePurgeable() {
68         SkASSERT(fResource->isPurgeable());
69         fResource->fTimeWhenBecamePurgeable = GrStdSteadyClock::now();
70     }
71     /**
72      * Called by the cache to determine whether this resource should be purged based on the length
73      * of time it has been available for purging.
74      */
timeWhenResourceBecamePurgeable()75     GrStdSteadyClock::time_point timeWhenResourceBecamePurgeable() {
76         SkASSERT(fResource->isPurgeable());
77         return fResource->fTimeWhenBecamePurgeable;
78     }
79 
accessCacheIndex()80     int* accessCacheIndex() const { return &fResource->fCacheArrayIndex; }
81 
CacheAccess(GrGpuResource * resource)82     CacheAccess(GrGpuResource* resource) : fResource(resource) {}
CacheAccess(const CacheAccess & that)83     CacheAccess(const CacheAccess& that) : fResource(that.fResource) {}
84     CacheAccess& operator=(const CacheAccess&); // unimpl
85 
86     // No taking addresses of this type.
87     const CacheAccess* operator&() const = delete;
88     CacheAccess* operator&() = delete;
89 
90     GrGpuResource* fResource;
91 
92     friend class GrGpuResource; // to construct/copy this type.
93     friend class GrResourceCache; // to use this type
94     friend void test_unbudgeted_to_scratch(skiatest::Reporter* reporter); // for unit testing
95 };
96 
cacheAccess()97 inline GrGpuResource::CacheAccess GrGpuResource::cacheAccess() { return CacheAccess(this); }
98 
cacheAccess()99 inline const GrGpuResource::CacheAccess GrGpuResource::cacheAccess() const {
100     return CacheAccess(const_cast<GrGpuResource*>(this));
101 }
102 
103 #endif
104