From f9635999a4aa8810d04e8ef04594a9fbcc061e3d Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Wed, 10 Aug 2016 11:09:07 -0700 Subject: [PATCH] Add flag for window rectangles to GrRenderTarget Adds a flag to GrRenderTarget that indicates whether it can be used with window rectangles. Also attempts to clean up some of the mixed samples API. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2225303002 Review-Url: https://codereview.chromium.org/2225303002 --- include/gpu/GrDrawContext.h | 2 +- include/gpu/GrRenderTarget.h | 81 ++++++----------------- include/gpu/GrTypes.h | 21 ++++++ include/private/GrInstancedPipelineInfo.h | 2 +- include/private/GrRenderTargetProxy.h | 72 +++++++------------- src/gpu/GrRenderTarget.cpp | 20 +++--- src/gpu/GrRenderTargetPriv.h | 5 +- src/gpu/GrRenderTargetProxy.cpp | 32 +++++++-- src/gpu/gl/GrGLGpu.cpp | 10 +-- src/gpu/gl/GrGLRenderTarget.cpp | 17 ++++- src/gpu/gl/GrGLRenderTarget.h | 13 ++-- src/gpu/vk/GrVkRenderTarget.cpp | 8 +-- tests/ProxyTest.cpp | 36 ++++++++-- tools/gpu/GrTest.cpp | 7 ++ 14 files changed, 180 insertions(+), 146 deletions(-) diff --git a/include/gpu/GrDrawContext.h b/include/gpu/GrDrawContext.h index 6b582a6a63..def541d9a9 100644 --- a/include/gpu/GrDrawContext.h +++ b/include/gpu/GrDrawContext.h @@ -263,7 +263,7 @@ public: return fRenderTarget->isStencilBufferMultisampled(); } bool isUnifiedMultisampled() const { return fRenderTarget->isUnifiedMultisampled(); } - bool hasMixedSamples() const { return fRenderTarget->hasMixedSamples(); } + bool hasMixedSamples() const { return fRenderTarget->isMixedSampled(); } bool mustUseHWAA(const GrPaint& paint) const { return paint.isAntiAlias() && fRenderTarget->isUnifiedMultisampled(); diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h index 77b04d24d3..1f87787d45 100644 --- a/include/gpu/GrRenderTarget.h +++ b/include/gpu/GrRenderTarget.h @@ -30,66 +30,28 @@ public: const GrRenderTarget* asRenderTarget() const override { return this; } // GrRenderTarget - /** - * On some hardware it is possible for a render target to have multisampling - * only in certain buffers. - * Enforce only two legal sample configs. - * kUnified_SampleConfig signifies multisampling in both color and stencil - * buffers and is available across all hardware. - * kStencil_SampleConfig means multisampling is present in stencil buffer - * only; this config requires hardware support of - * NV_framebuffer_mixed_samples. - */ - enum SampleConfig { - kUnified_SampleConfig = 0, - kStencil_SampleConfig = 1 - }; - - /** - * @return true if the surface is multisampled in all buffers, - * false otherwise - */ - bool isUnifiedMultisampled() const { - if (fSampleConfig != kUnified_SampleConfig) { - return false; - } - return 0 != fDesc.fSampleCnt; - } + bool isStencilBufferMultisampled() const { return fDesc.fSampleCnt > 0; } /** - * @return true if the surface is multisampled in the stencil buffer, - * false otherwise + * For our purposes, "Mixed Sampled" means the stencil buffer is multisampled but the color + * buffer is not. */ - bool isStencilBufferMultisampled() const { - return 0 != fDesc.fSampleCnt; - } + bool isMixedSampled() const { return fFlags & Flags::kMixedSampled; } /** - * @return the number of color samples-per-pixel, or zero if non-MSAA or - * multisampled in the stencil buffer only. + * "Unified Sampled" means the stencil and color buffers are both multisampled. */ - int numColorSamples() const { - if (fSampleConfig == kUnified_SampleConfig) { - return fDesc.fSampleCnt; - } - return 0; - } + bool isUnifiedMultisampled() const { return fDesc.fSampleCnt > 0 && !this->isMixedSampled(); } /** - * @return the number of stencil samples-per-pixel, or zero if non-MSAA. + * Returns the number of samples/pixel in the stencil buffer (Zero if non-MSAA). */ - int numStencilSamples() const { - return fDesc.fSampleCnt; - } + int numStencilSamples() const { return fDesc.fSampleCnt; } /** - * @return true if the surface is mixed sampled, false otherwise. + * Returns the number of samples/pixel in the color buffer (Zero if non-MSAA or mixed sampled). */ - bool hasMixedSamples() const { - SkASSERT(kStencil_SampleConfig != fSampleConfig || - this->isStencilBufferMultisampled()); - return kStencil_SampleConfig == fSampleConfig; - } + int numColorSamples() const { return this->isMixedSampled() ? 0 : fDesc.fSampleCnt; } /** * Call to indicate the multisample contents were modified such that the @@ -156,19 +118,17 @@ public: void setLastDrawTarget(GrDrawTarget* dt); GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; } - static SampleConfig ComputeSampleConfig(const GrCaps& caps, int sampleCnt); - protected: - GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, - SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr) - : INHERITED(gpu, desc) - , fStencilAttachment(stencil) - , fMultisampleSpecsID(0) - , fSampleConfig(sampleConfig) - , fLastDrawTarget(nullptr) { - fResolveRect.setLargestInverted(); - } + enum class Flags { + kNone = 0, + kMixedSampled = 1 << 0, + kWindowRectsSupport = 1 << 1 + }; + + GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags); + GrRenderTarget(GrGpu*, const GrSurfaceDesc&, Flags = Flags::kNone, + GrStencilAttachment* = nullptr); ~GrRenderTarget() override; // override of GrResource @@ -186,7 +146,7 @@ private: GrStencilAttachment* fStencilAttachment; uint8_t fMultisampleSpecsID; - SampleConfig fSampleConfig; + Flags fFlags; SkIRect fResolveRect; @@ -201,5 +161,6 @@ private: typedef GrSurface INHERITED; }; +GR_MAKE_BITFIELD_CLASS_OPS(GrRenderTarget::Flags); #endif diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index a0f13aa6fe..7bc949d73c 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -49,6 +49,27 @@ \ template \ friend X operator & (X a, T b); \ + +/** + * Defines bitwise operators that make it possible to use an enum class as a + * very basic bitfield. + */ +#define GR_MAKE_BITFIELD_CLASS_OPS(X) \ + inline X operator | (X a, X b) { \ + return (X) ((int)a | (int)b); \ + } \ + inline X& operator |= (X& a, X b) { \ + return (a = a | b); \ + } \ + inline bool operator & (X a, X b) { \ + return SkToBool((int)a & (int)b); \ + } + +#define GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(X) \ + friend X operator | (X a, X b); \ + friend X& operator |= (X& a, X b); \ + friend bool operator & (X a, X b); + //////////////////////////////////////////////////////////////////////////////// // compile time versions of min/max diff --git a/include/private/GrInstancedPipelineInfo.h b/include/private/GrInstancedPipelineInfo.h index f12b89fc6b..7e6482da90 100644 --- a/include/private/GrInstancedPipelineInfo.h +++ b/include/private/GrInstancedPipelineInfo.h @@ -17,7 +17,7 @@ struct GrInstancedPipelineInfo { GrInstancedPipelineInfo(const GrRenderTarget* rt) : fIsMultisampled(rt->isStencilBufferMultisampled()), - fIsMixedSampled(rt->hasMixedSamples()), + fIsMixedSampled(rt->isMixedSampled()), fIsRenderingToFloat(GrPixelConfigIsFloatingPoint(rt->desc().fConfig)), fColorDisabled(false), fDrawingShapeToStencil(false), diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h index 287aa017f0..e4bc70f212 100644 --- a/include/private/GrRenderTargetProxy.h +++ b/include/private/GrRenderTargetProxy.h @@ -9,6 +9,7 @@ #define GrRenderTargetProxy_DEFINED #include "GrRenderTarget.h" +#include "GrRenderTargetPriv.h" #include "GrSurfaceProxy.h" #include "GrTypes.h" @@ -25,7 +26,7 @@ public: */ static sk_sp Make(const GrCaps&, const GrSurfaceDesc&, SkBackingFit, SkBudgeted); - static sk_sp Make(sk_sp rt); + static sk_sp Make(const GrCaps&, sk_sp); ~GrRenderTargetProxy() override; @@ -36,78 +37,51 @@ public: // Actually instantiate the backing rendertarget, if necessary. GrRenderTarget* instantiate(GrTextureProvider* texProvider); - /** - * @return true if the surface is multisampled in all buffers, - * false otherwise - */ - bool isUnifiedMultisampled() const { - if (fSampleConfig != GrRenderTarget::kUnified_SampleConfig) { - return false; - } - return 0 != fDesc.fSampleCnt; - } + bool isStencilBufferMultisampled() const { return fDesc.fSampleCnt > 0; } /** - * @return true if the surface is multisampled in the stencil buffer, - * false otherwise + * For our purposes, "Mixed Sampled" means the stencil buffer is multisampled but the color + * buffer is not. */ - bool isStencilBufferMultisampled() const { - return 0 != fDesc.fSampleCnt; - } + bool isMixedSampled() const { return fFlags & GrRenderTargetPriv::Flags::kMixedSampled; } /** - * @return the number of color samples-per-pixel, or zero if non-MSAA or - * multisampled in the stencil buffer only. + * "Unified Sampled" means the stencil and color buffers are both multisampled. */ - int numColorSamples() const { - if (fSampleConfig == GrRenderTarget::kUnified_SampleConfig) { - return fDesc.fSampleCnt; - } - return 0; - } + bool isUnifiedMultisampled() const { return fDesc.fSampleCnt > 0 && !this->isMixedSampled(); } /** - * @return the number of stencil samples-per-pixel, or zero if non-MSAA. + * Returns the number of samples/pixel in the stencil buffer (Zero if non-MSAA). */ - int numStencilSamples() const { - return fDesc.fSampleCnt; - } + int numStencilSamples() const { return fDesc.fSampleCnt; } /** - * @return true if the surface is mixed sampled, false otherwise. + * Returns the number of samples/pixel in the color buffer (Zero if non-MSAA or mixed sampled). */ - bool hasMixedSamples() const { - SkASSERT(GrRenderTarget::kStencil_SampleConfig != fSampleConfig || - this->isStencilBufferMultisampled()); - return GrRenderTarget::kStencil_SampleConfig == fSampleConfig; - } + int numColorSamples() const { return this->isMixedSampled() ? 0 : fDesc.fSampleCnt; } void setLastDrawTarget(GrDrawTarget* dt); GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; } + GrRenderTargetPriv::Flags testingOnly_getFlags() const; + private: - // TODO: we can probably munge the 'desc' in both the wrapped and deferred - // cases to make the sampleConfig/numSamples stuff more rational. - GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc, - SkBackingFit fit, SkBudgeted budgeted) - : INHERITED(desc, fit, budgeted) - , fTarget(nullptr) - , fSampleConfig(GrRenderTarget::ComputeSampleConfig(caps, desc.fSampleCnt)) - , fLastDrawTarget(nullptr) { - } + // Deferred version + GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, SkBackingFit, SkBudgeted); // Wrapped version - GrRenderTargetProxy(sk_sp rt); + GrRenderTargetProxy(const GrCaps&, sk_sp rt); // For wrapped render targets we store it here. // For deferred proxies we will fill this in when we need to instantiate the deferred resource - sk_sp fTarget; + sk_sp fTarget; - // The sample config doesn't usually get computed until the render target is instantiated but - // the render target proxy may need to answer queries about it before then. For this reason - // we precompute it in the deferred case. In the wrapped case we just copy the wrapped + // These don't usually get computed until the render target is instantiated, but the render + // target proxy may need to answer queries about it before then. And since in the deferred case + // we know the newly created render target will be internal, we are able to precompute what the + // flags will ultimately end up being. In the wrapped case we just copy the wrapped // rendertarget's info here. - GrRenderTarget::SampleConfig fSampleConfig; + GrRenderTargetPriv::Flags fFlags; // The last drawTarget that wrote to or is currently going to write to this renderTarget // The drawTarget can be closed (e.g., no draw context is currently bound diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp index a0700a095f..90f94b324b 100644 --- a/src/gpu/GrRenderTarget.cpp +++ b/src/gpu/GrRenderTarget.cpp @@ -16,6 +16,18 @@ #include "GrRenderTargetPriv.h" #include "GrStencilAttachment.h" +GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, Flags flags, + GrStencilAttachment* stencil) + : INHERITED(gpu, desc) + , fStencilAttachment(stencil) + , fMultisampleSpecsID(0) + , fFlags(flags) + , fLastDrawTarget(nullptr) { + SkASSERT(!(fFlags & Flags::kMixedSampled) || fDesc.fSampleCnt > 0); + SkASSERT(!(fFlags & Flags::kWindowRectsSupport) || gpu->caps()->maxWindowRectangles() > 0); + fResolveRect.setLargestInverted(); +} + GrRenderTarget::~GrRenderTarget() { if (fLastDrawTarget) { fLastDrawTarget->clearRT(); @@ -115,11 +127,3 @@ const GrGpu::MultisampleSpecs& GrRenderTargetPriv::getMultisampleSpecs(const GrStencilSettings& stencil) const { return fRenderTarget->getGpu()->getMultisampleSpecs(fRenderTarget, stencil); } - -GrRenderTarget::SampleConfig GrRenderTarget::ComputeSampleConfig(const GrCaps& caps, - int sampleCnt) { - return (caps.usesMixedSamples() && sampleCnt > 0) - ? GrRenderTarget::kStencil_SampleConfig - : GrRenderTarget::kUnified_SampleConfig; -} - diff --git a/src/gpu/GrRenderTargetPriv.h b/src/gpu/GrRenderTargetPriv.h index db66bc3316..2c828ec59a 100644 --- a/src/gpu/GrRenderTargetPriv.h +++ b/src/gpu/GrRenderTargetPriv.h @@ -35,7 +35,10 @@ public: const GrGpu::MultisampleSpecs& getMultisampleSpecs(const GrStencilSettings& stencil) const; uint8_t& accessMultisampleSpecsID() { return fRenderTarget->fMultisampleSpecsID; } - GrRenderTarget::SampleConfig sampleConfig() const { return fRenderTarget->fSampleConfig; } + typedef GrRenderTarget::Flags Flags; + + Flags flags() const { return fRenderTarget->fFlags; } + bool supportsWindowRectangles() const { return this->flags() & Flags::kWindowRectsSupport; } private: explicit GrRenderTargetPriv(GrRenderTarget* renderTarget) : fRenderTarget(renderTarget) {} diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index 6c422c09cd..3d6587fefe 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -7,14 +7,34 @@ #include "GrRenderTargetProxy.h" +#include "GrCaps.h" #include "GrDrawTarget.h" #include "GrGpuResourcePriv.h" -#include "GrRenderTargetPriv.h" -GrRenderTargetProxy::GrRenderTargetProxy(sk_sp rt) +// Deferred version +// TODO: we can probably munge the 'desc' in both the wrapped and deferred +// cases to make the sampleConfig/numSamples stuff more rational. +GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc, + SkBackingFit fit, SkBudgeted budgeted) + : INHERITED(desc, fit, budgeted) + , fTarget(nullptr) + , fFlags(GrRenderTargetPriv::Flags::kNone) + , fLastDrawTarget(nullptr) { + // Since we know the newly created render target will be internal, we are able to precompute + // what the flags will ultimately end up being. + if (caps.usesMixedSamples() && fDesc.fSampleCnt > 0) { + fFlags |= GrRenderTargetPriv::Flags::kMixedSampled; + } + if (caps.maxWindowRectangles() > 0) { + fFlags |= GrRenderTargetPriv::Flags::kWindowRectsSupport; + } +} + +// Wrapped version +GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, sk_sp rt) : INHERITED(rt->desc(), SkBackingFit::kExact, rt->resourcePriv().isBudgeted()) , fTarget(std::move(rt)) - , fSampleConfig(fTarget->renderTargetPriv().sampleConfig()) + , fFlags(fTarget->renderTargetPriv().flags()) , fLastDrawTarget(nullptr) { } @@ -47,7 +67,7 @@ GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider) fTarget = sk_ref_sp(tex->asRenderTarget()); // Check that our a priori computation matched the ultimate reality - SkASSERT(fSampleConfig == fTarget->renderTargetPriv().sampleConfig()); + SkASSERT(fFlags == fTarget->renderTargetPriv().flags()); return fTarget.get(); } @@ -71,7 +91,7 @@ sk_sp GrRenderTargetProxy::Make(const GrCaps& caps, return sk_sp(new GrRenderTargetProxy(caps, desc, fit, budgeted)); } -sk_sp GrRenderTargetProxy::Make(sk_sp rt) { - return sk_sp(new GrRenderTargetProxy(rt)); +sk_sp GrRenderTargetProxy::Make(const GrCaps& caps, sk_sp rt) { + return sk_sp(new GrRenderTargetProxy(caps, rt)); } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index c91a0f46fa..1300bb7a03 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -722,7 +722,7 @@ GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe } else { idDesc.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed; } - idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig; + idDesc.fIsMixedSampled = false; GrSurfaceDesc desc; desc.fConfig = wrapDesc.fConfig; @@ -1505,7 +1505,7 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc, idDesc->fTexFBOID = 0; SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) == this->caps()->usesMixedSamples()); - idDesc->fSampleConfig = GrRenderTarget::ComputeSampleConfig(*this->caps(), desc.fSampleCnt); + idDesc->fIsMixedSampled = desc.fSampleCnt > 0 && this->caps()->usesMixedSamples(); GrGLenum status; @@ -2971,7 +2971,7 @@ void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabl } if (0 != this->caps()->maxRasterSamples()) { - if (useHWAA && rt->hasMixedSamples() && !stencilEnabled) { + if (useHWAA && rt->isMixedSampled() && !stencilEnabled) { // Since stencil is disabled and we want more samples than are in the color buffer, we // need to tell the rasterizer explicitly how many to run. if (kYes_TriState != fHWRasterMultisampleEnabled) { @@ -2990,7 +2990,7 @@ void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabl } } } else { - SkASSERT(!useHWAA || !rt->hasMixedSamples() || stencilEnabled); + SkASSERT(!useHWAA || !rt->isMixedSampled() || stencilEnabled); } } @@ -4440,7 +4440,7 @@ bool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) { void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings& stencil, int* effectiveSampleCnt, SamplePattern* samplePattern) { - SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachment() || + SkASSERT(!rt->isMixedSampled() || rt->renderTargetPriv().getStencilAttachment() || stencil.isDisabled()); this->flushStencil(stencil); diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 27713b2dd2..8dacf48ce5 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -23,7 +23,7 @@ GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const IDDesc& idDesc, GrGLStencilAttachment* stencil) : GrSurface(gpu, desc) - , INHERITED(gpu, desc, idDesc.fSampleConfig, stencil) { + , INHERITED(gpu, desc, ComputeFlags(gpu->glCaps(), idDesc), stencil) { this->init(desc, idDesc); this->registerWithCacheWrapped(); } @@ -31,10 +31,23 @@ GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc) : GrSurface(gpu, desc) - , INHERITED(gpu, desc, idDesc.fSampleConfig) { + , INHERITED(gpu, desc, ComputeFlags(gpu->glCaps(), idDesc)) { this->init(desc, idDesc); } +inline GrRenderTarget::Flags GrGLRenderTarget::ComputeFlags(const GrGLCaps& glCaps, + const IDDesc& idDesc) { + Flags flags = Flags::kNone; + if (idDesc.fIsMixedSampled) { + SkASSERT(glCaps.usesMixedSamples() && idDesc.fRTFBOID); // FBO 0 can't be mixed sampled. + flags |= Flags::kMixedSampled; + } + if (glCaps.maxWindowRectangles() > 0 && idDesc.fRTFBOID) { + flags |= Flags::kWindowRectsSupport; + } + return flags; +} + void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) { fRTFBOID = idDesc.fRTFBOID; fTexFBOID = idDesc.fTexFBOID; diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h index edf35a1a5c..85e377f69a 100644 --- a/src/gpu/gl/GrGLRenderTarget.h +++ b/src/gpu/gl/GrGLRenderTarget.h @@ -13,6 +13,7 @@ #include "GrRenderTarget.h" #include "SkScalar.h" +class GrGLCaps; class GrGLGpu; class GrGLStencilAttachment; @@ -23,11 +24,11 @@ public: enum { kUnresolvableFBOID = 0 }; struct IDDesc { - GrGLuint fRTFBOID; - GrBackendObjectOwnership fRTFBOOwnership; - GrGLuint fTexFBOID; - GrGLuint fMSColorRenderbufferID; - GrRenderTarget::SampleConfig fSampleConfig; + GrGLuint fRTFBOID; + GrBackendObjectOwnership fRTFBOOwnership; + GrGLuint fTexFBOID; + GrGLuint fMSColorRenderbufferID; + bool fIsMixedSampled; }; static GrGLRenderTarget* CreateWrapped(GrGLGpu*, @@ -83,6 +84,8 @@ private: // Constructor for instances wrapping backend objects. GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrGLStencilAttachment*); + static Flags ComputeFlags(const GrGLCaps&, const IDDesc&); + GrGLGpu* getGLGpu() const; bool completeStencilAttachment() override; diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp index 83a4b44a59..dc966cab81 100644 --- a/src/gpu/vk/GrVkRenderTarget.cpp +++ b/src/gpu/vk/GrVkRenderTarget.cpp @@ -32,7 +32,7 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, : GrSurface(gpu, desc) , GrVkImage(info, wrapped) // for the moment we only support 1:1 color to stencil - , GrRenderTarget(gpu, desc, kUnified_SampleConfig) + , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) , fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped)) , fResolveAttachmentView(resolveAttachmentView) @@ -57,7 +57,7 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, : GrSurface(gpu, desc) , GrVkImage(info, wrapped) // for the moment we only support 1:1 color to stencil - , GrRenderTarget(gpu, desc, kUnified_SampleConfig) + , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) , fMSAAImage(new GrVkImage(msaaInfo, GrVkImage::kNot_Wrapped)) , fResolveAttachmentView(resolveAttachmentView) @@ -79,7 +79,7 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, GrVkImage::Wrapped wrapped) : GrSurface(gpu, desc) , GrVkImage(info, wrapped) - , GrRenderTarget(gpu, desc, kUnified_SampleConfig) + , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) , fMSAAImage(nullptr) , fResolveAttachmentView(nullptr) @@ -100,7 +100,7 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, GrVkImage::Wrapped wrapped) : GrSurface(gpu, desc) , GrVkImage(info, wrapped) - , GrRenderTarget(gpu, desc, kUnified_SampleConfig) + , GrRenderTarget(gpu, desc) , fColorAttachmentView(colorAttachmentView) , fMSAAImage(nullptr) , fResolveAttachmentView(nullptr) diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp index 2ed4591a72..45d3945c7f 100644 --- a/tests/ProxyTest.cpp +++ b/tests/ProxyTest.cpp @@ -10,6 +10,7 @@ #include "Test.h" #if SK_SUPPORT_GPU +#include "GrGpu.h" #include "GrSurfaceProxy.h" #include "GrTextureProxy.h" #include "GrRenderTargetProxy.h" @@ -50,7 +51,8 @@ static void check_rendertarget(skiatest::Reporter* reporter, rtProxy->isStencilBufferMultisampled()); REPORTER_ASSERT(reporter, rt->numColorSamples() == rtProxy->numColorSamples()); REPORTER_ASSERT(reporter, rt->numStencilSamples() == rtProxy->numStencilSamples()); - REPORTER_ASSERT(reporter, rt->hasMixedSamples() == rtProxy->hasMixedSamples()); + REPORTER_ASSERT(reporter, rt->isMixedSampled() == rtProxy->isMixedSampled()); + REPORTER_ASSERT(reporter, rt->renderTargetPriv().flags() == rtProxy->testingOnly_getFlags()); } static void check_texture(skiatest::Reporter* reporter, @@ -124,6 +126,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(AllocedProxyTest, reporter, ctxInfo) { DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { GrTextureProvider* provider = ctxInfo.grContext()->textureProvider(); + const GrCaps& caps = *ctxInfo.grContext()->caps(); static const int kWidthHeight = 100; @@ -131,8 +134,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { for (auto config : { kAlpha_8_GrPixelConfig, kRGBA_8888_GrPixelConfig }) { for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) { for (auto numSamples: { 0, 4}) { - bool renderable = ctxInfo.grContext()->caps()->isConfigRenderable( - config, numSamples > 0); + bool renderable = caps.isConfigRenderable(config, numSamples > 0); GrSurfaceDesc desc; desc.fOrigin = origin; @@ -141,14 +143,40 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { desc.fConfig = config; desc.fSampleCnt = numSamples; + // External on-screen render target. + if (renderable && kOpenGL_GrBackend == ctxInfo.backend()) { + GrBackendRenderTargetDesc backendDesc; + backendDesc.fWidth = kWidthHeight; + backendDesc.fHeight = kWidthHeight; + backendDesc.fConfig = config; + backendDesc.fOrigin = origin; + backendDesc.fSampleCnt = numSamples; + backendDesc.fStencilBits = 8; + backendDesc.fRenderTargetHandle = 0; + + GrGpu* gpu = ctxInfo.grContext()->getGpu(); + sk_sp defaultFBO( + gpu->wrapBackendRenderTarget(backendDesc, kBorrow_GrWrapOwnership)); + SkASSERT(!defaultFBO->renderTargetPriv().supportsWindowRectangles()); + + sk_sp rtProxy( + GrRenderTargetProxy::Make(caps, defaultFBO)); + check_surface(reporter, rtProxy.get(), origin, + kWidthHeight, kWidthHeight, config); + check_rendertarget(reporter, provider, rtProxy.get(), SkBackingFit::kExact); + } + sk_sp tex; + // Internal offscreen render target. if (renderable) { desc.fFlags = kRenderTarget_GrSurfaceFlag; tex.reset(provider->createTexture(desc, budgeted)); sk_sp rt(sk_ref_sp(tex->asRenderTarget())); + SkASSERT(caps.maxWindowRectangles() <= 0 || + rt->renderTargetPriv().supportsWindowRectangles()); - sk_sp rtProxy(GrRenderTargetProxy::Make(rt)); + sk_sp rtProxy(GrRenderTargetProxy::Make(caps, rt)); check_surface(reporter, rtProxy.get(), origin, kWidthHeight, kWidthHeight, config); check_rendertarget(reporter, provider, rtProxy.get(), SkBackingFit::kExact); diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index 33d88446f2..d2c72956ea 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -13,6 +13,7 @@ #include "GrDrawingManager.h" #include "GrGpuResourceCacheAccess.h" #include "GrPipelineBuilder.h" +#include "GrRenderTargetProxy.h" #include "GrResourceCache.h" #include "SkGpuDevice.h" @@ -257,6 +258,12 @@ void GrDrawContextPriv::testingOnly_drawBatch(const GrPaint& paint, #undef ASSERT_SINGLE_OWNER #undef RETURN_IF_ABANDONED +/////////////////////////////////////////////////////////////////////////////// + +GrRenderTargetPriv::Flags GrRenderTargetProxy::testingOnly_getFlags() const { + return fFlags; +} + /////////////////////////////////////////////////////////////////////////////// // Code for the mock context. It's built on a mock GrGpu class that does nothing. //// -- 2.34.1