aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/gpu.gni1
-rw-r--r--include/core/SkSurfaceCharacterization.h12
-rw-r--r--include/gpu/GrContext.h4
-rw-r--r--include/gpu/GrSurface.h8
-rw-r--r--include/private/GrRenderTargetProxy.h26
-rw-r--r--include/private/GrSurfaceProxy.h14
-rw-r--r--include/private/GrTypesPriv.h5
-rw-r--r--src/core/SkDeferredDisplayListRecorder.cpp17
-rw-r--r--src/core/SkSurfaceCharacterization.cpp1
-rw-r--r--src/gpu/GrContext.cpp8
-rw-r--r--src/gpu/GrRenderTargetProxy.cpp10
-rw-r--r--src/gpu/GrRenderTargetProxyPriv.h50
-rw-r--r--src/gpu/GrTextureRenderTargetProxy.cpp6
-rw-r--r--src/gpu/gl/GrGLRenderTarget.cpp3
-rw-r--r--src/image/SkSurface_Gpu.cpp18
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;
}