• 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 "GrMockGpu.h"
9 #include "GrMockBuffer.h"
10 #include "GrMockCaps.h"
11 #include "GrMockGpuCommandBuffer.h"
12 #include "GrMockStencilAttachment.h"
13 #include "GrMockTexture.h"
14 #include <atomic>
15 
NextInternalTextureID()16 int GrMockGpu::NextInternalTextureID() {
17     static std::atomic<int> nextID{1};
18     int id;
19     do {
20         id = nextID.fetch_add(1);
21     } while (0 == id);  // Reserve 0 for an invalid ID.
22     return id;
23 }
24 
NextExternalTextureID()25 int GrMockGpu::NextExternalTextureID() {
26     // We use negative ints for the "testing only external textures" so they can easily be
27     // identified when debugging.
28     static std::atomic<int> nextID{-1};
29     return nextID--;
30 }
31 
NextInternalRenderTargetID()32 int GrMockGpu::NextInternalRenderTargetID() {
33     // We start off with large numbers to differentiate from texture IDs, even though they're
34     // technically in a different space.
35     static std::atomic<int> nextID{SK_MaxS32};
36     return nextID--;
37 }
38 
NextExternalRenderTargetID()39 int GrMockGpu::NextExternalRenderTargetID() {
40     // We use large negative ints for the "testing only external render targets" so they can easily
41     // be identified when debugging.
42     static std::atomic<int> nextID{SK_MinS32};
43     return nextID++;
44 }
45 
Make(const GrMockOptions * mockOptions,const GrContextOptions & contextOptions,GrContext * context)46 sk_sp<GrGpu> GrMockGpu::Make(const GrMockOptions* mockOptions,
47                              const GrContextOptions& contextOptions, GrContext* context) {
48     static const GrMockOptions kDefaultOptions = GrMockOptions();
49     if (!mockOptions) {
50         mockOptions = &kDefaultOptions;
51     }
52     return sk_sp<GrGpu>(new GrMockGpu(context, *mockOptions, contextOptions));
53 }
54 
getCommandBuffer(GrRenderTarget * rt,GrSurfaceOrigin origin,const SkRect & bounds,const GrGpuRTCommandBuffer::LoadAndStoreInfo &,const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo &)55 GrGpuRTCommandBuffer* GrMockGpu::getCommandBuffer(
56                                 GrRenderTarget* rt, GrSurfaceOrigin origin, const SkRect& bounds,
57                                 const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
58                                 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) {
59     return new GrMockGpuRTCommandBuffer(this, rt, origin);
60 }
61 
getCommandBuffer(GrTexture * texture,GrSurfaceOrigin origin)62 GrGpuTextureCommandBuffer* GrMockGpu::getCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin) {
63     return new GrMockGpuTextureCommandBuffer(texture, origin);
64 }
65 
submit(GrGpuCommandBuffer * buffer)66 void GrMockGpu::submit(GrGpuCommandBuffer* buffer) {
67     if (buffer->asRTCommandBuffer()) {
68         this->submitCommandBuffer(
69                         static_cast<GrMockGpuRTCommandBuffer*>(buffer->asRTCommandBuffer()));
70     }
71 
72     delete buffer;
73 }
74 
submitCommandBuffer(const GrMockGpuRTCommandBuffer * cmdBuffer)75 void GrMockGpu::submitCommandBuffer(const GrMockGpuRTCommandBuffer* cmdBuffer) {
76     for (int i = 0; i < cmdBuffer->numDraws(); ++i) {
77         fStats.incNumDraws();
78     }
79 }
80 
GrMockGpu(GrContext * context,const GrMockOptions & options,const GrContextOptions & contextOptions)81 GrMockGpu::GrMockGpu(GrContext* context, const GrMockOptions& options,
82                      const GrContextOptions& contextOptions)
83         : INHERITED(context)
84         , fMockOptions(options) {
85     fCaps.reset(new GrMockCaps(contextOptions, options));
86 }
87 
onCreateTexture(const GrSurfaceDesc & desc,SkBudgeted budgeted,const GrMipLevel texels[],int mipLevelCount)88 sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
89                                             const GrMipLevel texels[], int mipLevelCount) {
90     if (fMockOptions.fFailTextureAllocations) {
91         return nullptr;
92     }
93 
94     GrMipMapsStatus mipMapsStatus = mipLevelCount > 1 ? GrMipMapsStatus::kValid
95                                                       : GrMipMapsStatus::kNotAllocated;
96     GrMockTextureInfo texInfo;
97     texInfo.fConfig = desc.fConfig;
98     texInfo.fID = NextInternalTextureID();
99     if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
100         GrMockRenderTargetInfo rtInfo;
101         rtInfo.fConfig = desc.fConfig;
102         rtInfo.fID = NextInternalRenderTargetID();
103         return sk_sp<GrTexture>(new GrMockTextureRenderTarget(this, budgeted, desc, mipMapsStatus,
104                                                               texInfo, rtInfo));
105     }
106     return sk_sp<GrTexture>(new GrMockTexture(this, budgeted, desc, mipMapsStatus, texInfo));
107 }
108 
onWrapBackendTexture(const GrBackendTexture & tex,GrWrapOwnership ownership,GrWrapCacheable wrapType,GrIOType ioType)109 sk_sp<GrTexture> GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex,
110                                                  GrWrapOwnership ownership,
111                                                  GrWrapCacheable wrapType, GrIOType ioType) {
112     GrSurfaceDesc desc;
113     desc.fWidth = tex.width();
114     desc.fHeight = tex.height();
115 
116     GrMockTextureInfo info;
117     SkAssertResult(tex.getMockTextureInfo(&info));
118     desc.fConfig = info.fConfig;
119 
120     GrMipMapsStatus mipMapsStatus = tex.hasMipMaps() ? GrMipMapsStatus::kValid
121                                                      : GrMipMapsStatus::kNotAllocated;
122 
123     return sk_sp<GrTexture>(new GrMockTexture(this, desc, mipMapsStatus, info, wrapType, ioType));
124 }
125 
onWrapRenderableBackendTexture(const GrBackendTexture & tex,int sampleCnt,GrWrapOwnership ownership,GrWrapCacheable cacheable)126 sk_sp<GrTexture> GrMockGpu::onWrapRenderableBackendTexture(const GrBackendTexture& tex,
127                                                            int sampleCnt,
128                                                            GrWrapOwnership ownership,
129                                                            GrWrapCacheable cacheable) {
130     GrSurfaceDesc desc;
131     desc.fFlags = kRenderTarget_GrSurfaceFlag;
132     desc.fWidth = tex.width();
133     desc.fHeight = tex.height();
134 
135     GrMockTextureInfo texInfo;
136     SkAssertResult(tex.getMockTextureInfo(&texInfo));
137     desc.fConfig = texInfo.fConfig;
138 
139     GrMipMapsStatus mipMapsStatus =
140             tex.hasMipMaps() ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated;
141 
142     GrMockRenderTargetInfo rtInfo;
143     rtInfo.fConfig = texInfo.fConfig;
144     // The client gave us the texture ID but we supply the render target ID.
145     rtInfo.fID = NextInternalRenderTargetID();
146 
147     return sk_sp<GrTexture>(
148             new GrMockTextureRenderTarget(this, desc, mipMapsStatus, texInfo, rtInfo, cacheable));
149 }
150 
onWrapBackendRenderTarget(const GrBackendRenderTarget & rt)151 sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& rt) {
152     GrSurfaceDesc desc;
153     desc.fFlags = kRenderTarget_GrSurfaceFlag;
154     desc.fWidth = rt.width();
155     desc.fHeight = rt.height();
156 
157     GrMockRenderTargetInfo info;
158     SkAssertResult(rt.getMockRenderTargetInfo(&info));
159     desc.fConfig = info.fConfig;
160 
161     return sk_sp<GrRenderTarget>(
162             new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc, info));
163 }
164 
onWrapBackendTextureAsRenderTarget(const GrBackendTexture & tex,int sampleCnt)165 sk_sp<GrRenderTarget> GrMockGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
166                                                                     int sampleCnt) {
167     GrSurfaceDesc desc;
168     desc.fFlags = kRenderTarget_GrSurfaceFlag;
169     desc.fWidth = tex.width();
170     desc.fHeight = tex.height();
171 
172     GrMockTextureInfo texInfo;
173     SkAssertResult(tex.getMockTextureInfo(&texInfo));
174     desc.fConfig = texInfo.fConfig;
175     desc.fSampleCnt = sampleCnt;
176 
177     GrMockRenderTargetInfo rtInfo;
178     rtInfo.fConfig = texInfo.fConfig;
179     // The client gave us the texture ID but we supply the render target ID.
180     rtInfo.fID = NextInternalRenderTargetID();
181 
182     return sk_sp<GrRenderTarget>(
183             new GrMockRenderTarget(this, GrMockRenderTarget::kWrapped, desc, rtInfo));
184 }
185 
onCreateBuffer(size_t sizeInBytes,GrBufferType type,GrAccessPattern accessPattern,const void *)186 sk_sp<GrBuffer> GrMockGpu::onCreateBuffer(size_t sizeInBytes, GrBufferType type,
187                                           GrAccessPattern accessPattern, const void*) {
188     return sk_sp<GrBuffer>(new GrMockBuffer(this, sizeInBytes, type, accessPattern));
189 }
190 
createStencilAttachmentForRenderTarget(const GrRenderTarget * rt,int width,int height)191 GrStencilAttachment* GrMockGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
192                                                                        int width,
193                                                                        int height) {
194     static constexpr int kBits = 8;
195     fStats.incStencilAttachmentCreates();
196     return new GrMockStencilAttachment(this, width, height, kBits, rt->numColorSamples());
197 }
198 
199 #if GR_TEST_UTILS
createTestingOnlyBackendTexture(const void * pixels,int w,int h,GrColorType colorType,bool isRT,GrMipMapped mipMapped,size_t rowBytes)200 GrBackendTexture GrMockGpu::createTestingOnlyBackendTexture(const void* pixels, int w, int h,
201                                                             GrColorType colorType, bool isRT,
202                                                             GrMipMapped mipMapped,
203                                                             size_t rowBytes) {
204 
205     GrPixelConfig config = GrColorTypeToPixelConfig(colorType, GrSRGBEncoded::kNo);
206     if (!this->caps()->isConfigTexturable(config)) {
207         return GrBackendTexture();  // invalid
208     }
209 
210     GrMockTextureInfo info;
211     info.fConfig = config;
212     info.fID = NextExternalTextureID();
213     fOutstandingTestingOnlyTextureIDs.add(info.fID);
214     return GrBackendTexture(w, h, mipMapped, info);
215 }
216 
isTestingOnlyBackendTexture(const GrBackendTexture & tex) const217 bool GrMockGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
218     SkASSERT(GrBackendApi::kMock == tex.backend());
219 
220     GrMockTextureInfo info;
221     if (!tex.getMockTextureInfo(&info)) {
222         return false;
223     }
224 
225     return fOutstandingTestingOnlyTextureIDs.contains(info.fID);
226 }
227 
deleteTestingOnlyBackendTexture(const GrBackendTexture & tex)228 void GrMockGpu::deleteTestingOnlyBackendTexture(const GrBackendTexture& tex) {
229     SkASSERT(GrBackendApi::kMock == tex.backend());
230 
231     GrMockTextureInfo info;
232     if (tex.getMockTextureInfo(&info)) {
233         fOutstandingTestingOnlyTextureIDs.remove(info.fID);
234     }
235 }
236 
createTestingOnlyBackendRenderTarget(int w,int h,GrColorType colorType)237 GrBackendRenderTarget GrMockGpu::createTestingOnlyBackendRenderTarget(int w, int h,
238                                                                       GrColorType colorType) {
239     auto config = GrColorTypeToPixelConfig(colorType, GrSRGBEncoded::kNo);
240     if (kUnknown_GrPixelConfig == config) {
241         return {};
242     }
243     GrMockRenderTargetInfo info = {config, NextExternalRenderTargetID()};
244     static constexpr int kSampleCnt = 1;
245     static constexpr int kStencilBits = 8;
246     return {w, h, kSampleCnt, kStencilBits, info};
247 }
248 
deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget &)249 void GrMockGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {}
250 #endif
251