diff options
-rw-r--r-- | gn/gpu.gni | 1 | ||||
-rw-r--r-- | include/core/SkSurfaceCharacterization.h | 12 | ||||
-rw-r--r-- | include/gpu/GrContext.h | 4 | ||||
-rw-r--r-- | include/gpu/GrSurface.h | 8 | ||||
-rw-r--r-- | include/private/GrRenderTargetProxy.h | 26 | ||||
-rw-r--r-- | include/private/GrSurfaceProxy.h | 14 | ||||
-rw-r--r-- | include/private/GrTypesPriv.h | 5 | ||||
-rw-r--r-- | src/core/SkDeferredDisplayListRecorder.cpp | 17 | ||||
-rw-r--r-- | src/core/SkSurfaceCharacterization.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetProxy.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetProxyPriv.h | 50 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLRenderTarget.cpp | 3 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 18 |
15 files changed, 152 insertions, 31 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni index 55257a761f..93e21cbb0d 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -156,6 +156,7 @@ skia_gpu_sources = [ "$_src/gpu/GrRenderTarget.cpp", "$_src/gpu/GrRenderTargetPriv.h", "$_src/gpu/GrRenderTargetProxy.cpp", + "$_src/gpu/GrRenderTargetProxyPriv.h", "$_src/gpu/GrReducedClip.cpp", "$_src/gpu/GrReducedClip.h", "$_src/gpu/GrRenderTargetContext.cpp", diff --git a/include/core/SkSurfaceCharacterization.h b/include/core/SkSurfaceCharacterization.h index 797e5e4717..e8efdcf2a9 100644 --- a/include/core/SkSurfaceCharacterization.h +++ b/include/core/SkSurfaceCharacterization.h @@ -30,6 +30,7 @@ class SK_API SkSurfaceCharacterization { public: enum class Textureable : bool { kNo = false, kYes = true }; enum class MipMapped : bool { kNo = false, kYes = true }; + enum class UsesGLFBO0 : bool { kNo = false, kYes = true }; SkSurfaceCharacterization() : fCacheMaxResourceBytes(0) @@ -39,6 +40,7 @@ public: , fStencilCnt(0) , fIsTextureable(Textureable::kYes) , fIsMipMapped(MipMapped::kYes) + , fUsesGLFBO0(UsesGLFBO0::kNo) , fSurfaceProps(0, kUnknown_SkPixelGeometry) { } @@ -67,7 +69,7 @@ public: fCacheMaxResourceBytes, fImageInfo.makeWH(width, height), fOrigin, fConfig, fFSAAType, fStencilCnt, - fIsTextureable, fIsMipMapped, + fIsTextureable, fIsMipMapped, fUsesGLFBO0, fSurfaceProps); } @@ -86,6 +88,7 @@ public: int stencilCount() const { return fStencilCnt; } bool isTextureable() const { return Textureable::kYes == fIsTextureable; } bool isMipMapped() const { return MipMapped::kYes == fIsMipMapped; } + bool usesGLFBO0() const { return UsesGLFBO0::kYes == fUsesGLFBO0; } SkColorSpace* colorSpace() const { return fImageInfo.colorSpace(); } sk_sp<SkColorSpace> refColorSpace() const { return fImageInfo.refColorSpace(); } const SkSurfaceProps& surfaceProps()const { return fSurfaceProps; } @@ -105,6 +108,7 @@ private: GrPixelConfig config, GrFSAAType FSAAType, int stencilCnt, Textureable isTextureable, MipMapped isMipMapped, + UsesGLFBO0 usesGLFBO0, const SkSurfaceProps& surfaceProps) : fContextInfo(std::move(contextInfo)) , fCacheMaxResourceBytes(cacheMaxResourceBytes) @@ -115,6 +119,7 @@ private: , fStencilCnt(stencilCnt) , fIsTextureable(isTextureable) , fIsMipMapped(isMipMapped) + , fUsesGLFBO0(usesGLFBO0) , fSurfaceProps(surfaceProps) { } @@ -127,8 +132,10 @@ private: int stencilCnt, Textureable isTextureable, MipMapped isMipMapped, + UsesGLFBO0 usesGLFBO0, const SkSurfaceProps& surfaceProps) { SkASSERT(MipMapped::kNo == isMipMapped || Textureable::kYes == isTextureable); + SkASSERT(Textureable::kNo == isTextureable || UsesGLFBO0::kNo == usesGLFBO0); fContextInfo = contextInfo; fCacheMaxResourceBytes = cacheMaxResourceBytes; @@ -140,6 +147,7 @@ private: fStencilCnt = stencilCnt; fIsTextureable = isTextureable; fIsMipMapped = isMipMapped; + fUsesGLFBO0 = usesGLFBO0; fSurfaceProps = surfaceProps; } @@ -153,6 +161,7 @@ private: int fStencilCnt; Textureable fIsTextureable; MipMapped fIsMipMapped; + UsesGLFBO0 fUsesGLFBO0; SkSurfaceProps fSurfaceProps; }; @@ -180,6 +189,7 @@ public: int stencilCount() const { return 0; } bool isTextureable() const { return false; } bool isMipMapped() const { return false; } + bool usesGLFBO0() const { return false; } SkColorSpace* colorSpace() const { return nullptr; } sk_sp<SkColorSpace> refColorSpace() const { return nullptr; } const SkSurfaceProps& surfaceProps()const { return fSurfaceProps; } diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index e8f8acc3cf..1acd30c127 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -388,13 +388,15 @@ public: * with this characterization will be replayed into * @param isMipMapped Will the surface the DDL will be replayed into have space * allocated for mipmaps? + * @param willUseGLFBO0 Will the surface the DDL will be replayed into be backed by GL + * FBO 0. This flag is only valid if using an GL backend. */ SkSurfaceCharacterization createCharacterization( size_t cacheMaxResourceBytes, const SkImageInfo& ii, const GrBackendFormat& backendFormat, int sampleCount, GrSurfaceOrigin origin, const SkSurfaceProps& surfaceProps, - bool isMipMapped); + bool isMipMapped, bool willUseGLFBO0 = false); const GrCaps* caps() const { return fCaps.get(); } sk_sp<const GrCaps> refCaps() const { return fCaps; } diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h index 46d3945de4..4ddc5d14cc 100644 --- a/include/gpu/GrSurface.h +++ b/include/gpu/GrSurface.h @@ -91,6 +91,14 @@ protected: return fSurfaceFlags & GrInternalSurfaceFlags::kWindowRectsSupport; } + void setGLRTFBOIDIs0() { + SkASSERT(this->asRenderTarget()); + fSurfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0; + } + bool glRTFBOIDis0() const { + return fSurfaceFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0; + } + // Methods made available via GrSurfacePriv bool hasPendingRead() const; bool hasPendingWrite() const; diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h index 29c4fc300a..85201250e7 100644 --- a/include/private/GrRenderTargetProxy.h +++ b/include/private/GrRenderTargetProxy.h @@ -12,6 +12,7 @@ #include "GrTypesPriv.h" class GrResourceProvider; +class GrRenderTargetProxyPriv; // This class delays the acquisition of RenderTargets until they are actually // required @@ -56,8 +57,13 @@ public: // TODO: move this to a priv class! bool refsWrappedObjects() const; + // Provides access to special purpose functions. + GrRenderTargetProxyPriv rtPriv(); + const GrRenderTargetProxyPriv rtPriv() const; + protected: friend class GrProxyProvider; // for ctors + friend class GrRenderTargetProxyPriv; // Deferred version GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, GrSurfaceOrigin, SkBackingFit, @@ -83,6 +89,26 @@ protected: sk_sp<GrSurface> createSurface(GrResourceProvider*) const override; private: + void setHasMixedSamples() { + fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled; + } + bool hasMixedSamples() const { return fSurfaceFlags & GrInternalSurfaceFlags::kMixedSampled; } + + void setSupportsWindowRects() { + fSurfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport; + } + bool supportsWindowRects() const { + return fSurfaceFlags & GrInternalSurfaceFlags::kWindowRectsSupport; + } + + void setGLRTFBOIDIs0() { + fSurfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0; + } + bool glRTFBOIDIs0() const { + return fSurfaceFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0; + } + + size_t onUninstantiatedGpuMemorySize() const override; SkDEBUGCODE(void onValidateSurface(const GrSurface*) override;) diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 20ee9a4d97..1c18492cbd 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -420,20 +420,6 @@ protected: bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, bool needsStencil, GrSurfaceDescFlags descFlags, GrMipMapped, const GrUniqueKey*); - void setHasMixedSamples() { - SkASSERT(this->asRenderTargetProxy()); - fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled; - } - bool hasMixedSamples() const { return fSurfaceFlags & GrInternalSurfaceFlags::kMixedSampled; } - - void setSupportsWindowRects() { - SkASSERT(this->asRenderTargetProxy()); - fSurfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport; - } - bool supportsWindowRects() const { - return fSurfaceFlags & GrInternalSurfaceFlags::kWindowRectsSupport; - } - // In many cases these flags aren't actually known until the proxy has been instantiated. // However, Ganesh frequently needs to change its behavior based on these settings. For // internally create proxies we will know these properties ahead of time. For wrapped diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h index e47bef7f5b..ecbd616567 100644 --- a/include/private/GrTypesPriv.h +++ b/include/private/GrTypesPriv.h @@ -902,7 +902,10 @@ enum class GrInternalSurfaceFlags { // but, otherwise, is enabled whenever GrCaps reports window rect support kWindowRectsSupport = 1 << 4, - kRenderTargetMask = kMixedSampled | kWindowRectsSupport, + // This flag is for use with GL only. It tells us that the internal render target wraps FBO 0. + kGLRTFBOIDIs0 = 1 << 5, + + kRenderTargetMask = kMixedSampled | kWindowRectsSupport | kGLRTFBOIDIs0, }; GR_MAKE_BITFIELD_CLASS_OPS(GrInternalSurfaceFlags) diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp index 8a89068f4f..d390228e4a 100644 --- a/src/core/SkDeferredDisplayListRecorder.cpp +++ b/src/core/SkDeferredDisplayListRecorder.cpp @@ -80,6 +80,14 @@ bool SkDeferredDisplayListRecorder::init() { auto proxyProvider = fContext->contextPriv().proxyProvider(); + bool usesGLFBO0 = fCharacterization.usesGLFBO0(); + if (usesGLFBO0) { + if (kOpenGL_GrBackend != fContext->contextPriv().getBackend() || + fCharacterization.isTextureable()) { + return false; + } + } + GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = fCharacterization.width(); @@ -94,12 +102,17 @@ bool SkDeferredDisplayListRecorder::init() { // DDL is being replayed into. GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone; - if (fContext->caps()->usesMixedSamples() && desc.fSampleCnt > 1) { + if (fContext->caps()->usesMixedSamples() && desc.fSampleCnt > 1 && !usesGLFBO0) { + // In GL, FBO 0 never supports mixed samples surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled; } - if (fContext->caps()->maxWindowRectangles() > 0) { + if (fContext->caps()->maxWindowRectangles() > 0 && !usesGLFBO0) { + // In GL, FBO 0 never supports window rectangles surfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport; } + if (usesGLFBO0) { + surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0; + } sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy( [lazyProxyData](GrResourceProvider* resourceProvider) { diff --git a/src/core/SkSurfaceCharacterization.cpp b/src/core/SkSurfaceCharacterization.cpp index b82f2a681f..930e96fc39 100644 --- a/src/core/SkSurfaceCharacterization.cpp +++ b/src/core/SkSurfaceCharacterization.cpp @@ -25,6 +25,7 @@ bool SkSurfaceCharacterization::operator==(const SkSurfaceCharacterization& othe fStencilCnt == other.fStencilCnt && fIsTextureable == other.fIsTextureable && fIsMipMapped == other.fIsMipMapped && + fUsesGLFBO0 == other.fUsesGLFBO0 && fSurfaceProps == other.fSurfaceProps; } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index bade6e341c..7b0ab71676 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -172,11 +172,16 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization( const SkImageInfo& ii, const GrBackendFormat& backendFormat, int sampleCnt, GrSurfaceOrigin origin, const SkSurfaceProps& surfaceProps, - bool isMipMapped) { + bool isMipMapped, bool willUseGLFBO0) { if (!backendFormat.isValid()) { return SkSurfaceCharacterization(); // return an invalid characterization } + if (kOpenGL_GrBackend != backendFormat.backend() && willUseGLFBO0) { + // The willUseGLFBO0 flags can only be used for a GL backend. + return SkSurfaceCharacterization(); // return an invalid characterization + } + if (!fCaps->mipMapSupport()) { isMipMapped = false; } @@ -211,6 +216,7 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization( origin, config, FSAAType, sampleCnt, SkSurfaceCharacterization::Textureable(true), SkSurfaceCharacterization::MipMapped(isMipMapped), + SkSurfaceCharacterization::UsesGLFBO0(willUseGLFBO0), surfaceProps); } diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index c5d096d5db..5488625581 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -113,11 +113,9 @@ void GrRenderTargetProxy::onValidateSurface(const GrSurface* surface) { SkASSERT(surface->asRenderTarget()); SkASSERT(surface->asRenderTarget()->numStencilSamples() == this->numStencilSamples()); - // DDL TODO: re-enable this after skbug.com/7748 (Add FBO-0-ness to SkSurfaceCharacterization) - // is fixed. - // GrInternalSurfaceFlags proxyFlags = fSurfaceFlags; - // GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags(); - // SkASSERT((proxyFlags & GrInternalSurfaceFlags::kRenderTargetMask) == - // (surfaceFlags & GrInternalSurfaceFlags::kRenderTargetMask)); + GrInternalSurfaceFlags proxyFlags = fSurfaceFlags; + GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags(); + SkASSERT((proxyFlags & GrInternalSurfaceFlags::kRenderTargetMask) == + (surfaceFlags & GrInternalSurfaceFlags::kRenderTargetMask)); } #endif diff --git a/src/gpu/GrRenderTargetProxyPriv.h b/src/gpu/GrRenderTargetProxyPriv.h new file mode 100644 index 0000000000..7c80099743 --- /dev/null +++ b/src/gpu/GrRenderTargetProxyPriv.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrRenderTargetProxyPriv_DEFINED +#define GrRenderTargetProxyPriv_DEFINED + +#include "GrRenderTargetProxy.h" + +/** + * This class hides the more specialized capabilities of GrRenderTargetProxy. + */ +class GrRenderTargetProxyPriv { +public: + void setGLRTFBOIDIs0() { + fRenderTargetProxy->setGLRTFBOIDIs0(); + } + + bool glRTFBOIDIs0() const { + return fRenderTargetProxy->glRTFBOIDIs0(); + } + +private: + explicit GrRenderTargetProxyPriv(GrRenderTargetProxy* renderTargetProxy) + : fRenderTargetProxy(renderTargetProxy) {} + GrRenderTargetProxyPriv(const GrRenderTargetProxyPriv&) {} // unimpl + GrRenderTargetProxyPriv& operator=(const GrRenderTargetProxyPriv&); // unimpl + + // No taking addresses of this type. + const GrRenderTargetProxyPriv* operator&() const; + GrRenderTargetProxyPriv* operator&(); + + GrRenderTargetProxy* fRenderTargetProxy; + + friend class GrRenderTargetProxy; // to construct/copy this type. +}; + +inline GrRenderTargetProxyPriv GrRenderTargetProxy::rtPriv() { + return GrRenderTargetProxyPriv(this); +} + +inline const GrRenderTargetProxyPriv GrRenderTargetProxy::rtPriv() const { + return GrRenderTargetProxyPriv(const_cast<GrRenderTargetProxy*>(this)); +} + +#endif + diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp index dfc3d13432..95d5543bbf 100644 --- a/src/gpu/GrTextureRenderTargetProxy.cpp +++ b/src/gpu/GrTextureRenderTargetProxy.cpp @@ -125,10 +125,8 @@ void GrTextureRenderTargetProxy::onValidateSurface(const GrSurface* surface) { GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags(); SkASSERT((proxyFlags & GrInternalSurfaceFlags::kTextureMask) == (surfaceFlags & GrInternalSurfaceFlags::kTextureMask)); - // DDL TODO: re-enable this after skbug.com/7748 (Add FBO-0-ness to SkSurfaceCharacterization) - // is fixed. - // SkASSERT((proxyFlags & GrInternalSurfaceFlags::kRenderTargetMask) == - // (surfaceFlags & GrInternalSurfaceFlags::kRenderTargetMask)); + SkASSERT((proxyFlags & GrInternalSurfaceFlags::kRenderTargetMask) == + (surfaceFlags & GrInternalSurfaceFlags::kRenderTargetMask)); } #endif diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 5513e8aaa7..382457d5d7 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -46,6 +46,9 @@ inline void GrGLRenderTarget::setFlags(const GrGLCaps& glCaps, const IDDesc& idD if (glCaps.maxWindowRectangles() > 0 && idDesc.fRTFBOID) { this->setSupportsWindowRects(); } + if (!idDesc.fRTFBOID) { + this->setGLRTFBOIDIs0(); + } } void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) { diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index e9ae9104e2..21ed1f90eb 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -11,6 +11,7 @@ #include "GrContextPriv.h" #include "GrRenderTarget.h" #include "GrRenderTargetContextPriv.h" +#include "GrRenderTargetProxyPriv.h" #include "GrTexture.h" #include "SkCanvas.h" @@ -203,13 +204,19 @@ bool SkSurface_Gpu::onCharacterize(SkSurfaceCharacterization* characterization) return false; } + bool usesGLFBO0 = rtc->asRenderTargetProxy()->rtPriv().glRTFBOIDIs0(); + // We should never get in the situation where we have a texture render target that is also + // backend by FBO 0. + SkASSERT(!usesGLFBO0 || !SkToBool(rtc->asTextureProxy())); + SkImageInfo ii = SkImageInfo::Make(rtc->width(), rtc->height(), ct, kPremul_SkAlphaType, rtc->colorSpaceInfo().refColorSpace()); characterization->set(ctx->threadSafeProxy(), maxResourceBytes, ii, rtc->origin(), rtc->colorSpaceInfo().config(), rtc->fsaaType(), rtc->numStencilSamples(), SkSurfaceCharacterization::Textureable(SkToBool(rtc->asTextureProxy())), - SkSurfaceCharacterization::MipMapped(mipmapped), this->props()); + SkSurfaceCharacterization::MipMapped(mipmapped), + SkSurfaceCharacterization::UsesGLFBO0(usesGLFBO0), this->props()); return true; } @@ -245,6 +252,10 @@ bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& characterizati } } + if (characterization.usesGLFBO0() != rtc->asRenderTargetProxy()->rtPriv().glRTFBOIDIs0()) { + return false; + } + // TODO: the addition of colorType to the surfaceContext should remove this calculation SkColorType rtcColorType; if (!GrPixelConfigToColorType(rtc->colorSpaceInfo().config(), &rtcColorType)) { @@ -318,6 +329,11 @@ sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* context, return nullptr; } + if (c.usesGLFBO0()) { + // If we are making the surface we will never use FBO0. + return nullptr; + } + if (!SkSurface_Gpu::Valid(context->caps(), c.config(), c.colorSpace())) { return nullptr; } |