diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp index 09298abd79..724bda5a9c 100644 --- a/src/gpu/GrProxyProvider.cpp +++ b/src/gpu/GrProxyProvider.cpp @@ -211,6 +211,16 @@ sk_sp GrProxyProvider::createTextureProxy(sk_sp srcImag return nullptr; } + GrPixelConfig config = SkImageInfo2GrPixelConfig(as_IB(srcImage)->onImageInfo(), + *this->caps()); + + if (SkToBool(flags & kRenderTarget_GrSurfaceFlag)) { + sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, config); + if (!sampleCnt) { + return nullptr; + } + } + GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone; if (SkToBool(flags & kRenderTarget_GrSurfaceFlag)) { if (fCaps->usesMixedSamples() && sampleCnt > 1) { @@ -227,7 +237,7 @@ sk_sp GrProxyProvider::createTextureProxy(sk_sp srcImag desc.fFlags = flags; desc.fOrigin = origin; desc.fSampleCnt = sampleCnt; - desc.fConfig = SkImageInfo2GrPixelConfig(as_IB(srcImage)->onImageInfo(), *this->caps()); + desc.fConfig = config; sk_sp proxy = this->createLazyProxy( [desc, budgeted, srcImage, fit] @@ -451,6 +461,9 @@ sk_sp GrProxyProvider::createWrappedTextureProxy(const GrBackend } sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config()); + if (!sampleCnt) { + return nullptr; + } GrSurfaceDesc desc; desc.fOrigin = origin; @@ -549,21 +562,63 @@ sk_sp GrProxyProvider::createWrappedRenderTargetProxy( return proxy; } -sk_sp GrProxyProvider::createWrappedRenderTargetProxy(const GrBackendTexture& tex, - GrSurfaceOrigin origin, - int sampleCnt) { +sk_sp GrProxyProvider::createWrappedRenderTargetProxy( + const GrBackendTexture& backendTex, + GrSurfaceOrigin origin, + int sampleCnt) { if (this->isAbandoned()) { return nullptr; } - sk_sp rt(fResourceProvider->wrapBackendTextureAsRenderTarget(tex, sampleCnt)); - if (!rt) { + sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config()); + if (!sampleCnt) { return nullptr; } - SkASSERT(!rt->asTexture()); // Strictly a GrRenderTarget - SkASSERT(!rt->getUniqueKey().isValid()); - return sk_sp(new GrRenderTargetProxy(std::move(rt), origin)); + GrSurfaceDesc desc; + desc.fOrigin = origin; + desc.fWidth = backendTex.width(); + desc.fHeight = backendTex.height(); + desc.fConfig = backendTex.config(); + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fSampleCnt = sampleCnt; + + GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone; + if (fCaps->usesMixedSamples() && sampleCnt > 1) { + renderTargetFlags |= GrRenderTargetFlags::kMixedSampled; + } + if (fCaps->maxWindowRectangles() > 0) { + renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport; + } + + sk_sp proxy = this->createLazyRenderTargetProxy( + [backendTex, sampleCnt] (GrResourceProvider* resourceProvider) { + if (!resourceProvider) { + return sk_sp(); + } + + sk_sp rt = resourceProvider->wrapBackendTextureAsRenderTarget( + backendTex, sampleCnt); + if (!rt) { + return sk_sp(); + } + SkASSERT(!rt->asTexture()); // A GrRenderTarget that's not textureable + SkASSERT(!rt->getUniqueKey().isValid()); + // Make sure we match how we created the proxy with SkBudgeted::kNo + SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted()); + + return rt; + }, desc, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo, SkBackingFit::kExact, + SkBudgeted::kNo); + + if (fResourceProvider) { + // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however, + // we're better off instantiating the proxy immediately here. + if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { + return nullptr; + } + } + return proxy; } sk_sp GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback, diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp index 3a46438e79..20d721be86 100644 --- a/tests/ProxyTest.cpp +++ b/tests/ProxyTest.cpp @@ -206,6 +206,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { } // External on-screen render target. + // Tests createWrappedRenderTargetProxy with a GrBackendRenderTarget { GrGLFramebufferInfo fboInfo; fboInfo.fFBOID = 0; @@ -222,16 +223,17 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { supportedNumSamples, SkBackingFit::kExact, 0); } + // Tests createWrappedRenderTargetProxy with a GrBackendTexture { GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(nullptr, kWidthHeight, kWidthHeight, colorType, true, GrMipMapped::kNo); - sk_sp sProxy = - proxyProvider->createWrappedTextureProxy(backendTex, origin, - supportedNumSamples); + proxyProvider->createWrappedRenderTargetProxy(backendTex, origin, + supportedNumSamples); if (!sProxy) { + gpu->deleteTestingOnlyBackendTexture(&backendTex); continue; // This can fail on Mesa } @@ -246,6 +248,33 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { gpu->deleteTestingOnlyBackendTexture(&backendTex); } + // Tests createWrappedTextureProxy that is only renderable + { + GrBackendTexture backendTex = + gpu->createTestingOnlyBackendTexture(nullptr, kWidthHeight, + kWidthHeight, colorType, true, + GrMipMapped::kNo); + + sk_sp sProxy = + proxyProvider->createWrappedTextureProxy(backendTex, origin, + supportedNumSamples); + if (!sProxy) { + gpu->deleteTestingOnlyBackendTexture(&backendTex); + continue; // This can fail on Mesa + } + + check_surface(reporter, sProxy.get(), origin, + kWidthHeight, kWidthHeight, + backendTex.testingOnly_getPixelConfig(), SkBudgeted::kNo); + check_rendertarget(reporter, caps, resourceProvider, + sProxy->asRenderTargetProxy(), + supportedNumSamples, SkBackingFit::kExact, + caps.maxWindowRectangles()); + + gpu->deleteTestingOnlyBackendTexture(&backendTex); + } + + // Tests createWrappedTextureProxy that is only textureable { // Internal offscreen texture GrBackendTexture backendTex = @@ -258,6 +287,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) { kBorrow_GrWrapOwnership, nullptr, nullptr); if (!sProxy) { + gpu->deleteTestingOnlyBackendTexture(&backendTex); continue; }