• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "src/gpu/ganesh/mock/GrMockGpu.h"
9 
10 #include "src/gpu/ganesh/GrThreadSafePipelineBuilder.h"
11 #include "src/gpu/ganesh/mock/GrMockAttachment.h"
12 #include "src/gpu/ganesh/mock/GrMockBuffer.h"
13 #include "src/gpu/ganesh/mock/GrMockCaps.h"
14 #include "src/gpu/ganesh/mock/GrMockOpsRenderPass.h"
15 #include "src/gpu/ganesh/mock/GrMockTexture.h"
16 
17 #include <atomic>
18 
NextInternalTextureID()19 int GrMockGpu::NextInternalTextureID() {
20     static std::atomic<int> nextID{1};
21     int id;
22     do {
23         id = nextID.fetch_add(1, std::memory_order_relaxed);
24     } while (0 == id);  // Reserve 0 for an invalid ID.
25     return id;
26 }
27 
NextExternalTextureID()28 int GrMockGpu::NextExternalTextureID() {
29     // We use negative ints for the "testing only external textures" so they can easily be
30     // identified when debugging.
31     static std::atomic<int> nextID{-1};
32     return nextID.fetch_add(-1, std::memory_order_relaxed);
33 }
34 
NextInternalRenderTargetID()35 int GrMockGpu::NextInternalRenderTargetID() {
36     // We start off with large numbers to differentiate from texture IDs, even though they're
37     // technically in a different space.
38     static std::atomic<int> nextID{SK_MaxS32};
39     return nextID.fetch_add(-1, std::memory_order_relaxed);
40 }
41 
NextExternalRenderTargetID()42 int GrMockGpu::NextExternalRenderTargetID() {
43     // We use large negative ints for the "testing only external render targets" so they can easily
44     // be identified when debugging.
45     static std::atomic<int> nextID{SK_MinS32};
46     return nextID.fetch_add(1, std::memory_order_relaxed);
47 }
48 
Make(const GrMockOptions * mockOptions,const GrContextOptions & contextOptions,GrDirectContext * direct)49 sk_sp<GrGpu> GrMockGpu::Make(const GrMockOptions* mockOptions,
50                              const GrContextOptions& contextOptions, GrDirectContext* direct) {
51     static const GrMockOptions kDefaultOptions = GrMockOptions();
52     if (!mockOptions) {
53         mockOptions = &kDefaultOptions;
54     }
55     return sk_sp<GrGpu>(new GrMockGpu(direct, *mockOptions, contextOptions));
56 }
57 
onGetOpsRenderPass(GrRenderTarget * rt,bool,GrAttachment *,GrSurfaceOrigin origin,const SkIRect & bounds,const GrOpsRenderPass::LoadAndStoreInfo & colorInfo,const GrOpsRenderPass::StencilLoadAndStoreInfo &,const SkTArray<GrSurfaceProxy *,true> & sampledProxies,GrXferBarrierFlags renderPassXferBarriers)58 GrOpsRenderPass* GrMockGpu::onGetOpsRenderPass(GrRenderTarget* rt,
59                                                bool /*useMSAASurface*/,
60                                                GrAttachment*,
61                                                GrSurfaceOrigin origin,
62                                                const SkIRect& bounds,
63                                                const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
64                                                const GrOpsRenderPass::StencilLoadAndStoreInfo&,
65                                                const SkTArray<GrSurfaceProxy*,true>& sampledProxies,
66                                                GrXferBarrierFlags renderPassXferBarriers) {
67     return new GrMockOpsRenderPass(this, rt, origin, colorInfo);
68 }
69 
submit(GrOpsRenderPass * renderPass)70 void GrMockGpu::submit(GrOpsRenderPass* renderPass) {
71     for (int i = 0; i < static_cast<GrMockOpsRenderPass*>(renderPass)->numDraws(); ++i) {
72         fStats.incNumDraws();
73     }
74     delete renderPass;
75 }
76 
GrMockGpu(GrDirectContext * direct,const GrMockOptions & options,const GrContextOptions & contextOptions)77 GrMockGpu::GrMockGpu(GrDirectContext* direct, const GrMockOptions& options,
78                      const GrContextOptions& contextOptions)
79         : INHERITED(direct)
80         , fMockOptions(options) {
81     this->initCapsAndCompiler(sk_make_sp<GrMockCaps>(contextOptions, options));
82 }
83 
~GrMockGpu()84 GrMockGpu::~GrMockGpu() {}
85 
pipelineBuilder()86 GrThreadSafePipelineBuilder* GrMockGpu::pipelineBuilder() {
87     return nullptr;
88 }
89 
refPipelineBuilder()90 sk_sp<GrThreadSafePipelineBuilder> GrMockGpu::refPipelineBuilder() {
91     return nullptr;
92 }
93 
onCreateTexture(SkISize dimensions,const GrBackendFormat & format,GrRenderable renderable,int renderTargetSampleCnt,skgpu::Budgeted budgeted,GrProtected isProtected,int mipLevelCount,uint32_t levelClearMask,std::string_view label)94 sk_sp<GrTexture> GrMockGpu::onCreateTexture(SkISize dimensions,
95                                             const GrBackendFormat& format,
96                                             GrRenderable renderable,
97                                             int renderTargetSampleCnt,
98                                             skgpu::Budgeted budgeted,
99                                             GrProtected isProtected,
100                                             int mipLevelCount,
101                                             uint32_t levelClearMask,
102                                             std::string_view label) {
103     if (fMockOptions.fFailTextureAllocations) {
104         return nullptr;
105     }
106 
107     // Compressed formats should go through onCreateCompressedTexture
108     SkASSERT(format.asMockCompressionType() == SkImage::CompressionType::kNone);
109 
110     GrColorType ct = format.asMockColorType();
111     SkASSERT(ct != GrColorType::kUnknown);
112 
113     GrMipmapStatus mipmapStatus =
114             mipLevelCount > 1 ? GrMipmapStatus::kDirty : GrMipmapStatus::kNotAllocated;
115     GrMockTextureInfo texInfo(ct, SkImage::CompressionType::kNone, NextInternalTextureID());
116     if (renderable == GrRenderable::kYes) {
117         GrMockRenderTargetInfo rtInfo(ct, NextInternalRenderTargetID());
118         return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, budgeted, dimensions,
119                                                               renderTargetSampleCnt, isProtected,
120                                                               mipmapStatus,
121                                                               texInfo,
122                                                               rtInfo,
123                                                               label));
124     }
125     return sk_sp<GrTexture>(new GrMockTexture(
126             this, budgeted, dimensions, isProtected, mipmapStatus, texInfo, label));
127 }
128 
129 // TODO: why no 'isProtected' ?!
onCreateCompressedTexture(SkISize dimensions,const GrBackendFormat & format,skgpu::Budgeted budgeted,GrMipmapped mipmapped,GrProtected isProtected,const void * data,size_t dataSize)130 sk_sp<GrTexture> GrMockGpu::onCreateCompressedTexture(SkISize dimensions,
131                                                       const GrBackendFormat& format,
132                                                       skgpu::Budgeted budgeted,
133                                                       GrMipmapped mipmapped,
134                                                       GrProtected isProtected,
135                                                       const void* data,
136                                                       size_t dataSize) {
137     if (fMockOptions.fFailTextureAllocations) {
138         return nullptr;
139     }
140 
141 #ifdef SK_DEBUG
142     // Uncompressed formats should go through onCreateTexture
143     SkImage::CompressionType compression = format.asMockCompressionType();
144     SkASSERT(compression != SkImage::CompressionType::kNone);
145 #endif
146 
147     GrMipmapStatus mipmapStatus = (mipmapped == GrMipmapped::kYes)
148                                                                 ? GrMipmapStatus::kValid
149                                                                 : GrMipmapStatus::kNotAllocated;
150     GrMockTextureInfo texInfo(GrColorType::kUnknown,
151                               format.asMockCompressionType(),
152                               NextInternalTextureID());
153 
154     return sk_sp<GrTexture>(new GrMockTexture(
155             this, budgeted, dimensions, isProtected, mipmapStatus, texInfo,
156             /*label=*/"MockGpu_CreateCompressedTexture"));
157 }
158 
onWrapBackendTexture(const GrBackendTexture & tex,GrWrapOwnership ownership,GrWrapCacheable wrapType,GrIOType ioType)159 sk_sp<GrTexture> GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex,
160                                                  GrWrapOwnership ownership,
161                                                  GrWrapCacheable wrapType,
162                                                  GrIOType ioType) {
163     GrMockTextureInfo texInfo;
164     SkAssertResult(tex.getMockTextureInfo(&texInfo));
165 
166     SkImage::CompressionType compression = texInfo.compressionType();
167     if (compression != SkImage::CompressionType::kNone) {
168         return nullptr;
169     }
170 
171     GrMipmapStatus mipmapStatus = tex.hasMipmaps() ? GrMipmapStatus::kValid
172                                                    : GrMipmapStatus::kNotAllocated;
173     auto isProtected = GrProtected(tex.isProtected());
174     return sk_sp<GrTexture>(new GrMockTexture(this,
175                                               tex.dimensions(),
176                                               isProtected,
177                                               mipmapStatus,
178                                               texInfo,
179                                               wrapType,
180                                               ioType,
181                                               /*label=*/"MockGpu_WrapBackendTexture"));
182 }
183 
onWrapCompressedBackendTexture(const GrBackendTexture & tex,GrWrapOwnership ownership,GrWrapCacheable wrapType)184 sk_sp<GrTexture> GrMockGpu::onWrapCompressedBackendTexture(const GrBackendTexture& tex,
185                                                            GrWrapOwnership ownership,
186                                                            GrWrapCacheable wrapType) {
187     return nullptr;
188 }
189 
onWrapRenderableBackendTexture(const GrBackendTexture & tex,int sampleCnt,GrWrapOwnership ownership,GrWrapCacheable cacheable)190 sk_sp<GrTexture> GrMockGpu::onWrapRenderableBackendTexture(const GrBackendTexture& tex,
191                                                            int sampleCnt,
192                                                            GrWrapOwnership ownership,
193                                                            GrWrapCacheable cacheable) {
194     GrMockTextureInfo texInfo;
195     SkAssertResult(tex.getMockTextureInfo(&texInfo));
196     SkASSERT(texInfo.compressionType() == SkImage::CompressionType::kNone);
197 
198     GrMipmapStatus mipmapStatus =
199             tex.hasMipmaps() ? GrMipmapStatus::kValid : GrMipmapStatus::kNotAllocated;
200 
201     // The client gave us the texture ID but we supply the render target ID.
202     GrMockRenderTargetInfo rtInfo(texInfo.colorType(), NextInternalRenderTargetID());
203 
204     auto isProtected = GrProtected(tex.isProtected());
205     return sk_sp<GrTexture>(
206             new GrMockTextureRenderTarget(this,
207                                           tex.dimensions(),
208                                           sampleCnt,
209                                           isProtected,
210                                           mipmapStatus,
211                                           texInfo,
212                                           rtInfo,
213                                           cacheable,
214                                           /*label=*/"MockGpu_WrapRenderableBackendTexture"));
215 }
216 
onWrapBackendRenderTarget(const GrBackendRenderTarget & rt)217 sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& rt) {
218     GrMockRenderTargetInfo info;
219     SkAssertResult(rt.getMockRenderTargetInfo(&info));
220 
221     auto isProtected = GrProtected(rt.isProtected());
222     return sk_sp<GrRenderTarget>(
223             new GrMockRenderTarget(this,
224                                    GrMockRenderTarget::kWrapped,
225                                    rt.dimensions(),
226                                    rt.sampleCnt(),
227                                    isProtected,
228                                    info,
229                                    /*label=*/"MockGpu_WrapBackendRenderTarget"));
230 }
231 
onCreateBuffer(size_t sizeInBytes,GrGpuBufferType type,GrAccessPattern accessPattern)232 sk_sp<GrGpuBuffer> GrMockGpu::onCreateBuffer(size_t sizeInBytes,
233                                              GrGpuBufferType type,
234                                              GrAccessPattern accessPattern) {
235     return sk_sp<GrGpuBuffer>(
236             new GrMockBuffer(this, sizeInBytes, type, accessPattern,
237                              /*label=*/"MockGpu_CreateBuffer"));
238 }
239 
makeStencilAttachment(const GrBackendFormat &,SkISize dimensions,int numStencilSamples)240 sk_sp<GrAttachment> GrMockGpu::makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
241                                                      SkISize dimensions, int numStencilSamples) {
242     fStats.incStencilAttachmentCreates();
243     return sk_sp<GrAttachment>(new GrMockAttachment(this,
244                                                     dimensions,
245                                                     GrAttachment::UsageFlags::kStencilAttachment,
246                                                     numStencilSamples,
247                                                     /*label=*/"MockGpu_MakeStencilAttachment"));
248 }
249 
onCreateBackendTexture(SkISize dimensions,const GrBackendFormat & format,GrRenderable,GrMipmapped mipmapped,GrProtected,std::string_view label)250 GrBackendTexture GrMockGpu::onCreateBackendTexture(SkISize dimensions,
251                                                    const GrBackendFormat& format,
252                                                    GrRenderable,
253                                                    GrMipmapped mipmapped,
254                                                    GrProtected,
255                                                    std::string_view label) {
256     SkImage::CompressionType compression = format.asMockCompressionType();
257     if (compression != SkImage::CompressionType::kNone) {
258         return {}; // should go through onCreateCompressedBackendTexture
259     }
260 
261     auto colorType = format.asMockColorType();
262     if (!this->caps()->isFormatTexturable(format, GrTextureType::k2D)) {
263         return GrBackendTexture();  // invalid
264     }
265 
266     GrMockTextureInfo info(colorType, SkImage::CompressionType::kNone, NextExternalTextureID());
267 
268     fOutstandingTestingOnlyTextureIDs.add(info.id());
269     return GrBackendTexture(dimensions.width(), dimensions.height(), mipmapped, info);
270 }
271 
onCreateCompressedBackendTexture(SkISize dimensions,const GrBackendFormat & format,GrMipmapped mipmapped,GrProtected)272 GrBackendTexture GrMockGpu::onCreateCompressedBackendTexture(
273         SkISize dimensions, const GrBackendFormat& format, GrMipmapped mipmapped,
274          GrProtected) {
275     SkImage::CompressionType compression = format.asMockCompressionType();
276     if (compression == SkImage::CompressionType::kNone) {
277         return {}; // should go through onCreateBackendTexture
278     }
279 
280     if (!this->caps()->isFormatTexturable(format, GrTextureType::k2D)) {
281         return {};
282     }
283 
284     GrMockTextureInfo info(GrColorType::kUnknown, compression, NextExternalTextureID());
285 
286     fOutstandingTestingOnlyTextureIDs.add(info.id());
287     return GrBackendTexture(dimensions.width(), dimensions.height(), mipmapped, info);
288 }
289 
deleteBackendTexture(const GrBackendTexture & tex)290 void GrMockGpu::deleteBackendTexture(const GrBackendTexture& tex) {
291     SkASSERT(GrBackendApi::kMock == tex.backend());
292 
293     GrMockTextureInfo info;
294     if (tex.getMockTextureInfo(&info)) {
295         fOutstandingTestingOnlyTextureIDs.remove(info.id());
296     }
297 }
298 
299 #if GR_TEST_UTILS
isTestingOnlyBackendTexture(const GrBackendTexture & tex) const300 bool GrMockGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
301     SkASSERT(GrBackendApi::kMock == tex.backend());
302 
303     GrMockTextureInfo info;
304     if (!tex.getMockTextureInfo(&info)) {
305         return false;
306     }
307 
308     return fOutstandingTestingOnlyTextureIDs.contains(info.id());
309 }
310 
createTestingOnlyBackendRenderTarget(SkISize dimensions,GrColorType colorType,int sampleCnt,GrProtected)311 GrBackendRenderTarget GrMockGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions,
312                                                                       GrColorType colorType,
313                                                                       int sampleCnt,
314                                                                       GrProtected) {
315     GrMockRenderTargetInfo info(colorType, NextExternalRenderTargetID());
316     static constexpr int kStencilBits = 8;
317     return GrBackendRenderTarget(dimensions.width(), dimensions.height(), sampleCnt, kStencilBits,
318                                  info);
319 }
320 
deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget &)321 void GrMockGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {}
322 #endif
323