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