aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/gpu.gni2
-rw-r--r--gn/tests.gni1
-rw-r--r--include/private/GrRenderTargetProxy.h5
-rw-r--r--include/private/GrTextureProxy.h8
-rw-r--r--include/private/GrTextureRenderTargetProxy.h46
-rw-r--r--src/gpu/GrRenderTargetProxy.cpp10
-rw-r--r--src/gpu/GrTextureProxy.cpp13
-rw-r--r--src/gpu/GrTextureRenderTargetProxy.cpp65
-rw-r--r--tests/ProxyConversionTest.cpp158
-rw-r--r--tests/ProxyTest.cpp10
-rw-r--r--tests/SpecialImageTest.cpp4
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;