aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-04-16 11:24:10 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-16 17:05:20 +0000
commite3204864899651a132d3387422d7fd599c21b3ac (patch)
treedcc19da5c650a435de56317f73044eb03b82a3c4
parent45c92203ef43d09ca6444430bd4081ac97b71237 (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.h30
-rw-r--r--include/private/GrTextureProxy.h13
-rw-r--r--src/gpu/GrBackendTextureImageGenerator.cpp11
-rw-r--r--src/gpu/GrGpu.cpp14
-rw-r--r--src/gpu/GrProxyProvider.cpp4
-rw-r--r--src/gpu/GrSurfaceProxy.cpp10
-rw-r--r--src/gpu/GrTexturePriv.h4
-rw-r--r--src/gpu/GrTextureProxyPriv.h4
-rw-r--r--src/image/SkImage_Gpu.cpp9
-rw-r--r--tests/DeferredDisplayListTest.cpp2
-rw-r--r--tests/LazyProxyTest.cpp4
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();