From 398487a850431cf495330d4023607df5305a311f Mon Sep 17 00:00:00 2001 From: Robert Phillips Date: Tue, 13 Dec 2016 15:29:42 -0500 Subject: Add a deferred copy surface (take 2) This CL forces all GrSurface copies to go through a GrSurfaceContext (rather than GrContext). There is a bit of goofiness going on here until read/writePixels is also consolidated in GrSurfaceContext and a proxy-backed SkImage/SkSurface is added. This is a reland of https://skia-review.googlesource.com/c/5773/ (Add a deferred copy surface) Change-Id: Ide560f569aede5e622420dc2f30eef76357d69f4 Reviewed-on: https://skia-review.googlesource.com/5939 Reviewed-by: Brian Osman Reviewed-by: Brian Salomon Commit-Queue: Robert Phillips --- include/gpu/GrContext.h | 19 ------------------- include/gpu/GrRenderTargetContext.h | 7 +++++-- include/gpu/GrSurfaceContext.h | 34 +++++++++++++++++++++++++++++++++- include/gpu/GrTextureContext.h | 6 +++++- include/private/GrRenderTargetProxy.h | 3 +++ include/private/GrSurfaceProxy.h | 14 ++++++++++++++ 6 files changed, 60 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 9ccda23727..9e9773c73a 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -301,25 +301,6 @@ public: size_t rowBytes, uint32_t pixelOpsFlags = 0); - /** - * Copies a rectangle of texels from src to dst. - * @param dst the surface to copy to. - * @param src the surface to copy from. - * @param srcRect the rectangle of the src that should be copied. - * @param dstPoint the translation applied when writing the srcRect's pixels to the dst. - */ - bool copySurface(GrSurface* dst, - GrSurface* src, - const SkIRect& srcRect, - const SkIPoint& dstPoint); - - /** Helper that copies the whole surface but fails when the two surfaces are not identically - sized. */ - bool copySurface(GrSurface* dst, GrSurface* src) { - return this->copySurface(dst, src, SkIRect::MakeWH(dst->width(), dst->height()), - SkIPoint::Make(0,0)); - } - /** * After this returns any pending writes to the surface will have been issued to the backend 3D API. */ diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h index 5317c3e07c..5fca84561e 100644 --- a/include/gpu/GrRenderTargetContext.h +++ b/include/gpu/GrRenderTargetContext.h @@ -50,8 +50,6 @@ class SK_API GrRenderTargetContext : public GrSurfaceContext { public: ~GrRenderTargetContext() override; - bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; - // TODO: it is odd that we need both the SkPaint in the following 3 methods. // We should extract the text parameters from SkPaint and pass them separately // akin to GrStyle (GrTextInfo?) @@ -372,6 +370,7 @@ public: return fRenderTargetProxy->instantiate(fContext->textureProvider()); } + GrSurfaceProxy* asDeferredSurface() override { return fRenderTargetProxy.get(); } GrTextureProxy* asDeferredTexture(); sk_sp asTexture() { @@ -467,6 +466,8 @@ private: const SkPath&, const GrStyle&); + bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; + // This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList. void addDrawOp(const GrPipelineBuilder&, const GrClip&, sk_sp); @@ -483,6 +484,8 @@ private: sk_sp fColorSpace; sk_sp fColorXformFromSRGB; SkSurfaceProps fSurfaceProps; + + typedef GrSurfaceContext INHERITED; }; #endif diff --git a/include/gpu/GrSurfaceContext.h b/include/gpu/GrSurfaceContext.h index a05d37fed3..e1c799e3ae 100644 --- a/include/gpu/GrSurfaceContext.h +++ b/include/gpu/GrSurfaceContext.h @@ -8,6 +8,8 @@ #ifndef GrSurfaceContext_DEFINED #define GrSurfaceContext_DEFINED +#include "../private/GrSurfaceProxy.h" + #include "SkRefCnt.h" class GrAuditTrail; @@ -24,7 +26,30 @@ class SK_API GrSurfaceContext : public SkRefCnt { public: ~GrSurfaceContext() override {} - virtual bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) = 0; + /* + * Copy 'src' into the proxy backing this context + * @param src src of pixels + * @param srcRect the subset of 'src' to copy + * @param dstPoint the origin of the 'srcRect' in the destination coordinate space + * @return true if the copy succeeded; false otherwise + * + * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted. + * Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent. + * The end result is only valid src pixels and dst pixels will be touched but the copied + * regions will not be shifted. + */ + bool copy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) { + return this->onCopy(src, srcRect, dstPoint); + } + + bool copy(GrSurfaceProxy* src) { + return this->onCopy(src, + SkIRect::MakeWH(src->width(), src->height()), + SkIPoint::Make(0, 0)); + } + + // TODO: this is virtual b.c. this object doesn't have a pointer to the wrapped GrSurfaceProxy? + virtual GrSurfaceProxy* asDeferredSurface() = 0; GrAuditTrail* auditTrail() { return fAuditTrail; } @@ -38,6 +63,13 @@ protected: // In debug builds we guard against improper thread handling SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;) + +private: + virtual bool onCopy(GrSurfaceProxy* src, + const SkIRect& srcRect, + const SkIPoint& dstPoint) = 0; + + typedef SkRefCnt INHERITED; }; #endif diff --git a/include/gpu/GrTextureContext.h b/include/gpu/GrTextureContext.h index da71c07c72..3052f0ccb5 100644 --- a/include/gpu/GrTextureContext.h +++ b/include/gpu/GrTextureContext.h @@ -27,7 +27,7 @@ class SK_API GrTextureContext : public GrSurfaceContext { public: ~GrTextureContext() override; - bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; + GrSurfaceProxy* asDeferredSurface() override { return fTextureProxy.get(); } protected: GrTextureContext(GrContext*, GrDrawingManager*, sk_sp, GrAuditTrail*, @@ -40,6 +40,8 @@ protected: private: friend class GrDrawingManager; // for ctor + bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; + GrTextureOpList* getOpList(); GrDrawingManager* fDrawingManager; @@ -48,6 +50,8 @@ private: // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'. GrTextureOpList* fOpList; + + typedef GrSurfaceContext INHERITED; }; #endif diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h index 83107daf61..7f026ba726 100644 --- a/include/private/GrRenderTargetProxy.h +++ b/include/private/GrRenderTargetProxy.h @@ -53,6 +53,9 @@ public: GrRenderTarget::Flags testingOnly_getFlags() const; + // TODO: move this to a priv class! + bool refsWrappedObjects() const; + protected: friend class GrSurfaceProxy; // for ctors diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 731603b2c9..12972c21be 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -266,6 +266,20 @@ public: return fGpuMemorySize; } + // Helper function that creates a temporary SurfaceContext to perform the copy + static sk_sp Copy(GrContext*, GrSurfaceProxy* src, + SkIRect srcRect, SkBudgeted); + + // Copy the entire 'src' + static sk_sp Copy(GrContext* context, GrSurfaceProxy* src, + SkBudgeted budgeted) { + return Copy(context, src, SkIRect::MakeWH(src->width(), src->height()), budgeted); + } + + // Test-only entry point - should decrease in use as proxies propagate + static sk_sp TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc, + GrTexture* srcTexture, SkBudgeted budgeted); + bool isWrapped_ForTesting() const; SkDEBUGCODE(void validate(GrContext*) const;) -- cgit v1.2.3