diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp index 2246fbb07d..ea0de3398e 100644 --- a/bench/nanobench.cpp +++ b/bench/nanobench.cpp @@ -424,6 +424,10 @@ static void create_config(const SkCommandLineConfig* config, SkTArray* c const auto sampleCount = gpuConfig->getSamples(); const auto colorType = gpuConfig->getColorType(); auto colorSpace = gpuConfig->getColorSpace(); + if (gpuConfig->getSurfType() != SkCommandLineConfigGpu::SurfType::kDefault) { + SkDebugf("This tool only supports the default surface type."); + return; + } GrContextFactory factory(grContextOpts); if (const GrContext* ctx = factory.get(ctxType, ctxOverrides)) { diff --git a/dm/DM.cpp b/dm/DM.cpp index 972c70d484..6f2025f4b9 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -884,17 +884,17 @@ static Sink* create_sink(const GrContextOptions& grCtxOptions, const SkCommandLi return nullptr; } if (gpuConfig->getTestThreading()) { - return new GPUThreadTestingSink(contextType, contextOverrides, - gpuConfig->getSamples(), gpuConfig->getUseDIText(), - gpuConfig->getColorType(), - gpuConfig->getAlphaType(), - sk_ref_sp(gpuConfig->getColorSpace()), - FLAGS_gpu_threading, grCtxOptions); + return new GPUThreadTestingSink( + contextType, contextOverrides, gpuConfig->getSurfType(), + gpuConfig->getSamples(), gpuConfig->getUseDIText(), + gpuConfig->getColorType(), gpuConfig->getAlphaType(), + sk_ref_sp(gpuConfig->getColorSpace()), FLAGS_gpu_threading, grCtxOptions); } else { - return new GPUSink(contextType, contextOverrides, gpuConfig->getSamples(), - gpuConfig->getUseDIText(), gpuConfig->getColorType(), - gpuConfig->getAlphaType(), sk_ref_sp(gpuConfig->getColorSpace()), - FLAGS_gpu_threading, grCtxOptions); + return new GPUSink(contextType, contextOverrides, gpuConfig->getSurfType(), + gpuConfig->getSamples(), gpuConfig->getUseDIText(), + gpuConfig->getColorType(), gpuConfig->getAlphaType(), + sk_ref_sp(gpuConfig->getColorSpace()), FLAGS_gpu_threading, + grCtxOptions); } } } diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h index a552d69f70..1ed00953c1 100644 --- a/dm/DMGpuSupport.h +++ b/dm/DMGpuSupport.h @@ -28,19 +28,6 @@ namespace DM { static const bool kGPUDisabled = false; -static inline sk_sp NewGpuSurface( - sk_gpu_test::GrContextFactory* grFactory, - sk_gpu_test::GrContextFactory::ContextType type, - sk_gpu_test::GrContextFactory::ContextOverrides overrides, - SkImageInfo info, - int samples, - bool useDIText) { - uint32_t flags = useDIText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0; - SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); - return SkSurface::MakeRenderTarget(grFactory->get(type, overrides), SkBudgeted::kNo, - info, samples, &props); -} - } // namespace DM #else// !SK_SUPPORT_GPU @@ -60,6 +47,11 @@ public: void dumpGpuStats(SkString*) const {} }; +class SkCommandLineConfigGpu { +public: + enum class SurfType; +}; + namespace sk_gpu_test { class GrContextFactory { public: @@ -93,15 +85,6 @@ namespace DM { static const bool kGPUDisabled = true; -static inline SkSurface* NewGpuSurface(sk_gpu_test::GrContextFactory*, - sk_gpu_test::GrContextFactory::ContextType, - sk_gpu_test::GrContextFactory::ContextOverrides, - SkImageInfo, - int, - bool) { - return nullptr; -} - } // namespace DM #endif//SK_SUPPORT_GPU diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index b84563701c..0fedd8e7ec 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -6,6 +6,9 @@ */ #include "DMSrcSink.h" +#include +#include +#include "../src/jumper/SkJumper.h" #include "Resources.h" #include "SkAndroidCodec.h" #include "SkAutoMalloc.h" @@ -44,17 +47,13 @@ #include "SkRandom.h" #include "SkRecordDraw.h" #include "SkRecorder.h" -#include "SkSurfaceCharacterization.h" #include "SkSVGCanvas.h" #include "SkStream.h" +#include "SkSurfaceCharacterization.h" #include "SkSwizzler.h" +#include "SkTLogic.h" #include "SkTaskGroup.h" #include "SkThreadedBMPDevice.h" -#include "SkTLogic.h" -#include -#include -#include "../src/jumper/SkJumper.h" - #if defined(SK_BUILD_FOR_WIN) #include "SkAutoCoInitialize.h" #include "SkHRESULT.h" @@ -72,7 +71,9 @@ #endif #if SK_SUPPORT_GPU +#include "GrBackendSurface.h" #include "GrContextPriv.h" +#include "GrGpu.h" #endif DEFINE_bool(multiPage, false, "For document-type backends, render the source" @@ -1603,6 +1604,7 @@ DEFINE_bool(gpuStats, false, "Append GPU stats to the log for each GPU task?"); GPUSink::GPUSink(GrContextFactory::ContextType ct, GrContextFactory::ContextOverrides overrides, + SkCommandLineConfigGpu::SurfType surfType, int samples, bool diText, SkColorType colorType, @@ -1612,6 +1614,7 @@ GPUSink::GPUSink(GrContextFactory::ContextType ct, const GrContextOptions& grCtxOptions) : fContextType(ct) , fContextOverrides(overrides) + , fSurfType(surfType) , fSampleCount(samples) , fUseDIText(diText) , fColorType(colorType) @@ -1636,16 +1639,45 @@ Error GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log, const SkISize size = src.size(); SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), fColorType, fAlphaType, fColorSpace); + sk_sp surface; #if SK_SUPPORT_GPU GrContext* context = factory.getContextInfo(fContextType, fContextOverrides).grContext(); const int maxDimension = context->caps()->maxTextureSize(); if (maxDimension < SkTMax(size.width(), size.height())) { return Error::Nonfatal("Src too large to create a texture.\n"); } + uint32_t flags = fUseDIText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 0; + SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); + GrBackendTexture backendTexture; + GrBackendRenderTarget backendRT; + switch (fSurfType) { + case SkCommandLineConfigGpu::SurfType::kDefault: + surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, fSampleCount, + &props); + break; + case SkCommandLineConfigGpu::SurfType::kBackendTexture: + backendTexture = context->contextPriv().getGpu()->createTestingOnlyBackendTexture( + nullptr, info.width(), info.height(), info.colorType(), true, GrMipMapped::kNo); + surface = SkSurface::MakeFromBackendTexture(context, backendTexture, + kTopLeft_GrSurfaceOrigin, fSampleCount, + info.refColorSpace(), &props); + break; + case SkCommandLineConfigGpu::SurfType::kBackendRenderTarget: + if (1 == fSampleCount) { + auto srgbEncoded = info.colorSpace() && info.colorSpace()->gammaCloseToSRGB() + ? GrSRGBEncoded::kYes + : GrSRGBEncoded::kNo; + auto colorType = SkColorTypeToGrColorType(info.colorType()); + backendRT = context->contextPriv().getGpu()->createTestingOnlyBackendRenderTarget( + info.width(), info.height(), colorType, srgbEncoded); + surface = SkSurface::MakeFromBackendRenderTarget(context, backendRT, + kBottomLeft_GrSurfaceOrigin, + info.refColorSpace(), &props); + } + break; + } #endif - auto surface( - NewGpuSurface(&factory, fContextType, fContextOverrides, info, fSampleCount, fUseDIText)); if (!surface) { return "Could not create a surface."; } @@ -1677,6 +1709,17 @@ Error GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log, } else if (FLAGS_releaseAndAbandonGpuContext) { factory.releaseResourcesAndAbandonContexts(); } +#if SK_SUPPORT_GPU + if (!context->contextPriv().abandoned()) { + surface.reset(); + if (backendTexture.isValid()) { + context->contextPriv().getGpu()->deleteTestingOnlyBackendTexture(&backendTexture); + } + if (backendRT.isValid()) { + context->contextPriv().getGpu()->deleteTestingOnlyBackendRenderTarget(backendRT); + } + } +#endif return ""; } @@ -1684,6 +1727,7 @@ Error GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log, GPUThreadTestingSink::GPUThreadTestingSink(GrContextFactory::ContextType ct, GrContextFactory::ContextOverrides overrides, + SkCommandLineConfigGpu::SurfType surfType, int samples, bool diText, SkColorType colorType, @@ -1691,8 +1735,8 @@ GPUThreadTestingSink::GPUThreadTestingSink(GrContextFactory::ContextType ct, sk_sp colorSpace, bool threaded, const GrContextOptions& grCtxOptions) - : INHERITED(ct, overrides, samples, diText, colorType, alphaType, std::move(colorSpace), - threaded, grCtxOptions) + : INHERITED(ct, overrides, surfType, samples, diText, colorType, alphaType, + std::move(colorSpace), threaded, grCtxOptions) #if SK_SUPPORT_GPU , fExecutor(SkExecutor::MakeFIFOThreadPool(FLAGS_gpuThreads)) { #else diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 227ef5341a..18e854bb0c 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -14,6 +14,7 @@ #include "SkBitmap.h" #include "SkBitmapRegionDecoder.h" #include "SkCanvas.h" +#include "SkCommonFlagsConfig.h" #include "SkData.h" #include "SkMultiPictureDocument.h" #include "SkPicture.h" @@ -339,7 +340,8 @@ public: class GPUSink : public Sink { public: GPUSink(sk_gpu_test::GrContextFactory::ContextType, - sk_gpu_test::GrContextFactory::ContextOverrides, int samples, bool diText, + sk_gpu_test::GrContextFactory::ContextOverrides, + SkCommandLineConfigGpu::SurfType surfType, int samples, bool diText, SkColorType colorType, SkAlphaType alphaType, sk_sp colorSpace, bool threaded, const GrContextOptions& grCtxOptions); @@ -359,6 +361,7 @@ public: private: sk_gpu_test::GrContextFactory::ContextType fContextType; sk_gpu_test::GrContextFactory::ContextOverrides fContextOverrides; + SkCommandLineConfigGpu::SurfType fSurfType; int fSampleCount; bool fUseDIText; SkColorType fColorType; @@ -371,7 +374,8 @@ private: class GPUThreadTestingSink : public GPUSink { public: GPUThreadTestingSink(sk_gpu_test::GrContextFactory::ContextType, - sk_gpu_test::GrContextFactory::ContextOverrides, int samples, bool diText, + sk_gpu_test::GrContextFactory::ContextOverrides, + SkCommandLineConfigGpu::SurfType surfType, int samples, bool diText, SkColorType colorType, SkAlphaType alphaType, sk_sp colorSpace, bool threaded, const GrContextOptions& grCtxOptions); diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 0c794e2eff..d63a38b758 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -448,12 +448,12 @@ public: Stats* stats() { return &fStats; } void dumpJSON(SkJSONWriter*) const; +#if GR_TEST_UTILS /** Creates a texture directly in the backend API without wrapping it in a GrTexture. This is only to be used for testing (particularly for testing the methods that import an externally created texture into Skia. Must be matched with a call to deleteTestingOnlyTexture(). */ GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, SkColorType, bool isRenderTarget, GrMipMapped); - /** Older version based on GrPixelConfig. Currently the preferred one above devolves to this. */ virtual GrBackendTexture createTestingOnlyBackendTexture( void* pixels, int w, int h, @@ -468,11 +468,23 @@ public: */ virtual void deleteTestingOnlyBackendTexture(GrBackendTexture*) = 0; + virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, + GrSRGBEncoded) = 0; + + virtual void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) = 0; + + // This is only to be used in GL-specific tests. + virtual const GrGLContext* glContextForTesting() const { return nullptr; } + + // This is only to be used by testing code + virtual void resetShaderCacheForTesting() const {} + /** * Flushes all work to the gpu and forces the GPU to wait until all the gpu work has completed. * This is for testing purposes only. */ virtual void testingOnly_flushGpuAndSync() = 0; +#endif // width and height may be larger than rt (if underlying API allows it). // Returns nullptr if compatible sb could not be created, otherwise the caller owns the ref on @@ -504,12 +516,6 @@ public: return this->onIsACopyNeededForTextureParams(proxy, params, copyParams, scaleAdjust); } - // This is only to be used in GL-specific tests. - virtual const GrGLContext* glContextForTesting() const { return nullptr; } - - // This is only to be used by testing code - virtual void resetShaderCacheForTesting() const {} - void handleDirtyContext() { if (fResetBits) { this->resetContext(); diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 82be0d1a97..7499e761c9 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -4344,6 +4344,7 @@ void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) { } } +#if GR_TEST_UTILS GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig config, bool /*isRT*/, GrMipMapped mipMapped) { @@ -4434,13 +4435,86 @@ void GrGLGpu::deleteTestingOnlyBackendTexture(GrBackendTexture* tex) { } } -void GrGLGpu::resetShaderCacheForTesting() const { - fProgramCache->abandon(); +GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h, + GrColorType colorType, + GrSRGBEncoded srgbEncoded) { + auto config = GrColorTypeToPixelConfig(colorType, srgbEncoded); + GrGLenum colorBufferFormat; + if (!this->glCaps().getRenderbufferFormat(config, &colorBufferFormat)) { + return {}; + } + int sFormatIdx = this->getCompatibleStencilIndex(config); + if (sFormatIdx < 0) { + return {}; + } + GrGLuint rbIDs[] = {0, 0}; + GL_CALL(GenRenderbuffers(2, rbIDs)); + if (!rbIDs[0] || !rbIDs[1]) { + if (!rbIDs[0]) { + GL_CALL(DeleteRenderbuffers(1, &rbIDs[0])); + } + if (!rbIDs[1]) { + GL_CALL(DeleteRenderbuffers(1, &rbIDs[1])); + } + return {}; + } + GrGLFramebufferInfo info; + info.fFBOID = 0; + GL_CALL(GenFramebuffers(1, &info.fFBOID)); + if (!info.fFBOID) { + GL_CALL(DeleteRenderbuffers(2, rbIDs)); + return GrBackendRenderTarget(); + } + + this->invalidateBoundRenderTarget(); + + GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID)); + GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbIDs[0])); + GL_ALLOC_CALL(this->glInterface(), + RenderbufferStorage(GR_GL_RENDERBUFFER, colorBufferFormat, w, h)); + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_RENDERBUFFER, + rbIDs[0])); + GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbIDs[1])); + auto stencilBufferFormat = this->glCaps().stencilFormats()[sFormatIdx].fInternalFormat; + GL_ALLOC_CALL(this->glInterface(), + RenderbufferStorage(GR_GL_RENDERBUFFER, stencilBufferFormat, w, h)); + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT, GR_GL_RENDERBUFFER, + rbIDs[1])); + if (this->glCaps().stencilFormats()[sFormatIdx].fPacked) { + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT, + GR_GL_RENDERBUFFER, rbIDs[1])); + } + + // We don't want to have to recover the renderbuffer IDs later to delete them. OpenGL has this + // rule that if a renderbuffer is deleted and a FBO other than the current FBO has the RB + // attached then deletion is delayed. So we unbind the FBO here and delete the renderbuffers. + GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); + GL_CALL(DeleteRenderbuffers(2, rbIDs)); + + GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID)); + GrGLenum status; + GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); + if (GR_GL_FRAMEBUFFER_COMPLETE != status) { + GL_CALL(DeleteFramebuffers(1, &info.fFBOID)); + return {}; + } + auto stencilBits = SkToInt(this->glCaps().stencilFormats()[sFormatIdx].fStencilBits); + return {w, h, 1, stencilBits, config, info}; +} + +void GrGLGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget& backendRT) { + SkASSERT(kOpenGL_GrBackend == backendRT.backend()); + if (auto info = backendRT.getGLFramebufferInfo()) { + if (info->fFBOID) { + GL_CALL(DeleteFramebuffers(1, &info->fFBOID)); + } + } } void GrGLGpu::testingOnly_flushGpuAndSync() { GL_CALL(Finish()); } +#endif /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 3a67958d5f..fa3d9e09c7 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -128,10 +128,6 @@ public: void clearStencilClip(const GrFixedClip&, bool insideStencilMask, GrRenderTarget*, GrSurfaceOrigin); - const GrGLContext* glContextForTesting() const override { - return &this->glContext(); - } - void clearStencil(GrRenderTarget*, int clearValue) override; GrGpuRTCommandBuffer* createCommandBuffer( @@ -148,7 +144,7 @@ public: GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, int width, int height) override; - +#if GR_TEST_UTILS GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig config, bool isRenderTarget, @@ -156,9 +152,17 @@ public: bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; void deleteTestingOnlyBackendTexture(GrBackendTexture*) override; - void resetShaderCacheForTesting() const override; + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, + GrSRGBEncoded) override; + + void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; + + const GrGLContext* glContextForTesting() const override { return &this->glContext(); } + + void resetShaderCacheForTesting() const override { fProgramCache->abandon(); } void testingOnly_flushGpuAndSync() override; +#endif GrFence SK_WARN_UNUSED_RESULT insertFence() override; bool waitFence(GrFence, uint64_t timeout) override; diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp index e31a775730..50b19f15e9 100644 --- a/src/gpu/mock/GrMockGpu.cpp +++ b/src/gpu/mock/GrMockGpu.cpp @@ -107,6 +107,7 @@ GrStencilAttachment* GrMockGpu::createStencilAttachmentForRenderTarget(const GrR return new GrMockStencilAttachment(this, width, height, kBits, rt->numColorSamples()); } +#if GR_TEST_UTILS GrBackendTexture GrMockGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig config, bool isRT, GrMipMapped) { @@ -136,3 +137,11 @@ void GrMockGpu::deleteTestingOnlyBackendTexture(GrBackendTexture* tex) { fOutstandingTestingOnlyTextureIDs.remove(info->fID); } } + +GrBackendRenderTarget GrMockGpu::createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, + GrSRGBEncoded) { + return {}; +} + +void GrMockGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {} +#endif diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index 00b19ac82e..b58b9ff6d7 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -119,12 +119,18 @@ private: int height) override; void clearStencil(GrRenderTarget*, int clearValue) override {} +#if GR_TEST_UTILS GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig, bool isRT, GrMipMapped) override; bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; void deleteTestingOnlyBackendTexture(GrBackendTexture*) override; + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, + GrSRGBEncoded) override; + void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; + void testingOnly_flushGpuAndSync() override {} +#endif static int NextInternalTextureID(); static int NextExternalTextureID(); diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h index 9907e95d29..38b4e6303c 100644 --- a/src/gpu/mtl/GrMtlGpu.h +++ b/src/gpu/mtl/GrMtlGpu.h @@ -137,6 +137,7 @@ private: void clearStencil(GrRenderTarget* target, int clearValue) override {} +#if GR_TEST_UTILS GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig config, bool isRT, GrMipMapped) override { @@ -145,7 +146,14 @@ private: bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override { return false; } void deleteTestingOnlyBackendTexture(GrBackendTexture*) override {} + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, + GrSRGBEncoded) override { + return {}; + } + void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override {} + void testingOnly_flushGpuAndSync() override {} +#endif sk_sp fMtlCaps; diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index b6268a7a65..b674185a00 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -1181,6 +1181,7 @@ bool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc, size return true; } +#if GR_TEST_UTILS GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h, GrPixelConfig config, bool isRenderTarget, @@ -1509,9 +1510,18 @@ void GrVkGpu::deleteTestingOnlyBackendTexture(GrBackendTexture* tex) { } } +GrBackendRenderTarget GrVkGpu::createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, + GrSRGBEncoded) { + return GrBackendRenderTarget(); +} + +void GrVkGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {} + + void GrVkGpu::testingOnly_flushGpuAndSync() { this->submitCommandBuffer(kForce_SyncQueue); } +#endif //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index 4d1685eb29..81517af86e 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -69,6 +69,7 @@ public: void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {} +#if GR_TEST_UTILS GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig config, bool isRenderTarget, @@ -76,7 +77,12 @@ public: bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; void deleteTestingOnlyBackendTexture(GrBackendTexture*) override; + GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, + GrSRGBEncoded) override; + void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; + void testingOnly_flushGpuAndSync() override; +#endif GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*, int width, diff --git a/tests/TestConfigParsing.cpp b/tests/TestConfigParsing.cpp index 6ff1fd830f..fae8cd8a14 100644 --- a/tests/TestConfigParsing.cpp +++ b/tests/TestConfigParsing.cpp @@ -41,13 +41,15 @@ DEF_TEST(ParseConfigs_Gpu, reporter) { REPORTER_ASSERT(reporter, configs[0]->getViaParts().count() == 0); #if SK_SUPPORT_GPU REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()); - REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getContextType() - == GrContextFactory::kGL_ContextType); + REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getContextType() == + GrContextFactory::kGL_ContextType); REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getUseNVPR() == false); REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getUseDIText() == false); REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getSamples() == 1); REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getColorType() == kRGBA_8888_SkColorType); REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getColorSpace() == nullptr); + REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getSurfType() == + SkCommandLineConfigGpu::SurfType::kDefault); #endif } @@ -112,6 +114,7 @@ DEF_TEST(ParseConfigs_DefaultConfigs, reporter) { "gl565", "gltestthreading", "gl1010102", + "glesbert" }); SkCommandLineConfigArray configs; @@ -204,6 +207,9 @@ DEF_TEST(ParseConfigs_DefaultConfigs, reporter) { REPORTER_ASSERT(reporter, configs[37]->asConfigGpu()); REPORTER_ASSERT(reporter, configs[37]->asConfigGpu()->getColorType() == kRGBA_1010102_SkColorType); + REPORTER_ASSERT(reporter, configs[38]->asConfigGpu()); + REPORTER_ASSERT(reporter, configs[38]->asConfigGpu()->getSurfType() == + SkCommandLineConfigGpu::SurfType::kBackendRenderTarget); #endif } @@ -218,7 +224,7 @@ DEF_TEST(ParseConfigs_ExtendedGpuConfigsCorrect, reporter) { "gpu[api=gl]", "gpu[api=vulkan]", "gpu[api=metal]", - "gpu[api=mock]", + "gpu[api=mock,surf=betex]", }); SkCommandLineConfigArray configs; @@ -268,6 +274,8 @@ DEF_TEST(ParseConfigs_ExtendedGpuConfigsCorrect, reporter) { #endif REPORTER_ASSERT(reporter, configs[9]->asConfigGpu()->getContextType() == GrContextFactory::kMock_ContextType); + REPORTER_ASSERT(reporter, configs[9]->asConfigGpu()->getSurfType() == + SkCommandLineConfigGpu::SurfType::kBackendTexture); #endif } diff --git a/tools/flags/SkCommonFlagsConfig.cpp b/tools/flags/SkCommonFlagsConfig.cpp index 85495c68d8..bb53c2d64e 100644 --- a/tools/flags/SkCommonFlagsConfig.cpp +++ b/tools/flags/SkCommonFlagsConfig.cpp @@ -34,7 +34,7 @@ static const struct { const char* predefinedConfig; const char* backend; const char* options; -} gPredefinedConfigs[] ={ +} gPredefinedConfigs[] = { #if SK_SUPPORT_GPU { "gl", "gpu", "api=gl" }, { "gles", "gpu", "api=gles" }, @@ -44,6 +44,10 @@ static const struct { { "glnvpr4", "gpu", "api=gl,nvpr=true,samples=4" }, { "glnvpr8" , "gpu", "api=gl,nvpr=true,samples=8" }, { "glesnvpr4", "gpu", "api=gles,nvpr=true,samples=4" }, + { "glbetex", "gpu", "api=gl,surf=betex" }, + { "glesbetex", "gpu", "api=gles,surf=betex" }, + { "glbert", "gpu", "api=gl,surf=bert" }, + { "glesbert", "gpu", "api=gles,surf=bert" }, { "gl4444", "gpu", "api=gl,color=4444" }, { "gl565", "gpu", "api=gl,color=565" }, { "glf16", "gpu", "api=gl,color=f16" }, @@ -162,6 +166,12 @@ static const char configExtendedHelp[] = "\t Allow the use of stencil buffers.\n" "\ttestThreading\ttype: bool\tdefault: false.\n" "\t Run config with and without worker threads, check that results match.\n" + "\tsurf\ttype: string\tdefault: default.\n" + "\t Controls the type of backing store for SkSurfaces.\n" + "\t Options:\n" + "\t\tdefault\t\t\tA renderable texture created in Skia's resource cache.\n" + "\t\tbetex\t\t\tA wrapped backend texture.\n" + "\t\tbert\t\t\tA wrapped backend render target\n" "\n" "Predefined configs:\n\n" // Help text for pre-defined configs is auto-generated from gPredefinedConfigs @@ -272,6 +282,7 @@ static bool parse_option_gpu_api(const SkString& value, #endif return false; } + static bool parse_option_gpu_color(const SkString& value, SkColorType* outColorType, SkAlphaType* alphaType, @@ -351,6 +362,23 @@ static bool parse_option_gpu_color(const SkString& value, } return false; } + +static bool parse_option_gpu_surf_type(const SkString& value, + SkCommandLineConfigGpu::SurfType* surfType) { + if (value.equals("default")) { + *surfType = SkCommandLineConfigGpu::SurfType::kDefault; + return true; + } + if (value.equals("betex")) { + *surfType = SkCommandLineConfigGpu::SurfType::kBackendTexture; + return true; + } + if (value.equals("bert")) { + *surfType = SkCommandLineConfigGpu::SurfType::kBackendRenderTarget; + return true; + } + return false; +} #endif // Extended options take form --config item[key1=value1,key2=value2,...] @@ -402,6 +430,16 @@ public: } return parse_option_gpu_api(*optionValue, outContextType); } + + bool get_option_gpu_surf_type(const char* optionKey, + SkCommandLineConfigGpu::SurfType* outSurfType, + bool optional = true) const { + SkString* optionValue = fOptionsMap.find(SkString(optionKey)); + if (optionValue == nullptr) { + return optional; + } + return parse_option_gpu_surf_type(*optionValue, outSurfType); + } #endif bool get_option_int(const char* optionKey, int* outInt, bool optional = true) const { @@ -426,9 +464,10 @@ private: #if SK_SUPPORT_GPU SkCommandLineConfigGpu::SkCommandLineConfigGpu( - const SkString& tag, const SkTArray& viaParts, ContextType contextType, bool useNVPR, - bool useDIText, int samples, SkColorType colorType, SkAlphaType alphaType, - sk_sp colorSpace, bool useStencilBuffers, bool testThreading) + const SkString& tag, const SkTArray& viaParts, ContextType contextType, + bool useNVPR, bool useDIText, int samples, SkColorType colorType, SkAlphaType alphaType, + sk_sp colorSpace, bool useStencilBuffers, bool testThreading, + SurfType surfType) : SkCommandLineConfig(tag, SkString("gpu"), viaParts) , fContextType(contextType) , fContextOverrides(ContextOverrides::kNone) @@ -437,7 +476,8 @@ SkCommandLineConfigGpu::SkCommandLineConfigGpu( , fColorType(colorType) , fAlphaType(alphaType) , fColorSpace(std::move(colorSpace)) - , fTestThreading(testThreading) { + , fTestThreading(testThreading) + , fSurfType(surfType) { if (useNVPR) { fContextOverrides |= ContextOverrides::kRequireNVPRSupport; } else { @@ -474,6 +514,7 @@ SkCommandLineConfigGpu* parse_command_line_config_gpu(const SkString& tag, sk_sp colorSpace = nullptr; bool useStencils = true; bool testThreading = false; + SkCommandLineConfigGpu::SurfType surfType = SkCommandLineConfigGpu::SurfType::kDefault; bool parseSucceeded = false; ExtendedOptions extendedOptions(options, &parseSucceeded); @@ -488,15 +529,17 @@ SkCommandLineConfigGpu* parse_command_line_config_gpu(const SkString& tag, extendedOptions.get_option_int("samples", &samples) && extendedOptions.get_option_gpu_color("color", &colorType, &alphaType, &colorSpace) && extendedOptions.get_option_bool("stencils", &useStencils) && - extendedOptions.get_option_bool("testThreading", &testThreading); + extendedOptions.get_option_bool("testThreading", &testThreading) && + extendedOptions.get_option_bool("testThreading", &testThreading) && + extendedOptions.get_option_gpu_surf_type("surf", &surfType); if (!validOptions) { return nullptr; } - return new SkCommandLineConfigGpu(tag, vias, contextType, useNVPR, useDIText, - samples, colorType, alphaType, colorSpace, useStencils, - testThreading); + return new SkCommandLineConfigGpu(tag, vias, contextType, useNVPR, useDIText, samples, + colorType, alphaType, colorSpace, useStencils, testThreading, + surfType); } #endif diff --git a/tools/flags/SkCommonFlagsConfig.h b/tools/flags/SkCommonFlagsConfig.h index d88edf1c3b..3f1056d113 100644 --- a/tools/flags/SkCommonFlagsConfig.h +++ b/tools/flags/SkCommonFlagsConfig.h @@ -52,14 +52,21 @@ class SkCommandLineConfig { // * backends that represent a shorthand of above (such as "glmsaa16" representing // "gpu(api=gl,samples=16)") class SkCommandLineConfigGpu : public SkCommandLineConfig { - public: +public: + enum class SurfType { + kDefault, + kBackendTexture, + kBackendRenderTarget + }; typedef sk_gpu_test::GrContextFactory::ContextType ContextType; typedef sk_gpu_test::GrContextFactory::ContextOverrides ContextOverrides; + SkCommandLineConfigGpu(const SkString& tag, const SkTArray& viaParts, - ContextType contextType, bool useNVPR, bool useDIText, - int samples, SkColorType colorType, SkAlphaType alphaType, + ContextType contextType, bool useNVPR, bool useDIText, int samples, + SkColorType colorType, SkAlphaType alphaType, sk_sp colorSpace, bool useStencilBuffers, - bool testThreading); + bool testThreading, SurfType); + const SkCommandLineConfigGpu* asConfigGpu() const override { return this; } ContextType getContextType() const { return fContextType; } ContextOverrides getContextOverrides() const { return fContextOverrides; } @@ -74,8 +81,9 @@ class SkCommandLineConfigGpu : public SkCommandLineConfig { SkAlphaType getAlphaType() const { return fAlphaType; } SkColorSpace* getColorSpace() const { return fColorSpace.get(); } bool getTestThreading() const { return fTestThreading; } + SurfType getSurfType() const { return fSurfType; } - private: +private: ContextType fContextType; ContextOverrides fContextOverrides; bool fUseDIText; @@ -84,6 +92,7 @@ class SkCommandLineConfigGpu : public SkCommandLineConfig { SkAlphaType fAlphaType; sk_sp fColorSpace; bool fTestThreading; + SurfType fSurfType; }; #endif diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp index 562c48165f..92a642af1c 100644 --- a/tools/skpbench/skpbench.cpp +++ b/tools/skpbench/skpbench.cpp @@ -274,6 +274,11 @@ int main(int argc, char** argv) { SkScalarCeilToInt(skp->cullRect().height()), width, height); } + if (config->getSurfType() != SkCommandLineConfigGpu::SurfType::kDefault) { + exitf(ExitErr::kUnavailable, "This tool only supports the default surface type. (%s)", + config->getTag().c_str()); + } + // Create a context. GrContextOptions ctxOptions; SetCtxOptionsFromCommonFlags(&ctxOptions);