aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2016-05-03 08:47:00 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-03 08:47:01 -0700
commit92605b35efa0155c44d24bd8415b4cc1db8831db (patch)
tree02df8d88f0f90cdab30ef095629d13d6fd45ea46
parent871a0484305e9c051e2d78b62e1f2a5fa4bdb3a4 (diff)
Add Gr*Proxy classes
-rw-r--r--gyp/gpu.gypi8
-rw-r--r--include/core/SkTypes.h9
-rw-r--r--include/gpu/GrContext.h7
-rw-r--r--include/gpu/GrRenderTarget.h3
-rw-r--r--include/private/GrRenderTargetProxy.h123
-rw-r--r--include/private/GrSurfaceProxy.h72
-rw-r--r--include/private/GrTextureProxy.h49
-rw-r--r--src/core/SkImageFilter.cpp2
-rw-r--r--src/effects/SkAlphaThresholdFilter.cpp2
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp2
-rw-r--r--src/effects/SkLightingImageFilter.cpp2
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp4
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp2
-rw-r--r--src/gpu/GrBlurUtils.cpp2
-rw-r--r--src/gpu/GrContext.cpp4
-rw-r--r--src/gpu/GrRenderTarget.cpp8
-rw-r--r--src/gpu/GrRenderTargetPriv.h2
-rw-r--r--src/gpu/GrRenderTargetProxy.cpp77
-rw-r--r--src/gpu/GrSurfaceProxy.cpp19
-rw-r--r--src/gpu/GrTextureProxy.cpp44
-rw-r--r--src/gpu/gl/GrGLGpu.cpp6
-rw-r--r--src/image/SkImage_Gpu.cpp2
-rw-r--r--tests/ClearTest.cpp2
-rw-r--r--tests/PrimitiveProcessorTest.cpp2
-rw-r--r--tests/ProxyTest.cpp172
25 files changed, 602 insertions, 23 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 69f286d239..5919e24b59 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -61,6 +61,9 @@
# Private includes
'<(skia_include_path)/private/GrAuditTrail.h',
'<(skia_include_path)/private/GrSingleOwner.h',
+ '<(skia_include_path)/private/GrRenderTargetProxy.h',
+ '<(skia_include_path)/private/GrSurfaceProxy.h',
+ '<(skia_include_path)/private/GrTextureProxy.h',
'<(skia_src_path)/gpu/GrAuditTrail.cpp',
'<(skia_src_path)/gpu/GrAutoLocaleSetter.h',
@@ -157,6 +160,7 @@
'<(skia_src_path)/gpu/GrRectanizer_skyline.h',
'<(skia_src_path)/gpu/GrRenderTarget.cpp',
'<(skia_src_path)/gpu/GrRenderTargetPriv.h',
+ '<(skia_src_path)/gpu/GrRenderTargetProxy.cpp',
'<(skia_src_path)/gpu/GrReducedClip.cpp',
'<(skia_src_path)/gpu/GrReducedClip.h',
'<(skia_src_path)/gpu/GrResourceCache.cpp',
@@ -185,12 +189,14 @@
'<(skia_src_path)/gpu/GrSoftwarePathRenderer.h',
'<(skia_src_path)/gpu/GrSurfacePriv.h',
'<(skia_src_path)/gpu/GrSurface.cpp',
+ '<(skia_src_path)/gpu/GrSurfaceProxy.cpp',
'<(skia_src_path)/gpu/GrSwizzle.h',
'<(skia_src_path)/gpu/GrTexture.cpp',
'<(skia_src_path)/gpu/GrTextureParamsAdjuster.h',
'<(skia_src_path)/gpu/GrTextureParamsAdjuster.cpp',
- '<(skia_src_path)/gpu/GrTextureProvider.cpp',
'<(skia_src_path)/gpu/GrTexturePriv.h',
+ '<(skia_src_path)/gpu/GrTextureProvider.cpp',
+ '<(skia_src_path)/gpu/GrTextureProxy.cpp',
'<(skia_src_path)/gpu/GrTextureToYUVPlanes.cpp',
'<(skia_src_path)/gpu/GrTextureToYUVPlanes.h',
'<(skia_src_path)/gpu/GrTextureAccess.cpp',
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index f9d0c533d3..f99bb01949 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -442,6 +442,15 @@ enum class SkBudgeted : bool {
kYes = true
};
+/**
+ * Indicates whether a backing store needs to be an exact match or can be larger
+ * than is strictly necessary
+ */
+enum class SkBackingFit {
+ kApprox,
+ kExact
+};
+
///////////////////////////////////////////////////////////////////////////////
/** Use to combine multiple bits in a bitmask in a type safe way.
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index cb407aa5bf..6f5ca981e5 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -194,16 +194,11 @@ public:
*/
sk_sp<GrDrawContext> drawContext(sk_sp<GrRenderTarget> rt, const SkSurfaceProps* = nullptr);
- enum BackingFit {
- kTight_BackingFit,
- kLoose_BackingFit
- };
-
/**
* Create both a GrRenderTarget and a matching GrDrawContext to wrap it.
* The created GrRenderTarget will always be budgeted.
*/
- sk_sp<GrDrawContext> newDrawContext(BackingFit fit,
+ sk_sp<GrDrawContext> newDrawContext(SkBackingFit fit,
int width, int height,
GrPixelConfig config,
int sampleCnt = 0,
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index eb9f142211..ff75af37e8 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -11,6 +11,7 @@
#include "GrSurface.h"
#include "SkRect.h"
+class GrCaps;
class GrDrawTarget;
class GrStencilAttachment;
class GrRenderTargetPriv;
@@ -155,6 +156,8 @@ public:
void setLastDrawTarget(GrDrawTarget* dt);
GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
+ static SampleConfig ComputeSampleConfig(const GrCaps& caps, int sampleCnt);
+
protected:
GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc,
SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr)
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
new file mode 100644
index 0000000000..287aa017f0
--- /dev/null
+++ b/include/private/GrRenderTargetProxy.h
@@ -0,0 +1,123 @@
+/*
+ * 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 GrRenderTargetProxy_DEFINED
+#define GrRenderTargetProxy_DEFINED
+
+#include "GrRenderTarget.h"
+#include "GrSurfaceProxy.h"
+#include "GrTypes.h"
+
+class GrTextureProvider;
+
+// This class delays the acquisition of RenderTargets until they are actually
+// required
+// Beware: the uniqueID of the RenderTargetProxy will usually be different than
+// the uniqueID of the RenderTarget it represents!
+class GrRenderTargetProxy : public GrSurfaceProxy {
+public:
+ /**
+ * The caller gets the creation ref.
+ */
+ static sk_sp<GrRenderTargetProxy> Make(const GrCaps&, const GrSurfaceDesc&,
+ SkBackingFit, SkBudgeted);
+ static sk_sp<GrRenderTargetProxy> Make(sk_sp<GrRenderTarget> rt);
+
+ ~GrRenderTargetProxy() override;
+
+ // TODO: add asTextureProxy variants
+ GrRenderTargetProxy* asRenderTargetProxy() override { return this; }
+ const GrRenderTargetProxy* asRenderTargetProxy() const override { return this; }
+
+ // Actually instantiate the backing rendertarget, if necessary.
+ GrRenderTarget* instantiate(GrTextureProvider* texProvider);
+
+ /**
+ * @return true if the surface is multisampled in all buffers,
+ * false otherwise
+ */
+ bool isUnifiedMultisampled() const {
+ if (fSampleConfig != GrRenderTarget::kUnified_SampleConfig) {
+ return false;
+ }
+ return 0 != fDesc.fSampleCnt;
+ }
+
+ /**
+ * @return true if the surface is multisampled in the stencil buffer,
+ * false otherwise
+ */
+ bool isStencilBufferMultisampled() const {
+ return 0 != fDesc.fSampleCnt;
+ }
+
+ /**
+ * @return the number of color samples-per-pixel, or zero if non-MSAA or
+ * multisampled in the stencil buffer only.
+ */
+ int numColorSamples() const {
+ if (fSampleConfig == GrRenderTarget::kUnified_SampleConfig) {
+ return fDesc.fSampleCnt;
+ }
+ return 0;
+ }
+
+ /**
+ * @return the number of stencil samples-per-pixel, or zero if non-MSAA.
+ */
+ int numStencilSamples() const {
+ return fDesc.fSampleCnt;
+ }
+
+ /**
+ * @return true if the surface is mixed sampled, false otherwise.
+ */
+ bool hasMixedSamples() const {
+ SkASSERT(GrRenderTarget::kStencil_SampleConfig != fSampleConfig ||
+ this->isStencilBufferMultisampled());
+ return GrRenderTarget::kStencil_SampleConfig == fSampleConfig;
+ }
+
+ void setLastDrawTarget(GrDrawTarget* dt);
+ GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
+
+private:
+ // TODO: we can probably munge the 'desc' in both the wrapped and deferred
+ // cases to make the sampleConfig/numSamples stuff more rational.
+ GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
+ SkBackingFit fit, SkBudgeted budgeted)
+ : INHERITED(desc, fit, budgeted)
+ , fTarget(nullptr)
+ , fSampleConfig(GrRenderTarget::ComputeSampleConfig(caps, desc.fSampleCnt))
+ , fLastDrawTarget(nullptr) {
+ }
+
+ // Wrapped version
+ GrRenderTargetProxy(sk_sp<GrRenderTarget> rt);
+
+ // For wrapped render targets we store it here.
+ // For deferred proxies we will fill this in when we need to instantiate the deferred resource
+ sk_sp<GrRenderTarget> fTarget;
+
+ // The sample config doesn't usually get computed until the render target is instantiated but
+ // the render target proxy may need to answer queries about it before then. For this reason
+ // we precompute it in the deferred case. In the wrapped case we just copy the wrapped
+ // rendertarget's info here.
+ GrRenderTarget::SampleConfig fSampleConfig;
+
+ // The last drawTarget that wrote to or is currently going to write to this renderTarget
+ // The drawTarget can be closed (e.g., no draw context is currently bound
+ // to this renderTarget).
+ // This back-pointer is required so that we can add a dependancy between
+ // the drawTarget used to create the current contents of this renderTarget
+ // and the drawTarget of a destination renderTarget to which this one is being drawn.
+ GrDrawTarget* fLastDrawTarget;
+
+ typedef GrSurfaceProxy INHERITED;
+};
+
+#endif
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
new file mode 100644
index 0000000000..63e646b7d3
--- /dev/null
+++ b/include/private/GrSurfaceProxy.h
@@ -0,0 +1,72 @@
+/*
+ * 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 GrSurfaceProxy_DEFINED
+#define GrSurfaceProxy_DEFINED
+
+#include "GrGpuResource.h"
+
+class GrTextureProxy;
+class GrRenderTargetProxy;
+
+class GrSurfaceProxy : public GrIORef<GrSurfaceProxy> {
+public:
+ const GrSurfaceDesc& desc() const { return fDesc; }
+
+ GrSurfaceOrigin origin() const {
+ SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin ||
+ kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
+ return fDesc.fOrigin;
+ }
+ int width() const { return fDesc.fWidth; }
+ int height() const { return fDesc.fWidth; }
+ GrPixelConfig config() const { return fDesc.fConfig; }
+
+ uint32_t uniqueID() const { return fUniqueID; }
+
+ /**
+ * @return the texture proxy associated with the surface proxy, may be NULL.
+ */
+ virtual GrTextureProxy* asTextureProxy() { return nullptr; }
+ virtual const GrTextureProxy* asTextureProxy() const { return nullptr; }
+
+ /**
+ * @return the render target proxy associated with the surface proxy, may be NULL.
+ */
+ virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; }
+ virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; }
+
+protected:
+ GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted)
+ : fDesc(desc)
+ , fFit(fit)
+ , fBudgeted(budgeted)
+ , fUniqueID(CreateUniqueID()) {
+ }
+
+ virtual ~GrSurfaceProxy() {}
+
+ // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource.
+ const GrSurfaceDesc fDesc;
+ const SkBackingFit fFit; // always exact for wrapped resources
+ const SkBudgeted fBudgeted; // set from the backing resource for wrapped resources
+ const uint32_t fUniqueID;
+
+private:
+ static uint32_t CreateUniqueID();
+
+ // See comment in GrGpuResource.h.
+ void notifyAllCntsAreZero(CntType) const {}
+ bool notifyRefCountIsZero() const { return false; }
+
+ typedef GrIORef<GrSurfaceProxy> INHERITED;
+
+ // to access notifyAllCntsAreZero and notifyRefCntIsZero.
+ friend class GrIORef<GrSurfaceProxy>;
+};
+
+#endif
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
new file mode 100644
index 0000000000..eb82ca7581
--- /dev/null
+++ b/include/private/GrTextureProxy.h
@@ -0,0 +1,49 @@
+/*
+ * 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 GrTextureProxy_DEFINED
+#define GrTextureProxy_DEFINED
+
+#include "GrSurfaceProxy.h"
+#include "GrTexture.h"
+
+class GrTextureProvider;
+
+// This class delays the acquisition of textures until they are actually required
+class GrTextureProxy : public GrSurfaceProxy {
+public:
+ // TODO: need to refine ownership semantics of 'srcData' if we're in completely
+ // deferred mode
+ static sk_sp<GrTextureProxy> Make(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
+ const void* srcData = nullptr, size_t rowBytes = 0);
+ static sk_sp<GrTextureProxy> Make(sk_sp<GrTexture>);
+
+ // TODO: add asRenderTargetProxy variants
+ GrTextureProxy* asTextureProxy() override { return this; }
+ const GrTextureProxy* asTextureProxy() const override { return this; }
+
+ // Actually instantiate the backing texture, if necessary
+ GrTexture* instantiate(GrTextureProvider* texProvider);
+
+private:
+ GrTextureProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted,
+ const void* /*srcData*/, size_t /*rowBytes*/)
+ : INHERITED(desc, fit, budgeted) {
+ // TODO: Handle 'srcData' here
+ }
+
+ // Wrapped version
+ GrTextureProxy(sk_sp<GrTexture> tex);
+
+ // For wrapped textures we store it here.
+ // For deferred proxies we will fill this in when we need to instantiate the deferred resource
+ sk_sp<GrTexture> fTexture;
+
+ typedef GrSurfaceProxy INHERITED;
+};
+
+#endif
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index d0042527e4..899083dbb4 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -280,7 +280,7 @@ sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context,
paint.addColorFragmentProcessor(fp.get());
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
- sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
bounds.width(), bounds.height(),
kRGBA_8888_GrPixelConfig));
if (!drawContext) {
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index cec45ba911..a4876c8008 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -102,7 +102,7 @@ sk_sp<GrTexture> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* contex
config = kRGBA_8888_GrPixelConfig;
}
- sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
bounds.width(), bounds.height(),
config));
if (!drawContext) {
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index cf9e2c3c9f..befda79332 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -335,7 +335,7 @@ sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
- sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
bounds.width(), bounds.height(),
kSkia8888_GrPixelConfig));
if (!drawContext) {
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 6efb0f6c4e..d9b29363ed 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -407,7 +407,7 @@ sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(SkSpecialIma
sk_sp<GrTexture> inputTexture(input->asTextureRef(context));
SkASSERT(inputTexture);
- sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
offsetBounds.width(),
offsetBounds.height(),
kRGBA_8888_GrPixelConfig));
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 2a0f078c05..121a7fdc01 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -487,7 +487,7 @@ static sk_sp<SkSpecialImage> apply_morphology(GrContext* context,
SkASSERT(radius.width() > 0 || radius.height() > 0);
if (radius.fWidth > 0) {
- sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kApprox,
rect.width(), rect.height(),
kSkia8888_GrPixelConfig));
if (!dstDrawContext) {
@@ -508,7 +508,7 @@ static sk_sp<SkSpecialImage> apply_morphology(GrContext* context,
srcRect = dstRect;
}
if (radius.fHeight > 0) {
- sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kApprox,
rect.width(), rect.height(),
kSkia8888_GrPixelConfig));
if (!dstDrawContext) {
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index b1e19bbec3..99ce24f129 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -238,7 +238,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter::filterImageGPU(SkSpecialImage* sour
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
- sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
bounds.width(), bounds.height(),
kSkia8888_GrPixelConfig));
if (!drawContext) {
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index f95bdfff02..59a3dfcd08 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -116,7 +116,7 @@ static sk_sp<GrTexture> create_mask_GPU(GrContext* context,
config = kAlpha_8_GrPixelConfig;
}
- sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
SkScalarCeilToInt(maskRect->width()),
SkScalarCeilToInt(maskRect->height()),
config,
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index a186bd87bc..31845f9d6d 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -615,7 +615,7 @@ sk_sp<GrDrawContext> GrContext::drawContext(sk_sp<GrRenderTarget> rt,
return fDrawingManager->drawContext(std::move(rt), surfaceProps);
}
-sk_sp<GrDrawContext> GrContext::newDrawContext(BackingFit fit,
+sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit,
int width, int height,
GrPixelConfig config,
int sampleCnt,
@@ -629,7 +629,7 @@ sk_sp<GrDrawContext> GrContext::newDrawContext(BackingFit fit,
desc.fSampleCnt = sampleCnt;
sk_sp<GrTexture> tex;
- if (kTight_BackingFit == fit) {
+ if (SkBackingFit::kExact == fit) {
tex.reset(this->textureProvider()->createTexture(desc, SkBudgeted::kYes));
} else {
tex.reset(this->textureProvider()->createApproxTexture(desc));
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index a6736403fc..ebbfae9b95 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -109,3 +109,11 @@ const GrGpu::MultisampleSpecs&
GrRenderTargetPriv::getMultisampleSpecs(const GrStencilSettings& stencil) const {
return fRenderTarget->getGpu()->getMultisampleSpecs(fRenderTarget, stencil);
}
+
+GrRenderTarget::SampleConfig GrRenderTarget::ComputeSampleConfig(const GrCaps& caps,
+ int sampleCnt) {
+ return (caps.usesMixedSamples() && sampleCnt > 0)
+ ? GrRenderTarget::kStencil_SampleConfig
+ : GrRenderTarget::kUnified_SampleConfig;
+}
+
diff --git a/src/gpu/GrRenderTargetPriv.h b/src/gpu/GrRenderTargetPriv.h
index e64ed57141..24b7e8838a 100644
--- a/src/gpu/GrRenderTargetPriv.h
+++ b/src/gpu/GrRenderTargetPriv.h
@@ -32,6 +32,8 @@ public:
const GrGpu::MultisampleSpecs& getMultisampleSpecs(const GrStencilSettings& stencil) const;
+ GrRenderTarget::SampleConfig sampleConfig() const { return fRenderTarget->fSampleConfig; }
+
private:
explicit GrRenderTargetPriv(GrRenderTarget* renderTarget) : fRenderTarget(renderTarget) {}
GrRenderTargetPriv(const GrRenderTargetPriv&) {} // unimpl
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
new file mode 100644
index 0000000000..8d821c3c1d
--- /dev/null
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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 "GrRenderTargetProxy.h"
+
+#include "GrDrawTarget.h"
+#include "GrGpuResourcePriv.h"
+#include "GrRenderTargetPriv.h"
+
+GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrRenderTarget> rt)
+ : INHERITED(rt->desc(), SkBackingFit::kExact, rt->resourcePriv().isBudgeted())
+ , fTarget(std::move(rt))
+ , fSampleConfig(fTarget->renderTargetPriv().sampleConfig())
+ , fLastDrawTarget(nullptr) {
+}
+
+GrRenderTargetProxy::~GrRenderTargetProxy() {
+ if (fLastDrawTarget) {
+ fLastDrawTarget->clearRT();
+ }
+ SkSafeUnref(fLastDrawTarget);
+}
+
+GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider) {
+ if (fTarget) {
+ return fTarget.get();
+ }
+
+ // TODO: it would be nice to not have to copy the desc here
+ GrSurfaceDesc desc = fDesc;
+ desc.fFlags |= GrSurfaceFlags::kRenderTarget_GrSurfaceFlag;
+
+ sk_sp<GrTexture> tex;
+ if (SkBackingFit::kApprox == fFit) {
+ tex.reset(texProvider->createApproxTexture(desc));
+ } else {
+ tex.reset(texProvider->createTexture(desc, fBudgeted));
+ }
+ if (!tex || !tex->asRenderTarget()) {
+ return nullptr;
+ }
+
+ fTarget.reset(tex->asRenderTarget());
+
+ // Check that our a priori computation matched the ultimate reality
+ SkASSERT(fSampleConfig == fTarget->renderTargetPriv().sampleConfig());
+
+ return fTarget.get();
+}
+
+void GrRenderTargetProxy::setLastDrawTarget(GrDrawTarget* dt) {
+ if (fLastDrawTarget) {
+ // The non-MDB world never closes so we can't check this condition
+#ifdef ENABLE_MDB
+ SkASSERT(fLastDrawTarget->isClosed());
+#endif
+ fLastDrawTarget->clearRT();
+ }
+
+ SkRefCnt_SafeAssign(fLastDrawTarget, dt);
+}
+
+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));
+}
+
+sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(sk_sp<GrRenderTarget> rt) {
+ return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(rt));
+}
+
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
new file mode 100644
index 0000000000..b8b5d7510d
--- /dev/null
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -0,0 +1,19 @@
+/*
+ * 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 "GrSurfaceProxy.h"
+
+#include "SkAtomics.h"
+
+uint32_t GrSurfaceProxy::CreateUniqueID() {
+ static int32_t gUniqueID = SK_InvalidUniqueID;
+ uint32_t id;
+ do {
+ id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
+ } while (id == SK_InvalidUniqueID);
+ return id;
+}
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
new file mode 100644
index 0000000000..09c22e37b0
--- /dev/null
+++ b/src/gpu/GrTextureProxy.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 "GrTextureProxy.h"
+
+#include "GrTextureProvider.h"
+#include "GrGpuResourcePriv.h"
+
+GrTextureProxy::GrTextureProxy(sk_sp<GrTexture> tex)
+ : INHERITED(tex->desc(), SkBackingFit::kExact, tex->resourcePriv().isBudgeted())
+ , fTexture(std::move(tex)) {
+}
+
+GrTexture* GrTextureProxy::instantiate(GrTextureProvider* texProvider) {
+ if (fTexture) {
+ return fTexture.get();
+ }
+
+ if (SkBackingFit::kApprox == fFit) {
+ fTexture.reset(texProvider->createApproxTexture(fDesc));
+ } else {
+ fTexture.reset(texProvider->createTexture(fDesc, fBudgeted));
+ }
+
+ return fTexture.get();
+}
+
+sk_sp<GrTextureProxy> GrTextureProxy::Make(const GrSurfaceDesc& desc,
+ SkBackingFit fit,
+ SkBudgeted budgeted,
+ const void* srcData,
+ size_t rowBytes) {
+ // TODO: handle 'srcData' (we could use the wrapped version if there is data)
+ SkASSERT(!srcData && !rowBytes);
+ return sk_sp<GrTextureProxy>(new GrTextureProxy(desc, fit, budgeted, srcData, rowBytes));
+}
+
+sk_sp<GrTextureProxy> GrTextureProxy::Make(sk_sp<GrTexture> tex) {
+ return sk_sp<GrTextureProxy>(new GrTextureProxy(tex));
+}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 9d2984f186..027d9527c0 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1474,9 +1474,9 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
idDesc->fRTFBOID = 0;
idDesc->fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
idDesc->fTexFBOID = 0;
- idDesc->fSampleConfig = (GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType() &&
- desc.fSampleCnt > 0) ? GrRenderTarget::kStencil_SampleConfig :
- GrRenderTarget::kUnified_SampleConfig;
+ SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) ==
+ this->caps()->usesMixedSamples());
+ idDesc->fSampleConfig = GrRenderTarget::ComputeSampleConfig(*this->caps(), desc.fSampleCnt);
GrGLenum status;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index eea7e2c040..339dee7a5c 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -253,7 +253,7 @@ sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace
const int height = yuvSizes[0].fHeight;
// Needs to be a render target in order to draw to it for the yuv->rgb conversion.
- sk_sp<GrDrawContext> drawContext(ctx->newDrawContext(GrContext::kTight_BackingFit,
+ sk_sp<GrDrawContext> drawContext(ctx->newDrawContext(SkBackingFit::kExact,
width, height,
kRGBA_8888_GrPixelConfig,
0,
diff --git a/tests/ClearTest.cpp b/tests/ClearTest.cpp
index 7a533ba19c..d227cb8073 100644
--- a/tests/ClearTest.cpp
+++ b/tests/ClearTest.cpp
@@ -45,7 +45,7 @@ static bool reset_dc(sk_sp<GrDrawContext>* dc, GrContext* context, int w, int h)
}
context->freeGpuResources();
- *dc = context->newDrawContext(GrContext::kTight_BackingFit, w, h, kRGBA_8888_GrPixelConfig);
+ *dc = context->newDrawContext(SkBackingFit::kExact, w, h, kRGBA_8888_GrPixelConfig);
SkASSERT((*dc)->accessRenderTarget()->getUniqueID() != oldID);
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
index b1157a33a9..a82237d9f8 100644
--- a/tests/PrimitiveProcessorTest.cpp
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -104,7 +104,7 @@ private:
DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(VertexAttributeCount, reporter, ctxInfo) {
GrContext* context = ctxInfo.fGrContext;
- sk_sp<GrDrawContext> dc(context->newDrawContext(GrContext::kLoose_BackingFit,
+ sk_sp<GrDrawContext> dc(context->newDrawContext(SkBackingFit::kApprox,
1, 1, kRGBA_8888_GrPixelConfig));
if (!dc) {
ERRORF(reporter, "Could not create draw context.");
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
new file mode 100644
index 0000000000..68fc1f142e
--- /dev/null
+++ b/tests/ProxyTest.cpp
@@ -0,0 +1,172 @@
+/*
+ * 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 void check_surface(skiatest::Reporter* reporter,
+ GrSurfaceProxy* proxy,
+ GrSurfaceOrigin origin,
+ int width, int height,
+ GrPixelConfig config) {
+ REPORTER_ASSERT(reporter, proxy->origin() == origin);
+ REPORTER_ASSERT(reporter, proxy->width() == width);
+ REPORTER_ASSERT(reporter, proxy->height() == height);
+ REPORTER_ASSERT(reporter, proxy->config() == config);
+}
+
+static void check_rendertarget(skiatest::Reporter* reporter,
+ GrTextureProvider* provider,
+ GrRenderTargetProxy* rtProxy,
+ SkBackingFit fit) {
+ REPORTER_ASSERT(reporter, rtProxy->asTextureProxy() == nullptr); // for now
+ REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy);
+
+ GrRenderTarget* rt = rtProxy->instantiate(provider);
+ REPORTER_ASSERT(reporter, rt);
+
+ REPORTER_ASSERT(reporter, rt->origin() == rtProxy->origin());
+ if (SkBackingFit::kExact == fit) {
+ REPORTER_ASSERT(reporter, rt->width() == rtProxy->width());
+ REPORTER_ASSERT(reporter, rt->height() == rtProxy->height());
+ } else {
+ REPORTER_ASSERT(reporter, rt->width() >= rtProxy->width());
+ REPORTER_ASSERT(reporter, rt->height() >= rtProxy->height());
+ }
+ REPORTER_ASSERT(reporter, rt->config() == rtProxy->config());
+
+ REPORTER_ASSERT(reporter, rt->isUnifiedMultisampled() == rtProxy->isUnifiedMultisampled());
+ REPORTER_ASSERT(reporter, rt->isStencilBufferMultisampled() ==
+ rtProxy->isStencilBufferMultisampled());
+ REPORTER_ASSERT(reporter, rt->numColorSamples() == rtProxy->numColorSamples());
+ REPORTER_ASSERT(reporter, rt->numStencilSamples() == rtProxy->numStencilSamples());
+ REPORTER_ASSERT(reporter, rt->hasMixedSamples() == rtProxy->hasMixedSamples());
+}
+
+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);
+
+ REPORTER_ASSERT(reporter, tex->origin() == texProxy->origin());
+ if (SkBackingFit::kExact == fit) {
+ REPORTER_ASSERT(reporter, tex->width() == texProxy->width());
+ REPORTER_ASSERT(reporter, tex->height() == texProxy->height());
+ } else {
+ REPORTER_ASSERT(reporter, tex->width() >= texProxy->width());
+ REPORTER_ASSERT(reporter, tex->height() >= texProxy->height());
+ }
+ REPORTER_ASSERT(reporter, tex->config() == texProxy->config());
+}
+
+
+DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(AllocedProxyTest, reporter, ctxInfo) {
+ GrTextureProvider* provider = ctxInfo.fGrContext->textureProvider();
+
+ for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) {
+ for (auto widthHeight : { 100, 128 }) {
+ for (auto config : { kAlpha_8_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 = ctxInfo.fGrContext->caps()->isConfigRenderable(
+ config, numSamples > 0);
+
+ GrSurfaceDesc desc;
+ desc.fOrigin = origin;
+ desc.fWidth = widthHeight;
+ desc.fHeight = widthHeight;
+ desc.fConfig = config;
+ desc.fSampleCnt = numSamples;
+
+ if (renderable) {
+ sk_sp<GrRenderTargetProxy> rtProxy(GrRenderTargetProxy::Make(
+ *ctxInfo.fGrContext->caps(),
+ desc,
+ fit,
+ budgeted));
+ check_surface(reporter, rtProxy.get(), origin,
+ widthHeight, widthHeight, config);
+ check_rendertarget(reporter, provider, rtProxy.get(), fit);
+ }
+
+ desc.fSampleCnt = 0;
+
+ sk_sp<GrTextureProxy> texProxy(GrTextureProxy::Make(desc,
+ fit,
+ budgeted));
+ check_surface(reporter, texProxy.get(), origin,
+ widthHeight, widthHeight, config);
+ check_texture(reporter, provider, texProxy.get(), fit);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
+ GrTextureProvider* provider = ctxInfo.fGrContext->textureProvider();
+
+ static const int kWidthHeight = 100;
+
+ for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) {
+ for (auto config : { kAlpha_8_GrPixelConfig, kRGBA_8888_GrPixelConfig }) {
+ for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) {
+ for (auto numSamples: { 0, 4}) {
+ bool renderable = ctxInfo.fGrContext->caps()->isConfigRenderable(
+ config, numSamples > 0);
+
+ GrSurfaceDesc desc;
+ desc.fOrigin = origin;
+ desc.fWidth = kWidthHeight;
+ desc.fHeight = kWidthHeight;
+ desc.fConfig = config;
+ desc.fSampleCnt = numSamples;
+
+ sk_sp<GrTexture> tex;
+
+ if (renderable) {
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
+ tex.reset(provider->createTexture(desc, budgeted));
+ sk_sp<GrRenderTarget> rt(sk_ref_sp(tex->asRenderTarget()));
+
+ sk_sp<GrRenderTargetProxy> rtProxy(GrRenderTargetProxy::Make(rt));
+ check_surface(reporter, rtProxy.get(), origin,
+ kWidthHeight, kWidthHeight, config);
+ check_rendertarget(reporter, provider, rtProxy.get(), SkBackingFit::kExact);
+ }
+
+ if (!tex) {
+ SkASSERT(kNone_GrSurfaceFlags == desc.fFlags );
+ desc.fSampleCnt = 0;
+ tex.reset(provider->createTexture(desc, budgeted));
+ }
+
+ sk_sp<GrTextureProxy> texProxy(GrTextureProxy::Make(tex));
+ check_surface(reporter, texProxy.get(), origin,
+ kWidthHeight, kWidthHeight, config);
+ check_texture(reporter, provider, texProxy.get(), SkBackingFit::kExact);
+ }
+ }
+ }
+ }
+}
+
+#endif