From f9b00424233747abf77c6d593dec69632430a0a8 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Thu, 8 Oct 2020 16:00:14 -0400 Subject: [PATCH] Expose ManagedBackendTexture from BackendTextureImageFactory. Add helper to create self-managed BackendTexture-backed SkSurface for tests using MBET. GrGpu::createTestingOnlyBackendRenderTarget supports protected. Make SkSurfaceCharacterization tests use self-managed SkSurface factories and a use case of MakeFromBackendTextureAsRenderTarget is removed. Use self-managed BackendTexture-backed SkSurface factory in DM sinks and in fm. Bug: skia:9832 Change-Id: I0c1dc49697f8b3c942864e18b9112a3552f431ba Reviewed-on: https://skia-review.googlesource.com/c/skia/+/323559 Commit-Queue: Brian Salomon Reviewed-by: Robert Phillips --- BUILD.gn | 2 + dm/DMSrcSink.cpp | 60 ++-- dm/DMSrcSink.h | 2 +- src/gpu/GrGpu.h | 8 +- src/gpu/d3d/GrD3DGpu.cpp | 5 +- src/gpu/d3d/GrD3DGpu.h | 5 +- src/gpu/dawn/GrDawnGpu.cpp | 7 +- src/gpu/dawn/GrDawnGpu.h | 5 +- src/gpu/gl/GrGLGpu.cpp | 7 +- src/gpu/gl/GrGLGpu.h | 5 +- src/gpu/mock/GrMockGpu.cpp | 3 +- src/gpu/mock/GrMockGpu.h | 3 +- src/gpu/mtl/GrMtlGpu.h | 5 +- src/gpu/mtl/GrMtlGpu.mm | 6 +- src/gpu/vk/GrVkGpu.cpp | 5 +- src/gpu/vk/GrVkGpu.h | 5 +- tests/BlendTest.cpp | 7 +- tests/DeferredDisplayListTest.cpp | 338 ++++++++--------------- tests/SurfaceTest.cpp | 18 +- tests/WritePixelsTest.cpp | 7 +- tools/fm/fm.cpp | 49 ++-- tools/gpu/BackendSurfaceFactory.cpp | 40 ++- tools/gpu/BackendSurfaceFactory.h | 16 +- tools/gpu/BackendTextureImageFactory.cpp | 42 +-- tools/gpu/ManagedBackendTexture.cpp | 27 ++ tools/gpu/ManagedBackendTexture.h | 82 ++++++ 26 files changed, 391 insertions(+), 368 deletions(-) create mode 100644 tools/gpu/ManagedBackendTexture.cpp create mode 100644 tools/gpu/ManagedBackendTexture.h diff --git a/BUILD.gn b/BUILD.gn index 200651611e..66b957d526 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1606,6 +1606,8 @@ if (skia_enable_tools) { "tools/gpu/FlushFinishTracker.h", "tools/gpu/GrContextFactory.cpp", "tools/gpu/GrTest.cpp", + "tools/gpu/ManagedBackendTexture.cpp", + "tools/gpu/ManagedBackendTexture.h", "tools/gpu/MemoryCache.cpp", "tools/gpu/MemoryCache.h", "tools/gpu/ProxyUtils.cpp", diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 63ab4e3857..1ac89a6f15 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -1468,9 +1468,7 @@ Result GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream* dstStream, SkStri return this->onDraw(src, dst, dstStream, log, fBaseContextOptions); } -sk_sp GPUSink::createDstSurface(GrDirectContext* context, - SkISize size, - GrBackendTexture* backendTexture) const { +sk_sp GPUSink::createDstSurface(GrDirectContext* context, SkISize size) const { sk_sp surface; SkImageInfo info = SkImageInfo::Make(size, fColorType, fAlphaType, fColorSpace); @@ -1483,21 +1481,25 @@ sk_sp GPUSink::createDstSurface(GrDirectContext* context, &props); break; case SkCommandLineConfigGpu::SurfType::kBackendTexture: - CreateBackendTexture(context, backendTexture, info.width(), info.height(), - info.colorType(), SkColors::kTransparent, GrMipmapped::kNo, - GrRenderable::kYes, GrProtected::kNo); - surface = SkSurface::MakeFromBackendTexture(context, *backendTexture, - kTopLeft_GrSurfaceOrigin, fSampleCount, - fColorType, info.refColorSpace(), &props); + surface = sk_gpu_test::MakeBackendTextureSurface(context, + info.dimensions(), + kTopLeft_GrSurfaceOrigin, + fSampleCount, + info.colorType(), + info.refColorSpace(), + GrMipmapped::kNo, + GrProtected::kNo, + &props); break; case SkCommandLineConfigGpu::SurfType::kBackendRenderTarget: - surface = MakeBackendRenderTargetSurface(context, - info.dimensions(), - fSampleCount, - kBottomLeft_GrSurfaceOrigin, - info.colorType(), - info.refColorSpace(), - &props); + surface = sk_gpu_test::MakeBackendRenderTargetSurface(context, + info.dimensions(), + kBottomLeft_GrSurfaceOrigin, + fSampleCount, + info.colorType(), + info.refColorSpace(), + GrProtected::kNo, + &props); break; } @@ -1536,8 +1538,7 @@ Result GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log, return Result::Skip("Src too large to create a texture.\n"); } - GrBackendTexture backendTexture; - sk_sp surface = this->createDstSurface(direct, src.size(), &backendTexture); + sk_sp surface = this->createDstSurface(direct, src.size()); if (!surface) { return Result::Fatal("Could not create a surface."); } @@ -1563,12 +1564,7 @@ Result GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log, } else if (FLAGS_releaseAndAbandonGpuContext) { factory.releaseResourcesAndAbandonContexts(); } - if (!direct->abandoned()) { - surface.reset(); - if (backendTexture.isValid()) { - direct->deleteBackendTexture(backendTexture); - } - } + if (grOptions.fPersistentCache) { direct->storeVkPipelineCacheData(); } @@ -1743,8 +1739,7 @@ Result GPUOOPRSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* lo SkASSERT(context->priv().getGpu()); - GrBackendTexture backendTexture; - sk_sp surface = this->createDstSurface(context, src.size(), &backendTexture); + sk_sp surface = this->createDstSurface(context, src.size()); if (!surface) { return Result::Fatal("Could not create a surface."); } @@ -1764,11 +1759,6 @@ Result GPUOOPRSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* lo return Result::Fatal("Could not readback from surface."); } - surface.reset(); - if (backendTexture.isValid()) { - context->deleteBackendTexture(backendTexture); - } - return Result::Ok(); } @@ -1918,8 +1908,7 @@ Result GPUDDLSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log // Make sure 'mainCtx' is current mainTestCtx->makeCurrent(); - GrBackendTexture backendTexture; - sk_sp surface = this->createDstSurface(mainCtx, src.size(), &backendTexture); + sk_sp surface = this->createDstSurface(mainCtx, src.size()); if (!surface) { return Result::Fatal("Could not create a surface."); } @@ -1949,11 +1938,6 @@ Result GPUDDLSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log return Result::Fatal("Could not readback from surface."); } - surface.reset(); - if (backendTexture.isValid()) { - mainCtx->deleteBackendTexture(backendTexture); - } - return Result::Ok(); } diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 10c4260c31..3ff2689eb6 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -407,7 +407,7 @@ public: } protected: - sk_sp createDstSurface(GrDirectContext*, SkISize size, GrBackendTexture*) const; + sk_sp createDstSurface(GrDirectContext*, SkISize size) const; bool readBack(SkSurface*, SkBitmap* dst) const; private: diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 5a014df657..b6aa43c039 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -673,9 +673,11 @@ public: * buffer for resolving. If the color is non-null the backing store should be cleared to the * passed in color. */ - virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize, - GrColorType, - int sampleCount = 1) = 0; + virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget( + SkISize dimensions, + GrColorType, + int sampleCount = 1, + GrProtected = GrProtected::kNo) = 0; /** * Deletes a GrBackendRenderTarget allocated with the above. Synchronization to make this safe diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp index 911ca27134..b3f22b951b 100644 --- a/src/gpu/d3d/GrD3DGpu.cpp +++ b/src/gpu/d3d/GrD3DGpu.cpp @@ -1259,7 +1259,8 @@ bool GrD3DGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { GrBackendRenderTarget GrD3DGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType colorType, - int sampleCnt) { + int sampleCnt, + GrProtected isProtected) { this->handleDirtyContext(); if (dimensions.width() > this->caps()->maxRenderTargetSize() || @@ -1272,7 +1273,7 @@ GrBackendRenderTarget GrD3DGpu::createTestingOnlyBackendRenderTarget(SkISize dim GrD3DTextureResourceInfo info; if (!this->createTextureResourceForBackendSurface(dxgiFormat, dimensions, GrTexturable::kNo, GrRenderable::kYes, GrMipmapped::kNo, - sampleCnt, &info, GrProtected::kNo)) { + sampleCnt, &info, isProtected)) { return {}; } diff --git a/src/gpu/d3d/GrD3DGpu.h b/src/gpu/d3d/GrD3DGpu.h index c1ff184535..58a656f5b8 100644 --- a/src/gpu/d3d/GrD3DGpu.h +++ b/src/gpu/d3d/GrD3DGpu.h @@ -65,9 +65,10 @@ public: #if GR_TEST_UTILS bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; - GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize, + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType, - int sampleCnt) override; + int sampleCnt, + GrProtected) override; void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; void testingOnly_flushGpuAndSync() override; diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp index bd327913c9..bb1d3adec3 100644 --- a/src/gpu/dawn/GrDawnGpu.cpp +++ b/src/gpu/dawn/GrDawnGpu.cpp @@ -493,7 +493,8 @@ bool GrDawnGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { GrBackendRenderTarget GrDawnGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType colorType, - int sampleCnt) { + int sampleCnt, + GrProtected isProtected) { if (dimensions.width() > this->caps()->maxTextureSize() || dimensions.height() > this->caps()->maxTextureSize()) { return {}; @@ -504,6 +505,10 @@ GrBackendRenderTarget GrDawnGpu::createTestingOnlyBackendRenderTarget(SkISize di return {}; } + if (isProtected == GrProtected::kYes) { + return {}; + } + wgpu::TextureFormat format; if (!GrColorTypeToDawnFormat(colorType, &format)) { return {}; diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h index 15bc2536a4..e6acb7fcee 100644 --- a/src/gpu/dawn/GrDawnGpu.h +++ b/src/gpu/dawn/GrDawnGpu.h @@ -53,9 +53,10 @@ public: #if GR_TEST_UTILS bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; - GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize, + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType, - int sampleCnt) override; + int sampleCnt, + GrProtected) override; void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; void testingOnly_flushGpuAndSync() override; diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 6a9c0d9ba5..69062bc74d 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -3704,11 +3704,16 @@ bool GrGLGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType colorType, - int sampleCnt) { + int sampleCnt, + GrProtected isProtected) { if (dimensions.width() > this->caps()->maxRenderTargetSize() || dimensions.height() > this->caps()->maxRenderTargetSize()) { return {}; } + if (isProtected == GrProtected::kYes) { + return {}; + } + this->handleDirtyContext(); auto format = this->glCaps().getFormatFromColorType(colorType); sampleCnt = this->glCaps().getRenderTargetSampleCount(sampleCnt, format); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 68e08918f0..e930f44d05 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -146,9 +146,10 @@ public: #if GR_TEST_UTILS bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; - GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize, + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType, - int sampleCnt) override; + int sampleCnt, + GrProtected) override; void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; const GrGLContext* glContextForTesting() const override { return &this->glContext(); } diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp index fbadc27c88..1839930b19 100644 --- a/src/gpu/mock/GrMockGpu.cpp +++ b/src/gpu/mock/GrMockGpu.cpp @@ -341,7 +341,8 @@ bool GrMockGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { GrBackendRenderTarget GrMockGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType colorType, - int sampleCnt) { + int sampleCnt, + GrProtected) { GrMockRenderTargetInfo info(colorType, NextExternalRenderTargetID()); static constexpr int kStencilBits = 8; return GrBackendRenderTarget(dimensions.width(), dimensions.height(), sampleCnt, kStencilBits, diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index d010b5c23d..0153110a41 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -179,7 +179,8 @@ private: GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType, - int sampleCnt) override; + int sampleCnt, + GrProtected) override; void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; void testingOnly_flushGpuAndSync() override {} diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h index eb58fc7b53..247832161e 100644 --- a/src/gpu/mtl/GrMtlGpu.h +++ b/src/gpu/mtl/GrMtlGpu.h @@ -65,9 +65,10 @@ public: #if GR_TEST_UTILS bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; - GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize, + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType, - int sampleCnt) override; + int sampleCnt, + GrProtected) override; void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; void testingOnly_flushGpuAndSync() override; diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm index 1fc1c2d028..7af0dbf03c 100644 --- a/src/gpu/mtl/GrMtlGpu.mm +++ b/src/gpu/mtl/GrMtlGpu.mm @@ -1101,11 +1101,15 @@ bool GrMtlGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { GrBackendRenderTarget GrMtlGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType ct, - int sampleCnt) { + int sampleCnt, + GrProtected isProtected) { if (dimensions.width() > this->caps()->maxRenderTargetSize() || dimensions.height() > this->caps()->maxRenderTargetSize()) { return {}; } + if (isProtected == GrProtected::kYes) { + return {}; + } MTLPixelFormat format = this->mtlCaps().getFormatFromColorType(ct); sampleCnt = this->mtlCaps().getRenderTargetSampleCount(sampleCnt, format); diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 167b0b5a73..892e7a0bec 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -2025,7 +2025,8 @@ bool GrVkGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const { GrBackendRenderTarget GrVkGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType ct, - int sampleCnt) { + int sampleCnt, + GrProtected isProtected) { this->handleDirtyContext(); if (dimensions.width() > this->caps()->maxRenderTargetSize() || @@ -2038,7 +2039,7 @@ GrBackendRenderTarget GrVkGpu::createTestingOnlyBackendRenderTarget(SkISize dime GrVkImageInfo info; if (!this->createVkImageForBackendSurface(vkFormat, dimensions, sampleCnt, GrTexturable::kNo, GrRenderable::kYes, GrMipmapped::kNo, &info, - GrProtected::kNo)) { + isProtected)) { return {}; } return GrBackendRenderTarget(dimensions.width(), dimensions.height(), 0, info); diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index 4f829007a8..7e457986c7 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -94,9 +94,10 @@ public: #if GR_TEST_UTILS bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; - GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize, + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions, GrColorType, - int sampleCnt) override; + int sampleCnt, + GrProtected) override; void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; void testingOnly_flushGpuAndSync() override; diff --git a/tests/BlendTest.cpp b/tests/BlendTest.cpp index 6aedefcf0c..c9313cd3e3 100644 --- a/tests/BlendTest.cpp +++ b/tests/BlendTest.cpp @@ -124,8 +124,11 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ES2BlendWithNoTexture, reporter, ctxInfo) GrSurfaceOrigin origin = testCase.fOrigin; // BGRA forces a framebuffer blit on ES2. - sk_sp surface = - MakeBackendRenderTargetSurface(context, kDimensions, sampleCnt, origin, kColorType); + sk_sp surface = sk_gpu_test::MakeBackendRenderTargetSurface(context, + kDimensions, + origin, + sampleCnt, + kColorType); if (!surface && sampleCnt > 1) { // Some platforms don't support MSAA. diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp index be736235c5..f4b4494a29 100644 --- a/tests/DeferredDisplayListTest.cpp +++ b/tests/DeferredDisplayListTest.cpp @@ -42,6 +42,7 @@ #include "src/image/SkSurface_Gpu.h" #include "tests/Test.h" #include "tests/TestUtils.h" +#include "tools/gpu/BackendSurfaceFactory.h" #include "tools/gpu/GrContextFactory.h" #include @@ -55,13 +56,11 @@ class SurfaceParameters { public: static const int kNumParams = 12; - static const int kSampleCount = 5; - static const int kMipMipCount = 8; static const int kFBO0Count = 9; - static const int kProtectedCount = 11; SurfaceParameters(GrRecordingContext* rContext) : fBackend(rContext->backend()) + , fCanBeProtected(false) , fWidth(64) , fHeight(64) , fOrigin(kTopLeft_GrSurfaceOrigin) @@ -75,12 +74,17 @@ public: , fIsProtected(GrProtected::kNo) , fVkRTSupportsInputAttachment(false) { #ifdef SK_VULKAN - if (GrBackendApi::kVulkan == rContext->backend()) { - const GrVkCaps* vkCaps = (const GrVkCaps*) rContext->priv().caps(); - - fIsProtected = GrProtected(vkCaps->supportsProtectedMemory()); + if (rContext->backend() == GrBackendApi::kVulkan) { + auto vkCaps = static_cast(rContext->priv().caps()); + fCanBeProtected = vkCaps->supportsProtectedMemory(); + if (fCanBeProtected) { + fIsProtected = GrProtected::kYes; + } } #endif + if (!rContext->priv().caps()->mipmapSupport()) { + fShouldCreateMipMaps = false; + } } int sampleCount() const { return fSampleCount; } @@ -88,7 +92,10 @@ public: void setColorType(SkColorType ct) { fColorType = ct; } SkColorType colorType() const { return fColorType; } void setColorSpace(sk_sp cs) { fColorSpace = std::move(cs); } - void setTextureable(bool isTextureable) { fIsTextureable = isTextureable; } + void disableTextureability() { + fIsTextureable = false; + fShouldCreateMipMaps = false; + } void setShouldCreateMipMaps(bool shouldCreateMipMaps) { fShouldCreateMipMaps = shouldCreateMipMaps; } @@ -96,55 +103,66 @@ public: fVkRTSupportsInputAttachment = inputSupport; } - // Modify the SurfaceParameters in just one way - void modify(int i) { + // Modify the SurfaceParameters in just one way. Returns false if the requested modification had + // no effect. + bool modify(int i) { + bool changed = false; + auto set = [&changed](auto& var, auto value) { + if (var != value) { + changed = true; + } + var = value; + }; switch (i) { case 0: - fWidth = 63; + set(fWidth, 63); break; case 1: - fHeight = 63; + set(fHeight, 63); break; case 2: - fOrigin = kBottomLeft_GrSurfaceOrigin; + set(fOrigin, kBottomLeft_GrSurfaceOrigin); break; case 3: - fColorType = kRGBA_F16_SkColorType; + set(fColorType, kRGBA_F16_SkColorType); break; case 4: // This just needs to be a colorSpace different from that returned by MakeSRGB(). // In this case we just change the gamut. - fColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kAdobeRGB); + set(fColorSpace, SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, + SkNamedGamut::kAdobeRGB)); break; - case kSampleCount: - fSampleCount = 4; + case 5: + set(fSampleCount, 4); break; case 6: - fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry); + set(fSurfaceProps, SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry)); break; case 7: - fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag, - kUnknown_SkPixelGeometry); + set(fSurfaceProps, SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag, + kUnknown_SkPixelGeometry)); break; case 8: - fShouldCreateMipMaps = false; + set(fShouldCreateMipMaps, false); break; case 9: if (GrBackendApi::kOpenGL == fBackend) { - fUsesGLFBO0 = true; - fShouldCreateMipMaps = false; // needs to changed in tandem w/ textureability - fIsTextureable = false; + set(fUsesGLFBO0, true); + set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability + set(fIsTextureable, false); } break; case 10: - fShouldCreateMipMaps = false; // needs to changed in tandem w/ textureability - fIsTextureable = false; + set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability + set(fIsTextureable, false); break; case 11: - fIsProtected = GrProtected::kYes == fIsProtected ? GrProtected::kNo - : GrProtected::kYes; + if (fCanBeProtected) { + set(fIsProtected, GrProtected(!static_cast(fIsProtected))); + } break; } + return changed; } SkSurfaceCharacterization createCharacterization(GrDirectContext* dContext) const { @@ -188,13 +206,9 @@ public: } // Create the surface with the current set of parameters - sk_sp make(GrDirectContext* dContext, GrBackendTexture* backend) const { + sk_sp make(GrDirectContext* dContext) const { const SkSurfaceCharacterization c = this->createCharacterization(dContext); - GrMipmapped mipmapped = !fIsTextureable - ? GrMipmapped::kNo - : GrMipmapped(fShouldCreateMipMaps); - #ifdef SK_GL if (fUsesGLFBO0) { if (GrBackendApi::kOpenGL != dContext->backend()) { @@ -219,45 +233,50 @@ public: return result; } #endif - CreateBackendTexture(dContext, backend, fWidth, fHeight, fColorType, - SkColors::kTransparent, mipmapped, GrRenderable::kYes, fIsProtected); - if (!backend->isValid()) { - return nullptr; - } - - // Even if a characterization couldn't be constructed we want to soldier on to make - // sure that surface creation will/would've also failed - SkASSERT(!c.isValid() || c.isCompatible(*backend)); sk_sp surface; - if (!fIsTextureable) { - // Create a surface w/ the current parameters but make it non-textureable - surface = SkSurface::MakeFromBackendTextureAsRenderTarget( - dContext, *backend, fOrigin, fSampleCount, fColorType, - fColorSpace, &fSurfaceProps); + if (fIsTextureable) { + surface = sk_gpu_test::MakeBackendTextureSurface(dContext, + {fWidth, fHeight}, + fOrigin, + fSampleCount, + fColorType, + fColorSpace, + GrMipmapped(fShouldCreateMipMaps), + fIsProtected, + &fSurfaceProps); } else { - surface = SkSurface::MakeFromBackendTexture( - dContext, *backend, fOrigin, fSampleCount, fColorType, - fColorSpace, &fSurfaceProps); + // Create a surface w/ the current parameters but make it non-textureable + SkASSERT(!fShouldCreateMipMaps); + surface = sk_gpu_test::MakeBackendRenderTargetSurface(dContext, + {fWidth, fHeight}, + fOrigin, + fSampleCount, + fColorType, + fColorSpace, + fIsProtected, + &fSurfaceProps); } if (!surface) { SkASSERT(!c.isValid()); - this->cleanUpBackEnd(dContext, *backend); return nullptr; } + GrBackendTexture texture = + surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess); + if (texture.isValid()) { + SkASSERT(c.isCompatible(texture)); + } SkASSERT(c.isValid()); SkASSERT(surface->isCompatible(c)); return surface; } - void cleanUpBackEnd(GrDirectContext* dContext, const GrBackendTexture& backend) const { - dContext->deleteBackendTexture(backend); - } - private: GrBackendApi fBackend; + bool fCanBeProtected; + int fWidth; int fHeight; GrSurfaceOrigin fOrigin; @@ -276,43 +295,29 @@ private: DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) { auto context = ctxInfo.directContext(); - bool mipmapSupport = context->priv().caps()->mipmapSupport(); - for (int i = 0; i < SurfaceParameters::kNumParams; ++i) { + for (int i = -1; i < SurfaceParameters::kNumParams; ++i) { SurfaceParameters params1(context); - params1.modify(i); + bool didModify1 = i >= 0 && params1.modify(i); SkSurfaceCharacterization char1 = params1.createCharacterization(context); if (!char1.isValid()) { continue; // can happen on some platforms (ChromeOS) } - if (SurfaceParameters::kMipMipCount == i && !mipmapSupport) { - // If changing the mipmap setting won't result in a different surface characterization, - // skip this step. - continue; - } - - for (int j = 0; j < SurfaceParameters::kNumParams; ++j) { + for (int j = -1; j < SurfaceParameters::kNumParams; ++j) { SurfaceParameters params2(context); - params2.modify(j); + bool didModify2 = j >= 0 && params2.modify(j); SkSurfaceCharacterization char2 = params2.createCharacterization(context); if (!char2.isValid()) { continue; // can happen on some platforms (ChromeOS) } - if (SurfaceParameters::kMipMipCount == j && !mipmapSupport) { - // If changing the mipmap setting won't result in a different surface - // characterization, skip this step. - continue; - } - - if (i == j) { + if (i == j || (!didModify1 && !didModify2)) { REPORTER_ASSERT(reporter, char1 == char2); } else { REPORTER_ASSERT(reporter, char1 != char2); } - } } @@ -334,9 +339,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) { //////////////////////////////////////////////////////////////////////////////// // This tests SkSurfaceCharacterization/SkSurface compatibility void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) { - GrGpu* gpu = dContext->priv().getGpu(); - const GrCaps* caps = dContext->priv().caps(); - // Create a bitmap that we can readback into SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kPremul_SkAlphaType); @@ -355,88 +357,39 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep SkAssertResult(ddl); // The DDL should draw into an SkSurface created with the same parameters - GrBackendTexture backend; - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (!s) { return; } REPORTER_ASSERT(reporter, s->draw(ddl)); s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); - dContext->flushAndSubmit(); - gpu->testingOnly_flushGpuAndSync(); - s = nullptr; - params.cleanUpBackEnd(dContext, backend); + + dContext->flush(); } // Then, alter each parameter in turn and check that the DDL & surface are incompatible for (int i = 0; i < SurfaceParameters::kNumParams; ++i) { SurfaceParameters params(dContext); - params.modify(i); - - if (SurfaceParameters::kProtectedCount == i) { - if (dContext->backend() != GrBackendApi::kVulkan) { - // Only the Vulkan backend respects the protected parameter - continue; - } -#ifdef SK_VULKAN - const GrVkCaps* vkCaps = (const GrVkCaps*) dContext->priv().caps(); - - // And, even then, only when it is a protected context - if (!vkCaps->supportsProtectedMemory()) { - continue; - } -#endif + if (!params.modify(i)) { + continue; } - GrBackendTexture backend; - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (!s) { continue; } - if (SurfaceParameters::kSampleCount == i) { - int supportedSampleCount = caps->getRenderTargetSampleCount( - params.sampleCount(), backend.getBackendFormat()); - if (1 == supportedSampleCount) { - // If changing the sample count won't result in a different - // surface characterization, skip this step - s = nullptr; - params.cleanUpBackEnd(dContext, backend); - continue; - } - } - - if (SurfaceParameters::kMipMipCount == i && !caps->mipmapSupport()) { - // If changing the mipmap setting won't result in a different surface characterization, - // skip this step - s = nullptr; - params.cleanUpBackEnd(dContext, backend); - continue; - } - - if (SurfaceParameters::kFBO0Count == i && dContext->backend() != GrBackendApi::kOpenGL) { - // FBO0 only affects the surface characterization when using OpenGL - s = nullptr; - params.cleanUpBackEnd(dContext, backend); - continue; - } - REPORTER_ASSERT(reporter, !s->draw(ddl), "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i); - - dContext->flushAndSubmit(); - gpu->testingOnly_flushGpuAndSync(); - s = nullptr; - params.cleanUpBackEnd(dContext, backend); + dContext->flush(); } // Next test the compatibility of resource cache parameters { const SurfaceParameters params(dContext); - GrBackendTexture backend; - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); size_t maxResourceBytes = dContext->getResourceCacheLimit(); @@ -460,27 +413,19 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); #endif - dContext->flushAndSubmit(); - gpu->testingOnly_flushGpuAndSync(); - s = nullptr; - params.cleanUpBackEnd(dContext, backend); + dContext->flush(); } // Test that the textureability of the DDL characterization can block a DDL draw { - GrBackendTexture backend; SurfaceParameters params(dContext); - params.setShouldCreateMipMaps(false); - params.setTextureable(false); + params.disableTextureability(); - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (s) { REPORTER_ASSERT(reporter, !s->draw(ddl)); // bc the DDL was made w/ textureability - dContext->flushAndSubmit(); - gpu->testingOnly_flushGpuAndSync(); - s = nullptr; - params.cleanUpBackEnd(dContext, backend); + dContext->flush(); } } @@ -496,9 +441,8 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep // Exercise the createResized method { SurfaceParameters params(dContext); - GrBackendTexture backend; - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (!s) { return; } @@ -519,17 +463,13 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep REPORTER_ASSERT(reporter, char3.isValid()); REPORTER_ASSERT(reporter, 32 == char3.width()); REPORTER_ASSERT(reporter, 32 == char3.height()); - - s = nullptr; - params.cleanUpBackEnd(dContext, backend); } // Exercise the createColorSpace method { SurfaceParameters params(dContext); - GrBackendTexture backend; - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (!s) { return; } @@ -564,17 +504,13 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep SkSurfaceCharacterization stillInvalid = invalid.createColorSpace(std::move(newCS)); REPORTER_ASSERT(reporter, !stillInvalid.isValid()); } - - s = nullptr; - params.cleanUpBackEnd(dContext, backend); } // Exercise the createBackendFormat method { SurfaceParameters params(dContext); - GrBackendTexture backend; - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (!s) { return; } @@ -603,9 +539,6 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep newBackendFormat); REPORTER_ASSERT(reporter, !stillInvalid.isValid()); } - - s = nullptr; - params.cleanUpBackEnd(dContext, backend); } // Exercise the createFBO0 method @@ -613,11 +546,9 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep SurfaceParameters params(dContext); // If the original characterization is textureable then we will fail trying to make an // FBO0 characterization - params.setTextureable(false); - params.setShouldCreateMipMaps(false); - GrBackendTexture backend; + params.disableTextureability(); - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (!s) { return; } @@ -640,9 +571,6 @@ void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Rep SkSurfaceCharacterization stillInvalid = invalid.createFBO0(true); REPORTER_ASSERT(reporter, !stillInvalid.isValid()); } - - s = nullptr; - params.cleanUpBackEnd(dContext, backend); } } @@ -731,7 +659,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctx // into a textureable destination. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) { auto context = ctxInfo.directContext(); - GrGpu* gpu = context->priv().getGpu(); // Create a bitmap that we can readback into SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, @@ -746,8 +673,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) // reusable DDLs, move this outside of the loop. { SurfaceParameters params(context); - params.setShouldCreateMipMaps(false); - params.setTextureable(false); + params.disableTextureability(); if (context->backend() == GrBackendApi::kVulkan) { params.setVkRTInputAttachmentSupport(true); } @@ -758,24 +684,22 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) // Then verify it can draw into either flavor of destination SurfaceParameters params(context); - params.setShouldCreateMipMaps(textureability); - params.setTextureable(textureability); + if (!textureability) { + params.disableTextureability(); + } if (context->backend() == GrBackendApi::kVulkan) { params.setVkRTInputAttachmentSupport(true); } - GrBackendTexture backend; - sk_sp s = params.make(context, &backend); + sk_sp s = params.make(context); if (!s) { continue; } REPORTER_ASSERT(reporter, s->draw(ddl)); s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); - context->flushAndSubmit(); - gpu->testingOnly_flushGpuAndSync(); - s = nullptr; - params.cleanUpBackEnd(context, backend); + + context->flush(); } } @@ -787,33 +711,27 @@ static void test_make_render_target(skiatest::Reporter* reporter, const SkSurfaceCharacterization c = params.createCharacterization(dContext); if (!c.isValid()) { - GrBackendTexture backend; - sk_sp tmp = params.make(dContext, &backend); - + sk_sp tmp = params.make(dContext); // If we couldn't characterize the surface we shouldn't be able to create it either REPORTER_ASSERT(reporter, !tmp); - if (tmp) { - tmp = nullptr; - params.cleanUpBackEnd(dContext, backend); - } return; } } const SkSurfaceCharacterization c = params.createCharacterization(dContext); - GrBackendTexture backend; - { - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); REPORTER_ASSERT(reporter, s); if (!s) { REPORTER_ASSERT(reporter, !c.isValid()); - params.cleanUpBackEnd(dContext, backend); return; } REPORTER_ASSERT(reporter, c.isValid()); - REPORTER_ASSERT(reporter, c.isCompatible(backend)); + GrBackendTexture backend = s->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess); + if (backend.isValid()) { + REPORTER_ASSERT(reporter, c.isCompatible(backend)); + } REPORTER_ASSERT(reporter, s->isCompatible(c)); // Note that we're leaving 'backend' live here } @@ -824,8 +742,6 @@ static void test_make_render_target(skiatest::Reporter* reporter, REPORTER_ASSERT(reporter, s); REPORTER_ASSERT(reporter, s->isCompatible(c)); } - - params.cleanUpBackEnd(dContext, backend); } //////////////////////////////////////////////////////////////////////////////// @@ -833,34 +749,15 @@ static void test_make_render_target(skiatest::Reporter* reporter, // In particular, the SkSurface, backendTexture and SkSurfaceCharacterization // should always be compatible. void DDLMakeRenderTargetTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) { - for (int i = 0; i < SurfaceParameters::kNumParams; ++i) { - + for (int i = -1; i < SurfaceParameters::kNumParams; ++i) { if (SurfaceParameters::kFBO0Count == i) { // MakeRenderTarget doesn't support FBO0 continue; } - if (SurfaceParameters::kProtectedCount == i) { - if (dContext->backend() != GrBackendApi::kVulkan) { - // Only the Vulkan backend respects the protected parameter - continue; - } -#ifdef SK_VULKAN - const GrVkCaps* vkCaps = (const GrVkCaps*) dContext->priv().caps(); - - // And, even then, only when it is a protected context - if (!vkCaps->supportsProtectedMemory()) { - continue; - } -#endif - } - - SurfaceParameters params(dContext); - params.modify(i); - - if (!dContext->priv().caps()->mipmapSupport()) { - params.setShouldCreateMipMaps(false); + if (i >= 0 && !params.modify(i)) { + continue; } test_make_render_target(reporter, dContext, params); @@ -898,9 +795,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) { } SurfaceParameters params(dContext); - GrBackendTexture backend; - sk_sp s = params.make(dContext, &backend); + sk_sp s = params.make(dContext); if (!s) { dContext->deleteBackendTexture(backendTex); return; @@ -917,7 +813,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) { auto rContext = canvas->recordingContext(); if (!rContext) { s = nullptr; - params.cleanUpBackEnd(dContext, backend); dContext->deleteBackendTexture(backendTex); return; } @@ -931,9 +826,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) { REPORTER_ASSERT(reporter, !image); dContext->deleteBackendTexture(backendTex); - - s = nullptr; - params.cleanUpBackEnd(dContext, backend); } static sk_sp dummy_fulfill_proc(void*) { @@ -1277,10 +1169,6 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) { params.setColorType(colorType); params.setColorSpace(nullptr); - if (!context->priv().caps()->mipmapSupport()) { - params.setShouldCreateMipMaps(false); - } - test_make_render_target(reporter, context, params); } diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp index 09da368e90..fe588cf8d8 100644 --- a/tests/SurfaceTest.cpp +++ b/tests/SurfaceTest.cpp @@ -159,8 +159,11 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrContext_colorTypeSupportedAsSurface, report } for (int sampleCnt : {1, 2}) { - auto surf = MakeBackendRenderTargetSurface(context, {16, 16}, sampleCnt, - kTopLeft_GrSurfaceOrigin, colorType); + auto surf = sk_gpu_test::MakeBackendRenderTargetSurface(context, + {16, 16}, + kTopLeft_GrSurfaceOrigin, + sampleCnt, + colorType); bool can = context->colorTypeSupportedAsSurface(colorType) && context->maxSurfaceSampleCountForColorType(colorType) >= sampleCnt; if (!surf && can && colorType == kBGRA_8888_SkColorType && sampleCnt > 1 && @@ -740,9 +743,14 @@ static sk_sp create_gpu_surface_backend_render_target(GrDirectContext const int kWidth = 10; const int kHeight = 10; - auto surf = MakeBackendRenderTargetSurface(dContext, {kWidth, kHeight}, sampleCnt, - kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, - nullptr, nullptr); + auto surf = sk_gpu_test::MakeBackendRenderTargetSurface(dContext, + {kWidth, kHeight}, + kTopLeft_GrSurfaceOrigin, + sampleCnt, + kRGBA_8888_SkColorType, + nullptr, + GrProtected::kNo, + nullptr); if (!surf) { return nullptr; } diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp index 51171823fc..221dc23cb9 100644 --- a/tests/WritePixelsTest.cpp +++ b/tests/WritePixelsTest.cpp @@ -461,8 +461,11 @@ static void test_write_pixels_non_texture(skiatest::Reporter* reporter, } for (auto& origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) { SkColorType colorType = kN32_SkColorType; - auto surface = MakeBackendRenderTargetSurface(dContext, {DEV_W, DEV_H}, sampleCnt, origin, - colorType); + auto surface = sk_gpu_test::MakeBackendRenderTargetSurface(dContext, + {DEV_W, DEV_H}, + origin, + sampleCnt, + colorType); if (surface) { auto ii = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); test_write_pixels(reporter, surface.get(), ii); diff --git a/tools/fm/fm.cpp b/tools/fm/fm.cpp index 6b9aef0ed4..6e1c4b0ced 100644 --- a/tools/fm/fm.cpp +++ b/tools/fm/fm.cpp @@ -311,8 +311,6 @@ static sk_sp draw_with_gpu(std::function draw, SkSurfaceProps props(flags, kRGB_H_SkPixelGeometry); sk_sp surface; - GrBackendTexture backendTexture; - GrBackendRenderTarget backendRT; switch (surfaceType) { case SurfaceType::kDefault: @@ -324,29 +322,26 @@ static sk_sp draw_with_gpu(std::function draw, break; case SurfaceType::kBackendTexture: - backendTexture = context->createBackendTexture(info.width(), - info.height(), - info.colorType(), - GrMipmapped::kNo, - GrRenderable::kYes, - GrProtected::kNo); - surface = SkSurface::MakeFromBackendTexture(context, - backendTexture, - kTopLeft_GrSurfaceOrigin, - FLAGS_samples, - info.colorType(), - info.refColorSpace(), - &props); + surface = sk_gpu_test::MakeBackendTextureSurface(context, + info.dimensions(), + kTopLeft_GrSurfaceOrigin, + FLAGS_samples, + info.colorType(), + info.refColorSpace(), + GrMipmapped::kNo, + GrProtected::kNo, + &props); break; case SurfaceType::kBackendRenderTarget: - surface = MakeBackendRenderTargetSurface(context, - info.dimensions(), - FLAGS_samples, - kBottomLeft_GrSurfaceOrigin, - info.colorType(), - info.refColorSpace(), - &props); + surface = sk_gpu_test::MakeBackendRenderTargetSurface(context, + info.dimensions(), + kBottomLeft_GrSurfaceOrigin, + FLAGS_samples, + info.colorType(), + info.refColorSpace(), + GrProtected::kNo, + &props); break; } @@ -370,16 +365,6 @@ static sk_sp draw_with_gpu(std::function draw, factory->releaseResourcesAndAbandonContexts(); } - if (!context->abandoned()) { - surface.reset(); - if (backendTexture.isValid()) { - context->deleteBackendTexture(backendTexture); - } - if (backendRT.isValid()) { - context->priv().getGpu()->deleteTestingOnlyBackendRenderTarget(backendRT); - } - } - return image; } diff --git a/tools/gpu/BackendSurfaceFactory.cpp b/tools/gpu/BackendSurfaceFactory.cpp index beae0841c6..32a6500692 100644 --- a/tools/gpu/BackendSurfaceFactory.cpp +++ b/tools/gpu/BackendSurfaceFactory.cpp @@ -11,13 +11,47 @@ #include "include/gpu/GrDirectContext.h" #include "src/gpu/GrContextPriv.h" #include "src/gpu/GrGpu.h" +#include "tools/gpu/ManagedBackendTexture.h" + +namespace sk_gpu_test { + +sk_sp MakeBackendTextureSurface(GrDirectContext* context, + SkISize dimensions, + GrSurfaceOrigin origin, + int sampleCnt, + SkColorType colorType, + sk_sp colorSpace, + GrMipmapped mipMapped, + GrProtected isProtected, + const SkSurfaceProps* props) { + auto mbet = ManagedBackendTexture::MakeWithoutData(context, + dimensions.fWidth, + dimensions.fHeight, + colorType, + mipMapped, + GrRenderable::kYes, + isProtected); + if (!mbet) { + return nullptr; + } + return SkSurface::MakeFromBackendTexture(context, + mbet->texture(), + origin, + sampleCnt, + colorType, + std::move(colorSpace), + props, + ManagedBackendTexture::ReleaseProc, + mbet->releaseContext()); +} sk_sp MakeBackendRenderTargetSurface(GrDirectContext* context, SkISize dimensions, - int sampleCnt, GrSurfaceOrigin origin, + int sampleCnt, SkColorType colorType, sk_sp colorSpace, + GrProtected isProtected, const SkSurfaceProps* props) { auto ct = SkColorTypeToGrColorType(colorType); @@ -27,7 +61,7 @@ sk_sp MakeBackendRenderTargetSurface(GrDirectContext* context, }; auto bert = context->priv().getGpu()->createTestingOnlyBackendRenderTarget( - dimensions, ct, sampleCnt); + dimensions, ct, sampleCnt, isProtected); auto rc = new ReleaseContext{context, bert}; SkASSERT(!bert.isValid() || bert.sampleCnt() >= sampleCnt); @@ -42,3 +76,5 @@ sk_sp MakeBackendRenderTargetSurface(GrDirectContext* context, return SkSurface::MakeFromBackendRenderTarget( context, bert, origin, colorType, std::move(colorSpace), props, proc, rc); } + +} // namespace sk_gpu_test diff --git a/tools/gpu/BackendSurfaceFactory.h b/tools/gpu/BackendSurfaceFactory.h index 93dfa4d6ee..c0177e77aa 100644 --- a/tools/gpu/BackendSurfaceFactory.h +++ b/tools/gpu/BackendSurfaceFactory.h @@ -17,13 +17,27 @@ class GrDirectContext; class SkSurface; class SkSurfaceProps; +namespace sk_gpu_test { + +sk_sp MakeBackendTextureSurface(GrDirectContext*, + SkISize, + GrSurfaceOrigin, + int sampleCnt, + SkColorType, + sk_sp = nullptr, + GrMipmapped = GrMipmapped::kNo, + GrProtected = GrProtected::kNo, + const SkSurfaceProps* = nullptr); + /** Creates an SkSurface backed by a non-textureable render target. */ sk_sp MakeBackendRenderTargetSurface(GrDirectContext*, SkISize, - int sampleCnt, GrSurfaceOrigin, + int sampleCnt, SkColorType, sk_sp = nullptr, + GrProtected = GrProtected::kNo, const SkSurfaceProps* = nullptr); +} // namespace sk_gpu_test #endif diff --git a/tools/gpu/BackendTextureImageFactory.cpp b/tools/gpu/BackendTextureImageFactory.cpp index 618ea6c99d..b0faf45d70 100644 --- a/tools/gpu/BackendTextureImageFactory.cpp +++ b/tools/gpu/BackendTextureImageFactory.cpp @@ -12,41 +12,7 @@ #include "include/gpu/GrBackendSurface.h" #include "include/gpu/GrDirectContext.h" #include "src/core/SkAutoPixmapStorage.h" - -namespace { -class ManagedBackendTexture : public SkNVRefCnt { -public: - ~ManagedBackendTexture() { - if (fDContext && fTexture.isValid()) { - fDContext->submit(true); - fDContext->deleteBackendTexture(fTexture); - } - } - - static void Release(void* context) { static_cast(context)->unref(); } - - template - static sk_sp Make(GrDirectContext* dContext, Args&&... args) { - sk_sp mbet(new ManagedBackendTexture); - mbet->fDContext = dContext; - mbet->fTexture = dContext->createBackendTexture(std::forward(args)..., Release, - mbet->refAndPassAsContext()); - return mbet; - } - - const GrBackendTexture& texture() { return fTexture; } - - void* refAndPassAsContext() { - this->ref(); - return static_cast(this); - } - -private: - ManagedBackendTexture() = default; - GrDirectContext* fDContext = nullptr; - GrBackendTexture fTexture; -}; -} // namespace +#include "tools/gpu/ManagedBackendTexture.h" namespace sk_gpu_test { sk_sp MakeBackendTextureImage(GrDirectContext* dContext, @@ -64,14 +30,14 @@ sk_sp MakeBackendTextureImage(GrDirectContext* dContext, } src = &temp; } - auto mbet = ManagedBackendTexture::Make(dContext, src, 1, renderable, GrProtected::kNo); + auto mbet = ManagedBackendTexture::MakeWithData(dContext, src, 1, renderable, GrProtected::kNo); return SkImage::MakeFromTexture(dContext, mbet->texture(), origin, src->colorType(), src->alphaType(), src->refColorSpace(), - ManagedBackendTexture::Release, - mbet->refAndPassAsContext()); + ManagedBackendTexture::ReleaseProc, + mbet->releaseContext()); } } // namespace sk_gpu_test diff --git a/tools/gpu/ManagedBackendTexture.cpp b/tools/gpu/ManagedBackendTexture.cpp new file mode 100644 index 0000000000..8409caa409 --- /dev/null +++ b/tools/gpu/ManagedBackendTexture.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "tools/gpu/ManagedBackendTexture.h" + +namespace sk_gpu_test { + +void ManagedBackendTexture::ReleaseProc(void* context) { + static_cast(context)->unref(); +} + +ManagedBackendTexture::~ManagedBackendTexture() { + if (fDContext && fTexture.isValid()) { + fDContext->deleteBackendTexture(fTexture); + } +} + +void* ManagedBackendTexture::releaseContext() { + this->ref(); + return static_cast(this); +} + +} // namespace sk_gpu_test diff --git a/tools/gpu/ManagedBackendTexture.h b/tools/gpu/ManagedBackendTexture.h new file mode 100644 index 0000000000..cd3b023987 --- /dev/null +++ b/tools/gpu/ManagedBackendTexture.h @@ -0,0 +1,82 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef ManagedBackendTexture_DEFINED +#define ManagedBackendTexture_DEFINED + +#include "include/core/SkRefCnt.h" +#include "include/gpu/GrDirectContext.h" + +namespace sk_gpu_test { + +class ManagedBackendTexture : public SkNVRefCnt { +public: + /** + * Make a managed backend texture with initial pixmap/color data. The 'Args' are any valid set + * of arguments to GrDirectContext::createBackendTexture that takes data but with the release + * proc/context omitted as the ManagedBackendTexture will provide them. + */ + template + static sk_sp MakeWithData(GrDirectContext*, Args&&...); + + /** + * Make a managed backend texture without initial data. The 'Args' are any valid set of + * arguments to GrDirectContext::createBackendTexture that does not take data. Because our + * createBackendTexture methods that *do* take data also use default args for the proc/context + * this can be used to make a texture with data but then the MBET won't be able to ensure that + * the upload has completed before the texture is deleted. Use the WithData variant instead to + * avoid this issue. + */ + template + static sk_sp MakeWithoutData(GrDirectContext*, Args&&...); + + /** GrGpuFinishedProc or image/surface release proc. */ + static void ReleaseProc(void* context); + + ~ManagedBackendTexture(); + + /** + * The context to use with ReleaseProc. This adds a ref so it *must* be balanced by a call to + * ReleaseProc. + */ + void* releaseContext(); + + const GrBackendTexture& texture() { return fTexture; } + +private: + ManagedBackendTexture() = default; + ManagedBackendTexture(const ManagedBackendTexture&) = delete; + ManagedBackendTexture(ManagedBackendTexture&&) = delete; + + GrDirectContext* fDContext = nullptr; + GrBackendTexture fTexture; +}; + +template +inline sk_sp ManagedBackendTexture::MakeWithData(GrDirectContext* dContext, + Args&&... args) { + sk_sp mbet(new ManagedBackendTexture); + mbet->fDContext = dContext; + mbet->fTexture = dContext->createBackendTexture(std::forward(args)..., + ReleaseProc, + mbet->releaseContext()); + return mbet; +} + +template +inline sk_sp ManagedBackendTexture::MakeWithoutData( + GrDirectContext* dContext, + Args&&... args) { + sk_sp mbet(new ManagedBackendTexture); + mbet->fDContext = dContext; + mbet->fTexture = dContext->createBackendTexture(std::forward(args)...); + return mbet; +} + +} // namespace sk_gpu_test + +#endif