1 /*
2  * Copyright 2017 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 #ifndef GrMockTexture_DEFINED
8 #define GrMockTexture_DEFINED
9 
10 #include "GrMockGpu.h"
11 #include "GrRenderTarget.h"
12 #include "GrRenderTargetPriv.h"
13 #include "GrTexture.h"
14 #include "GrTexturePriv.h"
15 #include "mock/GrMockTypes.h"
16 
17 class GrMockTexture : public GrTexture {
18 public:
GrMockTexture(GrMockGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,GrMipMapsStatus mipMapsStatus,const GrMockTextureInfo & info)19     GrMockTexture(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
20                   GrMipMapsStatus mipMapsStatus, const GrMockTextureInfo& info)
21             : GrMockTexture(gpu, desc, mipMapsStatus, info) {
22         this->registerWithCache(budgeted);
23     }
24 
GrMockTexture(GrMockGpu * gpu,const GrSurfaceDesc & desc,GrMipMapsStatus mipMapsStatus,const GrMockTextureInfo & info,GrWrapCacheable cacheable,GrIOType ioType)25     GrMockTexture(GrMockGpu* gpu, const GrSurfaceDesc& desc, GrMipMapsStatus mipMapsStatus,
26                   const GrMockTextureInfo& info, GrWrapCacheable cacheable, GrIOType ioType)
27             : GrMockTexture(gpu, desc, mipMapsStatus, info) {
28         if (ioType == kRead_GrIOType) {
29             this->setReadOnly();
30         }
31         this->registerWithCacheWrapped(cacheable);
32     }
33 
~GrMockTexture()34     ~GrMockTexture() override {}
35 
getBackendTexture()36     GrBackendTexture getBackendTexture() const override {
37         return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(),
38                                 fInfo);
39     }
40 
backendFormat()41     GrBackendFormat backendFormat() const override {
42         return GrBackendFormat::MakeMock(fInfo.fConfig);
43     }
44 
textureParamsModified()45     void textureParamsModified() override {}
setRelease(sk_sp<GrReleaseProcHelper> releaseHelper)46     void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override {
47         fReleaseHelper = std::move(releaseHelper);
48     }
49 
setIdleProc(IdleProc proc,void * context)50     void setIdleProc(IdleProc proc, void* context) override {
51         fIdleProc = proc;
52         fIdleProcContext = context;
53     }
idleContext()54     void* idleContext() const override { return fIdleProcContext; }
55 
56 protected:
57     // constructor for subclasses
GrMockTexture(GrMockGpu * gpu,const GrSurfaceDesc & desc,GrMipMapsStatus mipMapsStatus,const GrMockTextureInfo & info)58     GrMockTexture(GrMockGpu* gpu, const GrSurfaceDesc& desc, GrMipMapsStatus mipMapsStatus,
59                   const GrMockTextureInfo& info)
60             : GrSurface(gpu, desc)
61             , INHERITED(gpu, desc, GrTextureType::k2D, mipMapsStatus)
62             , fInfo(info) {}
63 
onRelease()64     void onRelease() override {
65         this->invokeReleaseProc();
66         INHERITED::onRelease();
67     }
68 
onAbandon()69     void onAbandon() override {
70         this->invokeReleaseProc();
71         INHERITED::onAbandon();
72     }
73 
onStealBackendTexture(GrBackendTexture *,SkImage::BackendTextureReleaseProc *)74     bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override {
75         return false;
76     }
77 
78     // protected so that GrMockTextureRenderTarget can call this to avoid "inheritance via
79     // dominance" warning.
removedLastRefOrPendingIO()80     void removedLastRefOrPendingIO() override {
81         if (fIdleProc) {
82             fIdleProc(fIdleProcContext);
83             fIdleProc = nullptr;
84             fIdleProcContext = nullptr;
85         }
86     }
87 
88 private:
invokeReleaseProc()89     void invokeReleaseProc() {
90         // Depending on the ref count of fReleaseHelper this may or may not actually trigger the
91         // ReleaseProc to be called.
92         fReleaseHelper.reset();
93     }
94 
95     GrMockTextureInfo fInfo;
96     sk_sp<GrReleaseProcHelper> fReleaseHelper;
97     IdleProc* fIdleProc = nullptr;
98     void* fIdleProcContext = nullptr;
99 
100     typedef GrTexture INHERITED;
101 };
102 
103 class GrMockRenderTarget : public GrRenderTarget {
104 public:
GrMockRenderTarget(GrMockGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const GrMockRenderTargetInfo & info)105     GrMockRenderTarget(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
106                        const GrMockRenderTargetInfo& info)
107             : GrSurface(gpu, desc), INHERITED(gpu, desc), fInfo(info) {
108         this->registerWithCache(budgeted);
109     }
110 
111     enum Wrapped { kWrapped };
GrMockRenderTarget(GrMockGpu * gpu,Wrapped,const GrSurfaceDesc & desc,const GrMockRenderTargetInfo & info)112     GrMockRenderTarget(GrMockGpu* gpu, Wrapped, const GrSurfaceDesc& desc,
113                        const GrMockRenderTargetInfo& info)
114             : GrSurface(gpu, desc), INHERITED(gpu, desc), fInfo(info) {
115         this->registerWithCacheWrapped(GrWrapCacheable::kNo);
116     }
117 
getResolveType()118     ResolveType getResolveType() const override { return kCanResolve_ResolveType; }
canAttemptStencilAttachment()119     bool canAttemptStencilAttachment() const override { return true; }
completeStencilAttachment()120     bool completeStencilAttachment() override { return true; }
121 
onGpuMemorySize()122     size_t onGpuMemorySize() const override {
123         int numColorSamples = this->numColorSamples();
124         if (numColorSamples > 1) {
125             // Add one to account for the resolve buffer.
126             ++numColorSamples;
127         }
128         return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
129                                       numColorSamples, GrMipMapped::kNo);
130     }
131 
getBackendRenderTarget()132     GrBackendRenderTarget getBackendRenderTarget() const override {
133         int numStencilBits = 0;
134         if (GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment()) {
135             numStencilBits = stencil->bits();
136         }
137         return {this->width(), this->height(), this->numColorSamples(), numStencilBits, fInfo};
138     }
139 
backendFormat()140     GrBackendFormat backendFormat() const override {
141         return GrBackendFormat::MakeMock(fInfo.fConfig);
142     }
143 
144 protected:
145     // constructor for subclasses
GrMockRenderTarget(GrMockGpu * gpu,const GrSurfaceDesc & desc,const GrMockRenderTargetInfo & info)146     GrMockRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc,
147                        const GrMockRenderTargetInfo& info)
148             : GrSurface(gpu, desc), INHERITED(gpu, desc), fInfo(info) {}
149 
150 private:
151     GrMockRenderTargetInfo fInfo;
152 
153     typedef GrRenderTarget INHERITED;
154 };
155 
156 class GrMockTextureRenderTarget : public GrMockTexture, public GrMockRenderTarget {
157 public:
158     // Internally created.
GrMockTextureRenderTarget(GrMockGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,GrMipMapsStatus mipMapsStatus,const GrMockTextureInfo & texInfo,const GrMockRenderTargetInfo & rtInfo)159     GrMockTextureRenderTarget(GrMockGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
160                               GrMipMapsStatus mipMapsStatus, const GrMockTextureInfo& texInfo,
161                               const GrMockRenderTargetInfo& rtInfo)
162             : GrSurface(gpu, desc)
163             , GrMockTexture(gpu, desc, mipMapsStatus, texInfo)
164             , GrMockRenderTarget(gpu, desc, rtInfo) {
165         this->registerWithCache(budgeted);
166     }
167 
168     // Renderable wrapped backend texture.
GrMockTextureRenderTarget(GrMockGpu * gpu,const GrSurfaceDesc & desc,GrMipMapsStatus mipMapsStatus,const GrMockTextureInfo & texInfo,const GrMockRenderTargetInfo & rtInfo,GrWrapCacheable cacheble)169     GrMockTextureRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc,
170                               GrMipMapsStatus mipMapsStatus, const GrMockTextureInfo& texInfo,
171                               const GrMockRenderTargetInfo& rtInfo, GrWrapCacheable cacheble)
172             : GrSurface(gpu, desc)
173             , GrMockTexture(gpu, desc, mipMapsStatus, texInfo)
174             , GrMockRenderTarget(gpu, desc, rtInfo) {
175         this->registerWithCacheWrapped(cacheble);
176     }
177 
asTexture()178     GrTexture* asTexture() override { return this; }
asRenderTarget()179     GrRenderTarget* asRenderTarget() override { return this; }
asTexture()180     const GrTexture* asTexture() const override { return this; }
asRenderTarget()181     const GrRenderTarget* asRenderTarget() const override { return this; }
182 
backendFormat()183     GrBackendFormat backendFormat() const override {
184         return GrMockTexture::backendFormat();
185     }
186 
187 private:
onAbandon()188     void onAbandon() override {
189         GrRenderTarget::onAbandon();
190         GrMockTexture::onAbandon();
191     }
192 
onRelease()193     void onRelease() override {
194         GrRenderTarget::onRelease();
195         GrMockTexture::onRelease();
196     }
197 
198     // We implement this to avoid the inheritance via dominance warning.
removedLastRefOrPendingIO()199     void removedLastRefOrPendingIO() override { GrMockTexture::removedLastRefOrPendingIO(); }
200 
onGpuMemorySize()201     size_t onGpuMemorySize() const override {
202         int numColorSamples = this->numColorSamples();
203         if (numColorSamples > 1) {
204             // Add one to account for the resolve buffer.
205             ++numColorSamples;
206         }
207         return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
208                                       numColorSamples,
209                                       this->texturePriv().mipMapped());
210     }
211 
computeScratchKey(GrScratchKey * key)212     void computeScratchKey(GrScratchKey* key) const override {
213         GrTexturePriv::ComputeScratchKey(this->config(), this->width(), this->height(),
214                                          true, this->numStencilSamples(),
215                                          this->texturePriv().mipMapped(), key);
216     }
217 };
218 
219 #endif
220