diff options
-rw-r--r-- | gn/gpu.gni | 2 | ||||
-rw-r--r-- | gn/tests.gni | 1 | ||||
-rw-r--r-- | include/private/GrRenderTargetProxy.h | 5 | ||||
-rw-r--r-- | include/private/GrTextureProxy.h | 8 | ||||
-rw-r--r-- | include/private/GrTextureRenderTargetProxy.h | 46 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetProxy.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrTextureProxy.cpp | 13 | ||||
-rw-r--r-- | src/gpu/GrTextureRenderTargetProxy.cpp | 65 | ||||
-rw-r--r-- | tests/ProxyConversionTest.cpp | 158 | ||||
-rw-r--r-- | tests/ProxyTest.cpp | 10 | ||||
-rw-r--r-- | tests/SpecialImageTest.cpp | 4 |
11 files changed, 306 insertions, 16 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni index f300677de5..cc72f4bc17 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -62,6 +62,7 @@ skia_gpu_sources = [ "$_include/private/GrRenderTargetProxy.h", "$_include/private/GrSurfaceProxy.h", "$_include/private/GrTextureProxy.h", + "$_include/private/GrTextureRenderTargetProxy.h", "$_include/private/GrTextureStripAtlas.h", "$_src/gpu/GrAppliedClip.h", @@ -200,6 +201,7 @@ skia_gpu_sources = [ "$_src/gpu/GrTexturePriv.h", "$_src/gpu/GrTextureProvider.cpp", "$_src/gpu/GrTextureProxy.cpp", + "$_src/gpu/GrTextureRenderTargetProxy.cpp", "$_src/gpu/GrTextureToYUVPlanes.cpp", "$_src/gpu/GrTextureToYUVPlanes.h", "$_src/gpu/GrTextureAccess.cpp", diff --git a/gn/tests.gni b/gn/tests.gni index 6de39b0c11..135c3ce412 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -155,6 +155,7 @@ tests_sources = [ "$_tests/PointTest.cpp", "$_tests/PremulAlphaRoundTripTest.cpp", "$_tests/PrimitiveProcessorTest.cpp", + "$_tests/ProxyConversionTest.cpp", "$_tests/ProxyTest.cpp", "$_tests/QuickRejectTest.cpp", "$_tests/RandomTest.cpp", diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h index c124dddd79..3bad9df9e4 100644 --- a/include/private/GrRenderTargetProxy.h +++ b/include/private/GrRenderTargetProxy.h @@ -18,7 +18,7 @@ class GrTextureProvider; // required // Beware: the uniqueID of the RenderTargetProxy will usually be different than // the uniqueID of the RenderTarget it represents! -class GrRenderTargetProxy : public GrSurfaceProxy { +class GrRenderTargetProxy : virtual public GrSurfaceProxy { public: /** * The caller gets the creation ref. @@ -65,13 +65,14 @@ public: SkDEBUGCODE(void validate(GrContext*) const;) -private: +protected: // Deferred version GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, SkBackingFit, SkBudgeted); // Wrapped version GrRenderTargetProxy(sk_sp<GrRenderTarget> rt); +private: size_t onGpuMemorySize() const override; // For wrapped render targets the actual GrRenderTarget is stored in the GrIORefProxy class. diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h index b85302feea..e68ef8896a 100644 --- a/include/private/GrTextureProxy.h +++ b/include/private/GrTextureProxy.h @@ -11,14 +11,15 @@ #include "GrSurfaceProxy.h" #include "GrTexture.h" +class GrCaps; class GrTextureProvider; // This class delays the acquisition of textures until they are actually required -class GrTextureProxy : public GrSurfaceProxy { +class GrTextureProxy : virtual public GrSurfaceProxy { public: // TODO: need to refine ownership semantics of 'srcData' if we're in completely // deferred mode - static sk_sp<GrTextureProxy> Make(GrTextureProvider*, const GrSurfaceDesc&, + static sk_sp<GrTextureProxy> Make(const GrCaps&, GrTextureProvider*, const GrSurfaceDesc&, SkBackingFit, SkBudgeted, const void* srcData = nullptr, size_t rowBytes = 0); static sk_sp<GrTextureProxy> Make(sk_sp<GrTexture>); @@ -30,13 +31,14 @@ public: // Actually instantiate the backing texture, if necessary GrTexture* instantiate(GrTextureProvider*); -private: +protected: // Deferred version GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit, SkBudgeted, const void* srcData, size_t srcRowBytes); // Wrapped version GrTextureProxy(sk_sp<GrTexture> tex); +private: size_t onGpuMemorySize() const override; // For wrapped proxies the GrTexture pointer is stored in GrIORefProxy. diff --git a/include/private/GrTextureRenderTargetProxy.h b/include/private/GrTextureRenderTargetProxy.h new file mode 100644 index 0000000000..c4d190f94d --- /dev/null +++ b/include/private/GrTextureRenderTargetProxy.h @@ -0,0 +1,46 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrTextureRenderTargetProxy_DEFINED +#define GrTextureRenderTargetProxy_DEFINED + +#include "GrRenderTargetProxy.h" +#include "GrTextureProxy.h" + +#ifdef SK_BUILD_FOR_WIN +// Windows gives warnings about inheriting asTextureProxy/asRenderTargetProxy via dominance. +#pragma warning(push) +#pragma warning(disable: 4250) +#endif + +// This class delays the acquisition of RenderTargets that are also textures until +// they are actually required +// Beware: the uniqueID of the TextureRenderTargetProxy will usually be different than +// the uniqueID of the RenderTarget/Texture it represents! +class GrTextureRenderTargetProxy : public GrTextureProxy, public GrRenderTargetProxy { +public: + static sk_sp<GrTextureRenderTargetProxy> Make(const GrCaps&, + const GrSurfaceDesc&, + SkBackingFit, SkBudgeted); + static sk_sp<GrTextureRenderTargetProxy> Make(sk_sp<GrTexture>); + static sk_sp<GrTextureRenderTargetProxy> Make(sk_sp<GrRenderTarget>); + +private: + // Deferred version + GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, SkBackingFit, SkBudgeted); + + // Wrapped version + GrTextureRenderTargetProxy(sk_sp<GrRenderTarget> rt); + + size_t onGpuMemorySize() const override; +}; + +#ifdef SK_BUILD_FOR_WIN +#pragma warning(pop) +#endif + +#endif diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index eb750847d2..f428a0fb73 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -11,6 +11,7 @@ #include "GrRenderTargetOpList.h" #include "GrRenderTargetPriv.h" #include "GrTextureProvider.h" +#include "GrTextureRenderTargetProxy.h" // Deferred version // TODO: we can probably munge the 'desc' in both the wrapped and deferred @@ -89,10 +90,17 @@ sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(const GrCaps& caps, const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted) { - return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(caps, desc, fit, budgeted)); + // We know anything we instantiate later from this deferred path will be + // both texturable and renderable + return GrTextureRenderTargetProxy::Make(caps, desc, fit, budgeted); } sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(sk_sp<GrRenderTarget> rt) { + if (rt->asTexture()) { + return GrTextureRenderTargetProxy::Make(std::move(rt)); + } + + // Not texturable return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(rt)); } diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp index 0a7f767fa7..ca773b3eaf 100644 --- a/src/gpu/GrTextureProxy.cpp +++ b/src/gpu/GrTextureProxy.cpp @@ -8,6 +8,7 @@ #include "GrTextureProxy.h" #include "GrTextureProvider.h" +#include "GrTextureRenderTargetProxy.h" GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, SkBudgeted budgeted, const void* srcData, size_t /*rowBytes*/) @@ -49,7 +50,8 @@ size_t GrTextureProxy::onGpuMemorySize() const { return GrSurface::ComputeSize(fDesc, 1, kHasMipMaps); } -sk_sp<GrTextureProxy> GrTextureProxy::Make(GrTextureProvider* texProvider, +sk_sp<GrTextureProxy> GrTextureProxy::Make(const GrCaps& caps, + GrTextureProvider* texProvider, const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, @@ -61,9 +63,18 @@ sk_sp<GrTextureProxy> GrTextureProxy::Make(GrTextureProvider* texProvider, return GrTextureProxy::Make(std::move(tex)); } + if (desc.fFlags & kRenderTarget_GrSurfaceFlag) { + return GrTextureRenderTargetProxy::Make(caps, desc, fit, budgeted); + } + return sk_sp<GrTextureProxy>(new GrTextureProxy(desc, fit, budgeted, nullptr, 0)); } sk_sp<GrTextureProxy> GrTextureProxy::Make(sk_sp<GrTexture> tex) { + if (tex->asRenderTarget()) { + return GrTextureRenderTargetProxy::Make(std::move(tex)); + } + + // Not renderable return sk_sp<GrTextureProxy>(new GrTextureProxy(std::move(tex))); } diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp new file mode 100644 index 0000000000..74c3b71f2d --- /dev/null +++ b/src/gpu/GrTextureRenderTargetProxy.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrTextureRenderTargetProxy.h" + +// Deferred version +// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and +// GrRenderTargetProxy) so its constructor must be explicitly called. +GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps, + const GrSurfaceDesc& desc, + SkBackingFit fit, + SkBudgeted budgeted) + : GrSurfaceProxy(desc, fit, budgeted) + , GrTextureProxy(desc, fit, budgeted, nullptr, 0) // 4 now textures w/ data are always wrapped + , GrRenderTargetProxy(caps, desc, fit, budgeted) { +} + +// Wrapped version +// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and +// GrRenderTargetProxy) so its constructor must be explicitly called. +GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(sk_sp<GrRenderTarget> rt) + : GrSurfaceProxy(rt, SkBackingFit::kExact) + , GrTextureProxy(sk_ref_sp(rt->asTexture())) + , GrRenderTargetProxy(rt) { + SkASSERT(rt->asTexture()); +} + +size_t GrTextureRenderTargetProxy::onGpuMemorySize() const { + if (fTarget) { + return fTarget->gpuMemorySize(); + } + + // TODO: do we have enough information to improve this worst case estimate? + return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, true); +} + +sk_sp<GrTextureRenderTargetProxy> GrTextureRenderTargetProxy::Make(const GrCaps& caps, + const GrSurfaceDesc& desc, + SkBackingFit fit, + SkBudgeted budgeted) { + SkASSERT(desc.fFlags & kRenderTarget_GrSurfaceFlag); + + return sk_sp<GrTextureRenderTargetProxy>(new GrTextureRenderTargetProxy(caps, desc, + fit, budgeted)); +} + +sk_sp<GrTextureRenderTargetProxy> GrTextureRenderTargetProxy::Make(sk_sp<GrTexture> tex) { + SkASSERT(tex->asRenderTarget()); + + return sk_sp<GrTextureRenderTargetProxy>(new GrTextureRenderTargetProxy( + sk_ref_sp(tex->asRenderTarget()))); +} + +sk_sp<GrTextureRenderTargetProxy> GrTextureRenderTargetProxy::Make(sk_sp<GrRenderTarget> rt) { + SkASSERT(rt->asTexture()); + + return sk_sp<GrTextureRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(rt))); +} + + + diff --git a/tests/ProxyConversionTest.cpp b/tests/ProxyConversionTest.cpp new file mode 100644 index 0000000000..8a799f7859 --- /dev/null +++ b/tests/ProxyConversionTest.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// This is a GPU-backend specific test. + +#include "Test.h" + +#if SK_SUPPORT_GPU +#include "GrSurfaceProxy.h" +#include "GrTextureProxy.h" +#include "GrRenderTargetProxy.h" + +static sk_sp<GrRenderTargetProxy> make_wrapped_FBO0(GrTextureProvider* provider, + skiatest::Reporter* reporter, + const GrSurfaceDesc& desc) { + GrBackendRenderTargetDesc backendDesc; + backendDesc.fWidth = desc.fWidth; + backendDesc.fHeight = desc.fHeight; + backendDesc.fConfig = desc.fConfig; + backendDesc.fOrigin = desc.fOrigin; + backendDesc.fSampleCnt = desc.fSampleCnt; + backendDesc.fStencilBits = 8; + backendDesc.fRenderTargetHandle = 0; + + sk_sp<GrRenderTarget> defaultFBO(provider->wrapBackendRenderTarget(backendDesc)); + SkASSERT(!defaultFBO->asTexture()); + + return GrRenderTargetProxy::Make(std::move(defaultFBO)); +} + +static sk_sp<GrRenderTargetProxy> make_wrapped_offscreen_rt(GrTextureProvider* provider, + skiatest::Reporter* reporter, + const GrSurfaceDesc& desc, + SkBudgeted budgeted) { + SkASSERT(kRenderTarget_GrSurfaceFlag == desc.fFlags); + + sk_sp<GrTexture> tex(provider->createTexture(desc, budgeted)); + sk_sp<GrRenderTarget> rt(sk_ref_sp(tex->asRenderTarget())); + + return GrRenderTargetProxy::Make(std::move(rt)); +} + +static sk_sp<GrTextureProxy> make_wrapped_texture(GrTextureProvider* provider, + const GrSurfaceDesc& desc, + SkBudgeted budgeted) { + sk_sp<GrTexture> tex(provider->createTexture(desc, budgeted)); + + return GrTextureProxy::Make(std::move(tex)); +} + +// Test converting between RenderTargetProxies and TextureProxies for wrapped +// Proxies +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyConversionTest, reporter, ctxInfo) { + GrTextureProvider* provider = ctxInfo.grContext()->textureProvider(); + + GrSurfaceDesc desc; + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fWidth = 64; + desc.fHeight = 64; + desc.fConfig = kRGBA_8888_GrPixelConfig; + + if (kOpenGL_GrBackend == ctxInfo.backend()) { + // External on-screen render target. + sk_sp<GrRenderTargetProxy> rtProxy(make_wrapped_FBO0(provider, reporter, desc)); + + // RenderTarget-only + REPORTER_ASSERT(reporter, !rtProxy->asTextureProxy()); + REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy.get()); + } + + { + // Internal offscreen render target. + sk_sp<GrRenderTargetProxy> rtProxy(make_wrapped_offscreen_rt(provider, + reporter, desc, + SkBudgeted::kYes)); + + // Both RenderTarget and Texture + GrTextureProxy* tProxy = rtProxy->asTextureProxy(); + REPORTER_ASSERT(reporter, tProxy); + REPORTER_ASSERT(reporter, tProxy->asRenderTargetProxy() == rtProxy.get()); + REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy.get()); + } + + { + // Internal offscreen render target - but through GrTextureProxy + sk_sp<GrTextureProxy> tProxy(make_wrapped_texture(provider, desc, SkBudgeted::kYes)); + + // Both RenderTarget and Texture + GrRenderTargetProxy* rtProxy = tProxy->asRenderTargetProxy(); + REPORTER_ASSERT(reporter, rtProxy); + REPORTER_ASSERT(reporter, rtProxy->asTextureProxy() == tProxy.get()); + REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy.get()); + } + + { + desc.fFlags = kNone_GrSurfaceFlags; // force no-RT + + sk_sp<GrTextureProxy> tProxy(make_wrapped_texture(provider, desc, SkBudgeted::kYes)); + + // Texture-only + REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy.get()); + REPORTER_ASSERT(reporter, !tProxy->asRenderTargetProxy()); + } +} + +// Test converting between RenderTargetProxies and TextureProxies for deferred +// Proxies +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DefferredProxyConversionTest, reporter, ctxInfo) { + GrTextureProvider* provider = ctxInfo.grContext()->textureProvider(); + const GrCaps& caps = *ctxInfo.grContext()->caps(); + + GrSurfaceDesc desc; + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fWidth = 64; + desc.fHeight = 64; + desc.fConfig = kRGBA_8888_GrPixelConfig; + + { + sk_sp<GrRenderTargetProxy> rtProxy(GrRenderTargetProxy::Make(caps, desc, + SkBackingFit::kApprox, + SkBudgeted::kYes)); + + // Both RenderTarget and Texture + GrTextureProxy* tProxy = rtProxy->asTextureProxy(); + REPORTER_ASSERT(reporter, tProxy); + REPORTER_ASSERT(reporter, tProxy->asRenderTargetProxy() == rtProxy.get()); + REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy.get()); + } + + { + sk_sp<GrTextureProxy> tProxy(GrTextureProxy::Make(caps, provider, desc, + SkBackingFit::kApprox, + SkBudgeted::kYes)); + + // Both RenderTarget and Texture - but via GrTextureProxy + GrRenderTargetProxy* rtProxy = tProxy->asRenderTargetProxy(); + REPORTER_ASSERT(reporter, rtProxy); + REPORTER_ASSERT(reporter, rtProxy->asTextureProxy() == tProxy.get()); + REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy.get()); + } + + { + desc.fFlags = kNone_GrSurfaceFlags; // force no-RT + + sk_sp<GrTextureProxy> tProxy(GrTextureProxy::Make(caps, provider, desc, + SkBackingFit::kApprox, + SkBudgeted::kYes)); + + // Texture-only + REPORTER_ASSERT(reporter, tProxy->asTextureProxy() == tProxy.get()); + REPORTER_ASSERT(reporter, !tProxy->asRenderTargetProxy()); + } +} +#endif diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp index 6b7ab25a3f..270f7873ab 100644 --- a/tests/ProxyTest.cpp +++ b/tests/ProxyTest.cpp @@ -40,9 +40,6 @@ static void check_rendertarget(skiatest::Reporter* reporter, SkBackingFit fit) { REPORTER_ASSERT(reporter, rtProxy->numStencilSamples() == numSamples); - REPORTER_ASSERT(reporter, rtProxy->asTextureProxy() == nullptr); // for now - REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy); - GrRenderTarget* rt = rtProxy->instantiate(provider); REPORTER_ASSERT(reporter, rt); @@ -69,9 +66,6 @@ static void check_texture(skiatest::Reporter* reporter, GrTextureProvider* provider, GrTextureProxy* texProxy, SkBackingFit fit) { - REPORTER_ASSERT(reporter, texProxy->asTextureProxy() == texProxy); - REPORTER_ASSERT(reporter, texProxy->asRenderTargetProxy() == nullptr); // for now - GrTexture* tex = texProxy->instantiate(provider); REPORTER_ASSERT(reporter, tex); @@ -102,6 +96,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) { numSamples <= ctxInfo.grContext()->caps()->maxColorSampleCount(); GrSurfaceDesc desc; + desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fOrigin = origin; desc.fWidth = widthHeight; desc.fHeight = widthHeight; @@ -119,9 +114,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) { numSamples, fit); } + desc.fFlags = kNone_GrSurfaceFlags; desc.fSampleCnt = 0; - sk_sp<GrTextureProxy> texProxy(GrTextureProxy::Make(provider, + sk_sp<GrTextureProxy> texProxy(GrTextureProxy::Make(caps, provider, desc, fit, budgeted)); diff --git a/tests/SpecialImageTest.cpp b/tests/SpecialImageTest.cpp index 23e8d5b7e3..abadb303cb 100644 --- a/tests/SpecialImageTest.cpp +++ b/tests/SpecialImageTest.cpp @@ -301,8 +301,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_DeferredGpu, reporter, ctxInfo) desc.fWidth = kFullSize; desc.fHeight = kFullSize; - sk_sp<GrTextureProxy> proxy(GrTextureProxy::Make(context->textureProvider(), desc, - SkBackingFit::kExact, SkBudgeted::kNo, + sk_sp<GrTextureProxy> proxy(GrTextureProxy::Make(*context->caps(), context->textureProvider(), + desc, SkBackingFit::kExact, SkBudgeted::kNo, bm.getPixels(), 0)); if (!proxy) { return; |