diff options
author | 2016-12-15 09:23:05 -0500 | |
---|---|---|
committer | 2016-12-15 15:07:39 +0000 | |
commit | e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0b (patch) | |
tree | d290f1a9d5d5e828c7177d230f56356f9fc9bf2e /src/gpu | |
parent | db8f44f497f2b67b2500bbfc7b11ce7a510c5e5c (diff) |
Add a deferred copy surface (take 3)
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: Ib8fd96d0569274ef781366eb900ed8ee839ae9bd
Reviewed-on: https://skia-review.googlesource.com/6109
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrContext.cpp | 64 | ||||
-rw-r--r-- | src/gpu/GrContextPriv.h | 2 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 16 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContextPriv.h | 4 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetProxy.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 53 | ||||
-rw-r--r-- | src/gpu/GrTextureContext.cpp | 25 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 32 |
8 files changed, 122 insertions, 82 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index bcb4f88980..3e3bc0e6a8 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -540,43 +540,6 @@ void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) { fDrawingManager->prepareSurfaceForExternalIO(surface); } -bool GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, - const SkIPoint& dstPoint) { - ASSERT_SINGLE_OWNER - RETURN_FALSE_IF_ABANDONED - GR_AUDIT_TRAIL_AUTO_FRAME(&fAuditTrail, "GrContext::copySurface"); - - if (!src || !dst) { - return false; - } - ASSERT_OWNED_RESOURCE(src); - ASSERT_OWNED_RESOURCE(dst); - - // We don't allow conversion between integer configs and float/fixed configs. - if (GrPixelConfigIsSint(dst->config()) != GrPixelConfigIsSint(src->config())) { - return false; - } - -#ifndef ENABLE_MDB - // We can't yet fully defer copies to textures, so GrTextureContext::copySurface will - // execute the copy immediately. Ensure the data is ready. - src->flushWrites(); -#endif - - sk_sp<GrSurfaceContext> surfaceContext( - this->contextPriv().makeWrappedSurfaceContext(sk_ref_sp(dst))); - - if (!surfaceContext) { - return false; - } - - if (!surfaceContext->copySurface(src, srcRect, dstPoint)) { - return false; - } - - return true; -} - void GrContext::flushSurfaceWrites(GrSurface* surface) { ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED @@ -593,23 +556,6 @@ void GrContext::flushSurfaceIO(GrSurface* surface) { } } -sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc, - SkBackingFit fit, - SkBudgeted isDstBudgeted) { - - sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*fContext->caps(), dstDesc, - fit, isDstBudgeted); - - if (proxy->asRenderTargetProxy()) { - return this->drawingManager()->makeRenderTargetContext(std::move(proxy), nullptr, nullptr); - } else { - SkASSERT(proxy->asTextureProxy()); - return this->drawingManager()->makeTextureContext(std::move(proxy)); - } - - return nullptr; -} - //////////////////////////////////////////////////////////////////////////////// int GrContext::getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const { @@ -661,6 +607,16 @@ sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface return this->makeWrappedSurfaceContext(std::move(proxy)); } +sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc, + SkBackingFit fit, + SkBudgeted isDstBudgeted) { + + sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*fContext->caps(), dstDesc, + fit, isDstBudgeted); + + return this->makeWrappedSurfaceContext(std::move(proxy)); +} + sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext( const GrBackendTextureDesc& desc, sk_sp<SkColorSpace> colorSpace, diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 75effa3848..e24a588d1d 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -11,6 +11,8 @@ #include "GrContext.h" #include "GrSurfaceContext.h" +class GrSurfaceProxy; + /** Class that adds methods to GrContext that are only intended for use internal to Skia. This class is purely a privileged window into GrContext. It should never have additional data members or virtual methods. */ diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 1ba66acac6..ee87dae13b 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -133,12 +133,20 @@ GrRenderTargetOpList* GrRenderTargetContext::getOpList() { return fOpList; } -bool GrRenderTargetContext::copySurface(GrSurface* src, const SkIRect& srcRect, - const SkIPoint& dstPoint) { +// TODO: move this (and GrTextContext::copy) to GrSurfaceContext? +bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy, + const SkIRect& srcRect, + const SkIPoint& dstPoint) { ASSERT_SINGLE_OWNER RETURN_FALSE_IF_ABANDONED SkDEBUGCODE(this->validate();) - GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copySurface"); + GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copy"); + + // TODO: defer instantiation until flush time + sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->textureProvider()))); + if (!src) { + return false; + } // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget sk_sp<GrRenderTarget> rt( @@ -147,7 +155,7 @@ bool GrRenderTargetContext::copySurface(GrSurface* src, const SkIRect& srcRect, return false; } - return this->getOpList()->copySurface(rt.get(), src, srcRect, dstPoint); + return this->getOpList()->copySurface(rt.get(), src.get(), srcRect, dstPoint); } void GrRenderTargetContext::drawText(const GrClip& clip, const GrPaint& grPaint, diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h index b3bd72a563..f1548cc9fa 100644 --- a/src/gpu/GrRenderTargetContextPriv.h +++ b/src/gpu/GrRenderTargetContextPriv.h @@ -114,6 +114,10 @@ public: const GrUserStencilSettings* = nullptr, bool snapToCenters = false); + bool refsWrappedObjects() const { + return fRenderTargetContext->fRenderTargetProxy->refsWrappedObjects(); + } + private: explicit GrRenderTargetContextPriv(GrRenderTargetContext* renderTargetContext) : fRenderTargetContext(renderTargetContext) {} diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index 03637cf9af..882acf660c 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -8,6 +8,7 @@ #include "GrRenderTargetProxy.h" #include "GrCaps.h" +#include "GrGpuResourcePriv.h" #include "GrRenderTargetOpList.h" #include "GrRenderTargetPriv.h" #include "GrTextureProvider.h" @@ -63,3 +64,10 @@ size_t GrRenderTargetProxy::onGpuMemorySize() const { return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, false, SkBackingFit::kApprox == fFit); } +bool GrRenderTargetProxy::refsWrappedObjects() const { + if (!fTarget) { + return false; + } + + return fTarget->resourcePriv().refsWrappedObjects(); +} diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 4a0c3480a4..780ff8aa44 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -8,8 +8,11 @@ #include "GrSurfaceProxy.h" #include "GrCaps.h" +#include "GrContext.h" +#include "GrContextPriv.h" #include "GrGpuResourcePriv.h" #include "GrOpList.h" +#include "GrSurfaceContext.h" #include "GrTextureProvider.h" #include "GrTextureRenderTargetProxy.h" @@ -161,3 +164,53 @@ void GrSurfaceProxy::validate(GrContext* context) const { INHERITED::validate(); } #endif + +sk_sp<GrSurfaceProxy> GrSurfaceProxy::Copy(GrContext* context, + GrSurfaceProxy* src, + SkIRect srcRect, + SkBudgeted budgeted) { + if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) { + return nullptr; + } + + GrSurfaceDesc dstDesc = src->desc(); + dstDesc.fWidth = srcRect.width(); + dstDesc.fHeight = srcRect.height(); + + sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext( + dstDesc, + SkBackingFit::kExact, + budgeted)); + if (!dstContext) { + return nullptr; + } + + if (!dstContext->copy(src, srcRect, SkIPoint::Make(0, 0))) { + return nullptr; + } + + return sk_ref_sp(dstContext->asDeferredSurface()); +} + +sk_sp<GrSurfaceProxy> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc, + GrTexture* srcTexture, SkBudgeted budgeted) { + + sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext( + dstDesc, + SkBackingFit::kExact, + budgeted)); + if (!dstContext) { + return nullptr; + } + + sk_sp<GrSurfaceProxy> srcProxy(GrSurfaceProxy::MakeWrapped(sk_ref_sp(srcTexture))); + if (!srcProxy) { + return nullptr; + } + + if (!dstContext->copy(srcProxy.get())) { + return nullptr; + } + + return sk_ref_sp(dstContext->asDeferredSurface()); +} diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp index 59dae3f0f2..9f61551270 100644 --- a/src/gpu/GrTextureContext.cpp +++ b/src/gpu/GrTextureContext.cpp @@ -24,8 +24,7 @@ GrTextureContext::GrTextureContext(GrContext* context, : GrSurfaceContext(context, auditTrail, singleOwner) , fDrawingManager(drawingMgr) , fTextureProxy(std::move(textureProxy)) - , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList())) -{ + , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList())) { SkDEBUGCODE(this->validate();) } @@ -62,12 +61,26 @@ GrTextureOpList* GrTextureContext::getOpList() { return fOpList; } -bool GrTextureContext::copySurface(GrSurface* src, const SkIRect& srcRect, - const SkIPoint& dstPoint) { +// TODO: move this (and GrRenderTargetContext::copy) to GrSurfaceContext? +bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy, + const SkIRect& srcRect, + const SkIPoint& dstPoint) { ASSERT_SINGLE_OWNER RETURN_FALSE_IF_ABANDONED SkDEBUGCODE(this->validate();) - GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copySurface"); + GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copy"); + + // TODO: defer instantiation until flush time + sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->textureProvider()))); + if (!src) { + return false; + } +
+#ifndef ENABLE_MDB
+ // We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
+ // execute the copy immediately. Ensure the data is ready.
+ src->flushWrites();
+#endif // TODO: this needs to be fixed up since it ends the deferrable of the GrTexture sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->textureProvider()))); @@ -76,7 +89,7 @@ bool GrTextureContext::copySurface(GrSurface* src, const SkIRect& srcRect, } GrTextureOpList* opList = this->getOpList(); - bool result = opList->copySurface(tex.get(), src, srcRect, dstPoint); + bool result = opList->copySurface(tex.get(), src.get(), srcRect, dstPoint); #ifndef ENABLE_MDB GrOpFlushState flushState(fContext->getGpu(), nullptr); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 8549b0ccf1..a623dd1fdb 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -15,6 +15,7 @@ #include "GrRenderTargetContextPriv.h" #include "GrStyle.h" #include "GrTextureAdjuster.h" +#include "GrTextureProxy.h" #include "GrTracing.h" #include "SkCanvasPriv.h" @@ -262,9 +263,7 @@ void SkGpuDevice::replaceRenderTargetContext(bool shouldRetainContent) { if (fRenderTargetContext->wasAbandoned()) { return; } - newRTC->copySurface(fRenderTargetContext->asTexture().get(), - SkIRect::MakeWH(this->width(), this->height()), - SkIPoint::Make(0, 0)); + newRTC->copy(fRenderTargetContext->asDeferredSurface()); } fRenderTargetContext = newRTC; @@ -1332,19 +1331,15 @@ sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) { } sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() { - sk_sp<GrTexture> texture(this->accessRenderTargetContext()->asTexture()); - if (!texture) { + sk_sp<GrSurfaceProxy> sProxy(sk_ref_sp(this->accessRenderTargetContext()->asDeferredTexture())); + if (!sProxy) { // When the device doesn't have a texture, we create a temporary texture. // TODO: we should actually only copy the portion of the source needed to apply the image // filter - texture.reset(fContext->textureProvider()->createTexture( - this->accessRenderTargetContext()->desc(), SkBudgeted::kYes)); - if (!texture) { - return nullptr; - } - - if (!fContext->copySurface(texture.get(), - this->accessRenderTargetContext()->accessRenderTarget())) { + sProxy = GrSurfaceProxy::Copy(fContext.get(), + this->accessRenderTargetContext()->asDeferredSurface(), + SkBudgeted::kYes); + if (!sProxy) { return nullptr; } } @@ -1352,11 +1347,12 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() { const SkImageInfo ii = this->imageInfo(); const SkIRect srcRect = SkIRect::MakeWH(ii.width(), ii.height()); - return SkSpecialImage::MakeFromGpu(srcRect, - kNeedNewImageUniqueID_SpecialImage, - std::move(texture), - sk_ref_sp(ii.colorSpace()), - &this->surfaceProps()); + return SkSpecialImage::MakeDeferredFromGpu(fContext.get(), + srcRect, + kNeedNewImageUniqueID_SpecialImage, + sProxy, + sk_ref_sp(ii.colorSpace()), + &this->surfaceProps()); } void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, |