diff options
author | Robert Phillips <robertphillips@google.com> | 2018-02-04 14:33:21 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-04 20:01:28 +0000 |
commit | e8fabb2665d12ee289bc3af5b7e93c5b12396e2d (patch) | |
tree | 3f7cde3336c04ae74c09b102d3fefd7f8c7fb5cd /src | |
parent | d2807d5115ad0f6954fa0d77e761db5afdb38d68 (diff) |
Update LazyProxy creation to allow for a non-textureable result
Change-Id: Ic284b4f4220afa714159e07f57798a94fd40d63a
Reviewed-on: https://skia-review.googlesource.com/102484
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkDeferredDisplayListRecorder.cpp | 17 | ||||
-rw-r--r-- | src/gpu/GrProxyProvider.cpp | 19 | ||||
-rw-r--r-- | src/gpu/GrProxyProvider.h | 11 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetProxy.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 15 | ||||
-rw-r--r-- | src/gpu/GrTextureProxy.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.cpp | 13 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 3 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 20 |
10 files changed, 93 insertions, 25 deletions
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp index b5442c69f8..14e5926637 100644 --- a/src/core/SkDeferredDisplayListRecorder.cpp +++ b/src/core/SkDeferredDisplayListRecorder.cpp @@ -76,22 +76,21 @@ bool SkDeferredDisplayListRecorder::init() { sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData; // What we're doing here is we're creating a lazy proxy to back the SkSurface. The lazy - // proxy, when instantiated, will use the GrTexture that backs the SkSurface that the + // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the // DDL is being replayed into. - sk_sp<GrSurfaceProxy> proxy = proxyProvider->createLazyProxy( + sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy( [ lazyProxyData ] (GrResourceProvider* resourceProvider, GrSurfaceOrigin* /* outOrigin */) { if (!resourceProvider) { - return sk_sp<GrTexture>(); + return sk_sp<GrSurface>(); } // The proxy backing the destination surface had better have been instantiated - // prior to the proxy backing the DLL's surface. Steal its GrTexture. - // DDL TODO: What do we do in the case where the Surface we're replaying into - // isn't texturable? - SkASSERT(lazyProxyData->fReplayDest->priv().peekTexture()); - return sk_ref_sp<GrTexture>(lazyProxyData->fReplayDest->priv().peekTexture()); - }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes); + // prior to the proxy backing the DLL's surface. Steal its GrRenderTarget. + SkASSERT(lazyProxyData->fReplayDest->priv().peekSurface()); + return sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->priv().peekSurface()); + }, desc, GrProxyProvider::Textureable(fCharacterization.isTextureable()), + GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes); sk_sp<GrSurfaceContext> c = fContext->contextPriv().makeWrappedSurfaceContext( std::move(proxy), diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp index 6641bcf9a8..8410a0a882 100644 --- a/src/gpu/GrProxyProvider.cpp +++ b/src/gpu/GrProxyProvider.cpp @@ -473,6 +473,25 @@ sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& budgeted, flags)); } +sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy( + LazyInstantiateCallback&& callback, + const GrSurfaceDesc& desc, + Textureable textureable, + GrMipMapped mipMapped, + SkBackingFit fit, SkBudgeted budgeted) { + SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) || + (desc.fWidth > 0 && desc.fHeight > 0)); + uint32_t flags = GrResourceProvider::kNoPendingIO_Flag; + if (Textureable::kYes == textureable) { + return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(callback), desc, + mipMapped, fit, budgeted, + flags)); + } + + return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(callback), desc, + fit, budgeted, flags)); +} + sk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallback&& callback, Renderable renderable, GrPixelConfig config) { diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h index 91cd5f600f..c5191a681c 100644 --- a/src/gpu/GrProxyProvider.h +++ b/src/gpu/GrProxyProvider.h @@ -147,9 +147,14 @@ public: GrSurfaceOrigin origin, int sampleCnt); - using LazyInstantiateCallback = std::function<sk_sp<GrTexture>(GrResourceProvider*, + using LazyInstantiateCallback = std::function<sk_sp<GrSurface>(GrResourceProvider*, GrSurfaceOrigin* outOrigin)>; + enum class Textureable : bool { + kNo = false, + kYes = true + }; + enum class Renderable : bool { kNo = false, kYes = true @@ -171,6 +176,10 @@ public: sk_sp<GrTextureProxy> createFullyLazyProxy(LazyInstantiateCallback&&, Renderable, GrPixelConfig); + sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&, + const GrSurfaceDesc&, Textureable, + GrMipMapped, SkBackingFit, SkBudgeted); + // 'proxy' is about to be used as a texture src or drawn to. This query can be used to // determine if it is going to need a texture domain or a full clear. static bool IsFunctionallyExact(GrSurfaceProxy* proxy); diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index 841d4b18fd..59dcd73a3e 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -115,3 +115,13 @@ bool GrRenderTargetProxy::refsWrappedObjects() const { return fTarget->resourcePriv().refsWrappedObjects(); } + +#ifdef SK_DEBUG +void GrRenderTargetProxy::validateLazySurface(const GrSurface* surface) { + SkASSERT(!surface->asTexture()); + + // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version + SkASSERT(surface->asRenderTarget()); + SkASSERT(surface->asRenderTarget()->numStencilSamples() == this->numStencilSamples()); +} +#endif diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 4020758259..c9cf535879 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -360,21 +360,20 @@ bool GrSurfaceProxyPriv::doLazyInstantiation(GrResourceProvider* resourceProvide outOrigin = &fProxy->fOrigin; } - sk_sp<GrTexture> texture = fProxy->fLazyInstantiateCallback(resourceProvider, outOrigin); - - if (!texture) { + sk_sp<GrSurface> surface = fProxy->fLazyInstantiateCallback(resourceProvider, outOrigin); + if (!surface) { fProxy->fWidth = 0; fProxy->fHeight = 0; fProxy->fOrigin = kTopLeft_GrSurfaceOrigin; return false; } - fProxy->fWidth = texture->width(); - fProxy->fHeight = texture->height(); + fProxy->fWidth = surface->width(); + fProxy->fHeight = surface->height(); - SkASSERT(texture->config() == fProxy->fConfig); - SkDEBUGCODE(fProxy->validateLazyTexture(texture.get());) - this->assign(std::move(texture)); + SkASSERT(surface->config() == fProxy->fConfig); + SkDEBUGCODE(fProxy->validateLazySurface(surface.get());) + this->assign(std::move(surface)); return true; } diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp index 54d0769a63..98c9ca0c6a 100644 --- a/src/gpu/GrTextureProxy.cpp +++ b/src/gpu/GrTextureProxy.cpp @@ -151,8 +151,12 @@ void GrTextureProxy::clearUniqueKey() { } #ifdef SK_DEBUG -void GrTextureProxy::validateLazyTexture(const GrTexture* texture) { - SkASSERT(!texture->asRenderTarget()); +void GrTextureProxy::validateLazySurface(const GrSurface* surface) { + SkASSERT(!surface->asRenderTarget()); + + // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version + SkASSERT(surface->asTexture()); + SkASSERT(surface->asTexture()->texturePriv().mipMapped() == this->mipMapped()); } #endif diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp index 843524c062..f1e47ec32b 100644 --- a/src/gpu/GrTextureRenderTargetProxy.cpp +++ b/src/gpu/GrTextureRenderTargetProxy.cpp @@ -9,6 +9,7 @@ #include "GrCaps.h" #include "GrTexture.h" +#include "GrTexturePriv.h" #include "GrRenderTarget.h" #include "GrSurfaceProxyPriv.h" @@ -104,10 +105,14 @@ sk_sp<GrSurface> GrTextureRenderTargetProxy::createSurface( } #ifdef SK_DEBUG -void GrTextureRenderTargetProxy::validateLazyTexture(const GrTexture* texture) { - SkASSERT(texture->asRenderTarget()); - SkASSERT(texture->asRenderTarget()->numStencilSamples() == this->numStencilSamples()); - SkASSERT(GrMipMapped::kNo == this->mipMapped()); +void GrTextureRenderTargetProxy::validateLazySurface(const GrSurface* surface) { + // Anything checked here should also be checking the GrTextureProxy version + SkASSERT(surface->asTexture()); + SkASSERT(surface->asTexture()->texturePriv().mipMapped() == this->mipMapped()); + + // Anything checked here should also be checking the GrRenderTargetProxy version + SkASSERT(surface->asRenderTarget()); + SkASSERT(surface->asRenderTarget()->numStencilSamples() == this->numStencilSamples()); } #endif diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h index 63cc4872b6..2947dd42c7 100644 --- a/src/gpu/GrTextureRenderTargetProxy.h +++ b/src/gpu/GrTextureRenderTargetProxy.h @@ -43,7 +43,7 @@ private: size_t onUninstantiatedGpuMemorySize() const override; - SkDEBUGCODE(void validateLazyTexture(const GrTexture*) override;) + SkDEBUGCODE(void validateLazySurface(const GrSurface*) override;) }; #ifdef SK_BUILD_FOR_WIN diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index b4a0341174..1aebb1271d 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -4469,6 +4469,9 @@ GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, i height = SkTMax(1, height / 2); } + // unbind the texture from the texture unit to avoid asserts + GL_CALL(BindTexture(info.fTarget, 0)); + return GrBackendTexture(w, h, mipMapped, info); } diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index ff66844da7..d7c1a46c58 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -167,9 +167,14 @@ bool SkSurface_Gpu::onCharacterize(SkSurfaceCharacterization* data) const { size_t maxResourceBytes; ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes); + bool mipmapped = rtc->asTextureProxy() ? GrMipMapped::kYes == rtc->asTextureProxy()->mipMapped() + : false; + data->set(ctx->threadSafeProxy(), maxResourceCount, maxResourceBytes, rtc->origin(), rtc->width(), rtc->height(), rtc->colorSpaceInfo().config(), rtc->fsaaType(), rtc->numStencilSamples(), + SkSurfaceCharacterization::Textureable(SkToBool(rtc->asTextureProxy())), + SkSurfaceCharacterization::MipMapped(mipmapped), rtc->colorSpaceInfo().refColorSpace(), this->props()); return true; @@ -185,6 +190,21 @@ bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& data) const { size_t maxResourceBytes; ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes); + if (data.isTextureable()) { + if (!rtc->asTextureProxy()) { + // If the characterization was textureable we require the replay dest to also be + // textureable. If the characterized surface wasn't textureable we allow the replay + // dest to be textureable. + return false; + } + + if (data.isMipMapped() && GrMipMapped::kNo == rtc->asTextureProxy()->mipMapped()) { + // Fail if the DDL's surface was mipmapped but the replay surface is not. + // Allow drawing to proceed if the DDL was not mipmapped but the replay surface is. + return false; + } + } + return data.contextInfo() && data.contextInfo()->matches(ctx) && data.cacheMaxResourceCount() <= maxResourceCount && data.cacheMaxResourceBytes() <= maxResourceBytes && |