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