diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index eda0a452a3..a032f693e7 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -136,9 +136,16 @@ sk_sp GrSurfaceProxy::MakeDeferred(const GrCaps& caps, SkBackingFit fit, SkBudgeted budgeted) { // TODO: share this testing code with check_texture_creation_params - if (SkBackingFit::kApprox == fit && GrPixelConfigIsCompressed(desc.fConfig)) { - // we don't allow scratch compressed textures - return nullptr; + if (GrPixelConfigIsCompressed(desc.fConfig)) { + if (SkBackingFit::kApprox == fit || kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { + // We don't allow scratch compressed textures and, apparently can't Y-flip compressed + // textures + return nullptr; + } + + if (!caps.npotTextureTileSupport() && (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight))) { + return nullptr; + } } if (!caps.isConfigTexturable(desc.fConfig)) { @@ -166,13 +173,16 @@ sk_sp GrSurfaceProxy::MakeDeferred(const GrCaps& caps, return nullptr; } + GrSurfaceDesc copyDesc = desc; + copyDesc.fSampleCnt = SkTMin(desc.fSampleCnt, caps.maxSampleCount()); + if (willBeRT) { // We know anything we instantiate later from this deferred path will be // both texturable and renderable - return sk_sp(new GrTextureRenderTargetProxy(caps, desc, fit, budgeted)); + return sk_sp(new GrTextureRenderTargetProxy(caps, copyDesc, fit, budgeted)); } - return sk_sp(new GrTextureProxy(desc, fit, budgeted, nullptr, 0)); + return sk_sp(new GrTextureProxy(copyDesc, fit, budgeted, nullptr, 0)); } sk_sp GrSurfaceProxy::MakeDeferred(const GrCaps& caps, diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp index 894c37eea3..f5a3a2c9c8 100644 --- a/tests/ProxyTest.cpp +++ b/tests/ProxyTest.cpp @@ -114,16 +114,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) { const GrGpuResource::UniqueID kInvalidResourceID = GrGpuResource::UniqueID::InvalidID(); + int attempt = 0; // useful for debugging + for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) { for (auto widthHeight : { 100, 128, 1048576 }) { - for (auto config : { kAlpha_8_GrPixelConfig, kRGBA_8888_GrPixelConfig }) { + for (auto config : { kAlpha_8_GrPixelConfig, kRGB_565_GrPixelConfig, + kETC1_GrPixelConfig, kRGBA_8888_GrPixelConfig }) { for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) { for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) { - for (auto numSamples : { 0, 4}) { - bool renderable = caps.isConfigRenderable(config, numSamples > 0) && - numSamples <= caps.maxColorSampleCount(); - bool allocable = widthHeight <= caps.maxTextureSize(); - + for (auto numSamples : { 0, 4, 16, 128 }) { GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fOrigin = origin; @@ -132,11 +131,18 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) { desc.fConfig = config; desc.fSampleCnt = numSamples; - if (renderable) { + { + sk_sp tex; + if (SkBackingFit::kApprox == fit) { + tex = sk_ref_sp(provider->createApproxTexture(desc)); + } else { + tex = sk_ref_sp(provider->createTexture(desc, budgeted)); + } + sk_sp sProxy(GrSurfaceProxy::MakeDeferred( caps, desc, fit, budgeted)); - REPORTER_ASSERT(reporter, allocable == SkToBool(sProxy)); + REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(sProxy)); if (sProxy) { REPORTER_ASSERT(reporter, sProxy->asRenderTargetProxy()); // This forces the proxy to compute and cache its @@ -150,33 +156,44 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) { widthHeight, widthHeight, config, kInvalidResourceID, budgeted); check_rendertarget(reporter, caps, provider, - sProxy->asRenderTargetProxy(), numSamples, + sProxy->asRenderTargetProxy(), + SkTMin(numSamples, caps.maxSampleCount()), fit, caps.maxWindowRectangles(), false); } } desc.fFlags = kNone_GrSurfaceFlags; - desc.fSampleCnt = 0; - sk_sp sProxy(GrSurfaceProxy::MakeDeferred(caps, - desc, - fit, - budgeted)); - REPORTER_ASSERT(reporter, allocable == SkToBool(sProxy)); - if (sProxy) { - // This forces the proxy to compute and cache its pre-instantiation - // size guess. Later, when it is actually instantiated, it checks - // that the instantiated size is <= to the pre-computation. - // If the proxy never computed its pre-instantiation size then the - // check is skipped. - sProxy->gpuMemorySize(); + { + sk_sp tex; + if (SkBackingFit::kApprox == fit) { + tex = sk_ref_sp(provider->createApproxTexture(desc)); + } else { + tex = sk_ref_sp(provider->createTexture(desc, budgeted)); + } - check_surface(reporter, sProxy.get(), origin, - widthHeight, widthHeight, config, - kInvalidResourceID, budgeted); - check_texture(reporter, provider, sProxy->asTextureProxy(), - fit, false); + sk_sp sProxy(GrSurfaceProxy::MakeDeferred(caps, + desc, + fit, + budgeted)); + REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(sProxy)); + if (sProxy) { + // This forces the proxy to compute and cache its pre-instantiation + // size guess. Later, when it is actually instantiated, it checks + // that the instantiated size is <= to the pre-computation. + // If the proxy never computed its pre-instantiation size then the + // check is skipped. + sProxy->gpuMemorySize(); + + check_surface(reporter, sProxy.get(), origin, + widthHeight, widthHeight, config, + kInvalidResourceID, budgeted); + check_texture(reporter, provider, sProxy->asTextureProxy(), + fit, false); + } } + + attempt++; } } }