diff options
author | Greg Daniel <egdaniel@google.com> | 2018-04-16 11:24:10 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-16 17:05:20 +0000 |
commit | e3204864899651a132d3387422d7fd599c21b3ac (patch) | |
tree | dcc19da5c650a435de56317f73044eb03b82a3c4 | |
parent | 45c92203ef43d09ca6444430bd4081ac97b71237 (diff) |
Don't allow ganesh to allocate mip maps for wrapped textures.
We will not allocate new mips on a wrapped texture but we will use mips
if the wrapped texture already has one. If we need mips for a draw this
will trigger a copy to occur.
Also some cleanup up of our InternalSurfaceFlags in general.
Bug: skia:7806
Change-Id: I7aa666478cc91bba6e0644b323825fcc9b49793a
Reviewed-on: https://skia-review.googlesource.com/121348
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | include/private/GrSurfaceProxy.h | 30 | ||||
-rw-r--r-- | include/private/GrTextureProxy.h | 13 | ||||
-rw-r--r-- | src/gpu/GrBackendTextureImageGenerator.cpp | 11 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrProxyProvider.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrTexturePriv.h | 4 | ||||
-rw-r--r-- | src/gpu/GrTextureProxyPriv.h | 4 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 9 | ||||
-rw-r--r-- | tests/DeferredDisplayListTest.cpp | 2 | ||||
-rw-r--r-- | tests/LazyProxyTest.cpp | 4 |
11 files changed, 71 insertions, 34 deletions
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 3c503faeb8..d8fd33cc76 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 setDoesNotSupportMipMaps() { - SkASSERT(this->asTextureProxy()); - fSurfaceFlags |= GrInternalSurfaceFlags::kDoesNotSupportMipMaps; - } - bool doesNotSupportMipMaps() const { - return fSurfaceFlags & GrInternalSurfaceFlags::kDoesNotSupportMipMaps; - } - - void setIsClampOnly() { - SkASSERT(this->asTextureProxy()); - fSurfaceFlags |= GrInternalSurfaceFlags::kIsClampOnly; - } - bool isClampOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kIsClampOnly; } - void setHasMixedSamples() { SkASSERT(this->asRenderTargetProxy()); fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled; @@ -448,6 +434,14 @@ protected: 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 + // proxies we will copy the properties off of the GrSurface. For lazy proxies we force the + // call sites to provide the required information ahead of time. At instantiation time + // we verify that the assumed properties match the actual properties. + GrInternalSurfaceFlags fSurfaceFlags; + private: // For wrapped resources, 'fConfig', 'fWidth', 'fHeight', and 'fOrigin; will always be filled in // from the wrapped resource. @@ -461,14 +455,6 @@ private: // set from the backing resource for wrapped resources // mutable bc of SkSurface/SkImage wishy-washiness - // 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 - // proxies we will copy the properties off of the GrSurface. For lazy proxies we force the - // call sites to provide the required information ahead of time. At instantiation time - // we verify that the assumed properties match the actual properties. - GrInternalSurfaceFlags fSurfaceFlags; - const UniqueID fUniqueID; // set from the backing resource for wrapped resources LazyInstantiateCallback fLazyInstantiateCallback; diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h index 2ded566475..5954f1b6f4 100644 --- a/include/private/GrTextureProxy.h +++ b/include/private/GrTextureProxy.h @@ -100,6 +100,19 @@ protected: sk_sp<GrSurface> createSurface(GrResourceProvider*) const override; + void setDoesNotSupportMipMaps() { + fSurfaceFlags |= GrInternalSurfaceFlags::kDoesNotSupportMipMaps; + } + bool doesNotSupportMipMaps() const { + return fSurfaceFlags & GrInternalSurfaceFlags::kDoesNotSupportMipMaps; + } + + void setIsClampOnly() { + fSurfaceFlags |= GrInternalSurfaceFlags::kIsClampOnly; + } + bool isClampOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kIsClampOnly; } + + private: GrMipMapped fMipMapped; diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp index 89a6870b59..3835bfaa26 100644 --- a/src/gpu/GrBackendTextureImageGenerator.cpp +++ b/src/gpu/GrBackendTextureImageGenerator.cpp @@ -18,6 +18,7 @@ #include "GrSemaphore.h" #include "GrTexture.h" #include "GrTexturePriv.h" +#include "GrTextureProxyPriv.h" #include "SkGr.h" #include "SkMessageBus.h" @@ -175,6 +176,16 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture( }, desc, fSurfaceOrigin, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo); + if (!proxy) { + return nullptr; + } + + // We can't pass the fact that this creates a wrapped texture into createLazyProxy so we need + // to manually call setDoesNotSupportMipMaps. + if (GrMipMapped::kNo == mipMapped) { + proxy->texPriv().setDoesNotSupportMipMaps(); + } + if (0 == origin.fX && 0 == origin.fY && info.width() == fBackendTexture.width() && info.height() == fBackendTexture.height() && (!willNeedMipMaps || GrMipMapped::kYes == proxy->mipMapped())) { diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index fafce10f57..297aa15684 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -138,8 +138,10 @@ sk_sp<GrTexture> GrGpu::wrapBackendTexture(const GrBackendTexture& backendTex, return nullptr; } sk_sp<GrTexture> tex = this->onWrapBackendTexture(backendTex, ownership); - if (!tex) { - return nullptr; + if (tex && !backendTex.hasMipMaps()) { + // Ganesh will not ever allocate mipmaps for a wrapped resource. By setting this flag here, + // it will be propagated to any proxy that wraps this texture. + tex->texturePriv().setDoesNotSupportMipMaps(); } return tex; } @@ -160,10 +162,12 @@ sk_sp<GrTexture> GrGpu::wrapRenderableBackendTexture(const GrBackendTexture& bac return nullptr; } sk_sp<GrTexture> tex = this->onWrapRenderableBackendTexture(backendTex, sampleCnt, ownership); - if (!tex) { - return nullptr; + if (tex && !backendTex.hasMipMaps()) { + // Ganesh will not ever allocate mipmaps for a wrapped resource. By setting this flag here, + // it will be propagated to any proxy that wraps this texture. + tex->texturePriv().setDoesNotSupportMipMaps(); } - SkASSERT(tex->asRenderTarget()); + SkASSERT(!tex || tex->asRenderTarget()); return tex; } diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp index a4b8d61cf3..49e57df35b 100644 --- a/src/gpu/GrProxyProvider.cpp +++ b/src/gpu/GrProxyProvider.cpp @@ -552,7 +552,6 @@ sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& return nullptr; } - surfaceFlags |= GrInternalSurfaceFlags::kNoPendingIO; #ifdef SK_DEBUG if (SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)) { @@ -585,7 +584,6 @@ sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy( } SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)); - surfaceFlags |= GrInternalSurfaceFlags::kNoPendingIO; #ifdef SK_DEBUG if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kMixedSampled)) { @@ -616,7 +614,7 @@ sk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallb GrSurfaceOrigin origin, GrPixelConfig config) { GrSurfaceDesc desc; - GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone; + GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNoPendingIO; if (Renderable::kYes == renderable) { desc.fFlags = kRenderTarget_GrSurfaceFlag; if (fCaps->maxWindowRectangles() > 0) { diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 1016390f7e..ff3ae3b560 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -51,13 +51,13 @@ static bool is_valid_non_lazy(const GrSurfaceDesc& desc) { GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType, const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags) - : fConfig(desc.fConfig) + : fSurfaceFlags(surfaceFlags) + , fConfig(desc.fConfig) , fWidth(desc.fWidth) , fHeight(desc.fHeight) , fOrigin(origin) , fFit(fit) , fBudgeted(budgeted) - , fSurfaceFlags(surfaceFlags) , fLazyInstantiateCallback(std::move(callback)) , fLazyInstantiationType(lazyType) , fNeedsClear(SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag)) @@ -74,13 +74,13 @@ GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantia // Wrapped version GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit) : INHERITED(std::move(surface)) + , fSurfaceFlags(fTarget->surfacePriv().flags()) , fConfig(fTarget->config()) , fWidth(fTarget->width()) , fHeight(fTarget->height()) , fOrigin(origin) , fFit(fit) , fBudgeted(fTarget->resourcePriv().isBudgeted()) - , fSurfaceFlags(fTarget->surfacePriv().flags()) , fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID! , fNeedsClear(false) , fGpuMemorySize(kInvalidGpuMemorySize) @@ -425,6 +425,10 @@ bool GrSurfaceProxyPriv::doLazyInstantiation(GrResourceProvider* resourceProvide GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, surface.get(), needsStencil); SkASSERT(surface->config() == fProxy->fConfig); + // Assert the flags are the same except for kNoPendingIO which is not passed onto the GrSurface. + SkDEBUGCODE(GrInternalSurfaceFlags proxyFlags = + fProxy->fSurfaceFlags & ~GrInternalSurfaceFlags::kNoPendingIO); + SkASSERT(surface->surfacePriv().flags() == proxyFlags); SkDEBUGCODE(fProxy->validateLazySurface(surface.get());) this->assign(std::move(surface)); return true; diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h index ad69d3133c..80ac75fdb8 100644 --- a/src/gpu/GrTexturePriv.h +++ b/src/gpu/GrTexturePriv.h @@ -44,6 +44,10 @@ public: return fTexture->fMaxMipMapLevel; } + void setDoesNotSupportMipMaps() { + fTexture->setDoesNotSupportMipMaps(); + } + GrSLType samplerType() const { return fTexture->fSamplerType; } /** The filter used is clamped to this value in GrProcessor::TextureSampler. */ diff --git a/src/gpu/GrTextureProxyPriv.h b/src/gpu/GrTextureProxyPriv.h index c7582d3ee9..b2b002864e 100644 --- a/src/gpu/GrTextureProxyPriv.h +++ b/src/gpu/GrTextureProxyPriv.h @@ -34,6 +34,10 @@ public: bool doesNotSupportMipMaps() const { return fTextureProxy->doesNotSupportMipMaps(); } bool isClampOnly() const { return fTextureProxy->isClampOnly(); } + void setDoesNotSupportMipMaps() { + fTextureProxy->setDoesNotSupportMipMaps(); + } + private: explicit GrTextureProxyPriv(GrTextureProxy* textureProxy) : fTextureProxy(textureProxy) {} GrTextureProxyPriv(const GrTextureProxyPriv&) {} // unimpl diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index fc2e436948..bd75c276a2 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -28,6 +28,7 @@ #include "GrTexture.h" #include "GrTexturePriv.h" #include "GrTextureProxy.h" +#include "GrTextureProxyPriv.h" #include "gl/GrGLDefines.h" #include "effects/GrNonlinearColorSpaceXformEffect.h" #include "effects/GrYUVtoRGBEffect.h" @@ -728,6 +729,14 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context, return nullptr; } + // Promise images always wrap resources. So if the promise image doesn't have mip maps, we + // cannot allocate mips for them and thus will need a copy to use a mipped image. We can't pass + // the fact that this creates a wrapped texture into createLazyProxy so we need to manually call + // setDoesNotSupportMipMaps. + if (GrMipMapped::kNo == mipMapped) { + proxy->texPriv().setDoesNotSupportMipMaps(); + } + return sk_make_sp<SkImage_Gpu>(context, kNeedNewImageUniqueID, alphaType, std::move(proxy), std::move(colorSpace), SkBudgeted::kNo); } diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp index 8c361560b7..9716477591 100644 --- a/tests/DeferredDisplayListTest.cpp +++ b/tests/DeferredDisplayListTest.cpp @@ -826,7 +826,7 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) { for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) { GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target); - sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, GrMipMapped::kNo, + sk_sp<SkImage> image = recorder.makePromiseTexture(format, 32, 32, GrMipMapped::kYes, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr, diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp index c048ea6a28..b8e672a55f 100644 --- a/tests/LazyProxyTest.cpp +++ b/tests/LazyProxyTest.cpp @@ -430,6 +430,10 @@ DEF_GPUTEST(LazyProxyUninstantiateTest, reporter, /* options */) { REPORTER_ASSERT(reporter, lazyProxy.get()); + // We can't pass the fact that this creates a wrapped texture into createLazyProxy so we + // need to manually call setDoesNotSupportMipMaps. + lazyProxy->texPriv().setDoesNotSupportMipMaps(); + rtc->priv().testingOnly_addDrawOp(skstd::make_unique<LazyUninstantiateTestOp>(lazyProxy)); ctx->flush(); |