diff options
author | Brian Osman <brianosman@google.com> | 2016-11-23 09:37:01 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-23 15:52:27 +0000 |
commit | 45580d3e3024c1536e8e1b2017b704805442b634 (patch) | |
tree | 9ed9fe3bdc0d949ec8e83b06691b37b6ffdcc54a /src/gpu | |
parent | 07764cefbb18041a77897df3453903b0a2016583 (diff) |
Added GrSurfaceContext and GrTextureContext
This lets copy-to-texture to be treated like copy-to-rt.
To match current behavior, though, copies to texture are
still executed immediately (forcing a flush).
Once MDB is enabled, copies to texture will be deferred.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5093
Change-Id: Icc0ce5435507a5f0a237c22eedef879824952367
Reviewed-on: https://skia-review.googlesource.com/5093
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrContext.cpp | 47 | ||||
-rw-r--r-- | src/gpu/GrContextPriv.h | 4 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.cpp | 34 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.h | 4 | ||||
-rw-r--r-- | src/gpu/GrOpList.h | 12 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetOpList.h | 2 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetProxy.cpp | 11 | ||||
-rw-r--r-- | src/gpu/GrSurfaceContext.cpp | 26 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 17 | ||||
-rw-r--r-- | src/gpu/GrTextureContext.cpp | 83 | ||||
-rw-r--r-- | src/gpu/GrTextureOpList.h | 2 |
12 files changed, 213 insertions, 37 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 1a5ee20721..7b789bd08d 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -14,7 +14,9 @@ #include "GrResourceProvider.h" #include "GrRenderTargetProxy.h" #include "GrSoftwarePathRenderer.h" +#include "GrSurfaceContext.h" #include "GrSurfacePriv.h" +#include "GrTextureContext.h" #include "SkConfig8888.h" #include "SkGrPriv.h" @@ -557,31 +559,23 @@ bool GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe return false; } - if (!dst->asRenderTarget()) { - SkIRect clippedSrcRect; - SkIPoint clippedDstPoint; - if (!GrCopySurfaceBatch::ClipSrcRectAndDstPoint(dst, src, srcRect, dstPoint, - &clippedSrcRect, &clippedDstPoint)) { - return false; - } - // If we don't have an RT for the dst then we won't have a GrRenderTargetContext to insert - // the copy surface into. In the future we plan to have a more limited Context type - // (GrCopyContext?) that has the subset of GrRenderTargetContext operations that should be - // allowed on textures that aren't render targets. - // For now we just flush any writes to the src and issue an immediate copy to the dst. - src->flushWrites(); - return fGpu->copySurface(dst, src, clippedSrcRect, clippedDstPoint); - } - sk_sp<GrRenderTargetContext> renderTargetContext( - this->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(dst->asRenderTarget()), - nullptr)); - if (!renderTargetContext) { +#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 (!renderTargetContext->copySurface(src, srcRect, dstPoint)) { + if (!surfaceContext->copySurface(src, srcRect, dstPoint)) { return false; } + return true; } @@ -633,6 +627,19 @@ sk_sp<GrRenderTargetContext> GrContextPriv::makeWrappedRenderTargetContext( surfaceProps); } +sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface> surface) { + ASSERT_SINGLE_OWNER_PRIV + + sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface))); + + if (proxy->asRenderTargetProxy()) { + return this->drawingManager()->makeRenderTargetContext(std::move(proxy), nullptr, nullptr); + } else { + SkASSERT(proxy->asTextureProxy()); + return this->drawingManager()->makeTextureContext(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 d2fa7c1610..dcf0807507 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -9,6 +9,7 @@ #define GrContextPriv_DEFINED #include "GrContext.h" +#include "GrSurfaceContext.h" /** 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 @@ -22,6 +23,9 @@ public: sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* = nullptr); + // Create a surfaceContext that wraps an existing texture or renderTarget + sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurface> tex); + sk_sp<GrRenderTargetContext> makeBackendTextureRenderTargetContext( const GrBackendTextureDesc& desc, sk_sp<SkColorSpace> colorSpace, diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 5267df3626..e1dff8b14f 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -14,6 +14,8 @@ #include "GrResourceProvider.h" #include "GrSoftwarePathRenderer.h" #include "GrSurfacePriv.h" +#include "GrTextureContext.h" +#include "GrTextureOpList.h" #include "SkSurface_Gpu.h" #include "SkTTopoSort.h" @@ -172,6 +174,24 @@ GrRenderTargetOpList* GrDrawingManager::newOpList(GrRenderTargetProxy* rtp) { return SkRef(opList); } +GrTextureOpList* GrDrawingManager::newOpList(GrTextureProxy* textureProxy) { + SkASSERT(fContext); + + GrTextureOpList* opList = new GrTextureOpList(textureProxy, fContext->getGpu(), + fContext->getAuditTrail()); + +#ifndef ENABLE_MDB + // When MDB is disabled we still create a new GrOpList, but don't store or ref it - we rely + // on the caller to immediately execute and free it. + return opList; +#else + *fOpLists.append() = opList; + + // Drawing manager gets the creation ref - this ref is for the caller + return SkRef(opList); +#endif +} + GrAtlasTextContext* GrDrawingManager::getAtlasTextContext() { if (!fAtlasTextContext) { fAtlasTextContext.reset(GrAtlasTextContext::Create()); @@ -253,3 +273,17 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext( fContext->getAuditTrail(), fSingleOwner)); } + +sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy) { + if (this->wasAbandoned() || !sProxy->asTextureProxy()) { + return nullptr; + } + + // GrTextureRenderTargets should always be using GrRenderTargetContext + SkASSERT(!sProxy->asRenderTargetProxy()); + + sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy())); + + return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy), + fContext->getAuditTrail(), fSingleOwner)); +} diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h index 3816868c75..90a3064e24 100644 --- a/src/gpu/GrDrawingManager.h +++ b/src/gpu/GrDrawingManager.h @@ -22,6 +22,8 @@ class GrRenderTargetContext; class GrRenderTargetProxy; class GrSingleOWner; class GrSoftwarePathRenderer; +class GrTextureContext; +class GrTextureOpList; // The GrDrawingManager allocates a new GrRenderTargetContext for each GrRenderTarget // but all of them still land in the same GrOpList! @@ -38,10 +40,12 @@ public: sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrSurfaceProxy>, sk_sp<SkColorSpace>, const SkSurfaceProps*); + sk_sp<GrTextureContext> makeTextureContext(sk_sp<GrSurfaceProxy>); // The caller automatically gets a ref on the returned opList. It must // be balanced by an unref call. GrRenderTargetOpList* newOpList(GrRenderTargetProxy* rtp); + GrTextureOpList* newOpList(GrTextureProxy* textureProxy); GrContext* getContext() { return fContext; } diff --git a/src/gpu/GrOpList.h b/src/gpu/GrOpList.h index 9c965f8f0f..313807d63c 100644 --- a/src/gpu/GrOpList.h +++ b/src/gpu/GrOpList.h @@ -15,8 +15,10 @@ class GrAuditTrail; class GrBatchFlushState; +class GrRenderTargetOpList; class GrSurface; class GrSurfaceProxy; +class GrTextureOpList; class GrOpList : public SkRefCnt { public: @@ -62,6 +64,16 @@ public: } /* + * Safely cast this GrOpList to a GrTextureOpList (if possible). + */ + virtual GrTextureOpList* asTextureOpList() { return nullptr; } + + /* + * Safely case this GrOpList to a GrRenderTargetOpList (if possible). + */ + virtual GrRenderTargetOpList* asRenderTargetOpList() { return nullptr; } + + /* * Dump out the GrOpList dependency DAG */ SkDEBUGCODE(virtual void dump() const;) diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 6238fa8025..f08f39a1be 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -81,18 +81,14 @@ GrRenderTargetContext::GrRenderTargetContext(GrContext* context, const SkSurfaceProps* surfaceProps, GrAuditTrail* auditTrail, GrSingleOwner* singleOwner) - : fDrawingManager(drawingMgr) + : GrSurfaceContext(context, auditTrail, singleOwner) + , fDrawingManager(drawingMgr) , fRenderTargetProxy(std::move(rtp)) , fOpList(SkSafeRef(fRenderTargetProxy->getLastRenderTargetOpList())) - , fContext(context) , fInstancedPipelineInfo(fRenderTargetProxy.get()) , fColorSpace(std::move(colorSpace)) , fColorXformFromSRGB(nullptr) , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps)) - , fAuditTrail(auditTrail) -#ifdef SK_DEBUG - , fSingleOwner(singleOwner) -#endif { if (fColorSpace) { // sRGB sources are very common (SkColor, etc...), so we cache that gamut transformation diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h index b084d48291..d96f83d21a 100644 --- a/src/gpu/GrRenderTargetOpList.h +++ b/src/gpu/GrRenderTargetOpList.h @@ -127,6 +127,8 @@ public: return fInstancedRendering.get(); } + GrRenderTargetOpList* asRenderTargetOpList() override { return this; } + SkDEBUGCODE(void dump() const override;) private: diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index cb9b97a4a9..03637cf9af 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -54,17 +54,6 @@ GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider) return surf->asRenderTarget(); } - -#ifdef SK_DEBUG -void GrRenderTargetProxy::validate(GrContext* context) const { - if (fTarget) { - SkASSERT(fTarget->getContext() == context); - } - - INHERITED::validate(); -} -#endif - size_t GrRenderTargetProxy::onGpuMemorySize() const { if (fTarget) { return fTarget->gpuMemorySize(); diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp new file mode 100644 index 0000000000..682233bd1c --- /dev/null +++ b/src/gpu/GrSurfaceContext.cpp @@ -0,0 +1,26 @@ +/* + * 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 "GrSurfaceContext.h" + +#include "../private/GrAuditTrail.h" + + +// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress +// GrOpLists to be picked up and added to by renderTargetContexts lower in the call +// stack. When this occurs with a closed GrOpList, a new one will be allocated +// when the renderTargetContext attempts to use it (via getOpList). +GrSurfaceContext::GrSurfaceContext(GrContext* context, + GrAuditTrail* auditTrail, + GrSingleOwner* singleOwner) + : fContext(context) + , fAuditTrail(auditTrail) +#ifdef SK_DEBUG + , fSingleOwner(singleOwner) +#endif +{ +} diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 9de41ef482..95fc8b9a8a 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -66,6 +66,14 @@ void GrSurfaceProxy::setLastOpList(GrOpList* opList) { SkRefCnt_SafeAssign(fLastOpList, opList); } +GrRenderTargetOpList* GrSurfaceProxy::getLastRenderTargetOpList() { + return fLastOpList ? fLastOpList->asRenderTargetOpList() : nullptr; +} + +GrTextureOpList* GrSurfaceProxy::getLastTextureOpList() { + return fLastOpList ? fLastOpList->asTextureOpList() : nullptr; +} + sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf) { if (surf->asTexture()) { if (surf->asRenderTarget()) { @@ -109,3 +117,12 @@ sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps, return GrSurfaceProxy::MakeDeferred(caps, desc, SkBackingFit::kExact, budgeted); } +#ifdef SK_DEBUG +void GrSurfaceProxy::validate(GrContext* context) const { + if (fTarget) { + SkASSERT(fTarget->getContext() == context); + } + + INHERITED::validate(); +} +#endif diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp new file mode 100644 index 0000000000..5c0c17b728 --- /dev/null +++ b/src/gpu/GrTextureContext.cpp @@ -0,0 +1,83 @@ +/* + * 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 "GrTextureContext.h" +#include "GrDrawingManager.h" +#include "GrResourceProvider.h" +#include "GrTextureOpList.h" + +#include "../private/GrAuditTrail.h" + +#define ASSERT_SINGLE_OWNER \ + SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);) +#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; } + +GrTextureContext::GrTextureContext(GrContext* context, + GrDrawingManager* drawingMgr, + sk_sp<GrTextureProxy> textureProxy, + GrAuditTrail* auditTrail, + GrSingleOwner* singleOwner) + : GrSurfaceContext(context, auditTrail, singleOwner) + , fDrawingManager(drawingMgr) + , fTextureProxy(std::move(textureProxy)) + , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList())) +{ + SkDEBUGCODE(this->validate();) +} + +#ifdef SK_DEBUG +void GrTextureContext::validate() const { + SkASSERT(fTextureProxy); + fTextureProxy->validate(fContext); + + if (fOpList && !fOpList->isClosed()) { + SkASSERT(fTextureProxy->getLastOpList() == fOpList); + } +} +#endif + +GrTextureContext::~GrTextureContext() { + ASSERT_SINGLE_OWNER + SkSafeUnref(fOpList); +} + +GrTextureOpList* GrTextureContext::getOpList() { + ASSERT_SINGLE_OWNER + SkDEBUGCODE(this->validate();) + + if (!fOpList || fOpList->isClosed()) { + fOpList = fDrawingManager->newOpList(fTextureProxy.get()); + } + + return fOpList; +} + +bool GrTextureContext::copySurface(GrSurface* src, const SkIRect& srcRect, + const SkIPoint& dstPoint) { + ASSERT_SINGLE_OWNER + RETURN_FALSE_IF_ABANDONED + SkDEBUGCODE(this->validate();) + GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copySurface"); + + // 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()))); + if (!tex) { + return false; + } + + GrTextureOpList* opList = this->getOpList(); + bool result = opList->copySurface(tex.get(), src, srcRect, dstPoint); + +#ifndef ENABLE_MDB + GrBatchFlushState flushState(fContext->getGpu(), nullptr); + opList->prepareBatches(&flushState); + opList->drawBatches(&flushState); + opList->reset(); +#endif + + return result; +} diff --git a/src/gpu/GrTextureOpList.h b/src/gpu/GrTextureOpList.h index 33ca656cf6..7674184890 100644 --- a/src/gpu/GrTextureOpList.h +++ b/src/gpu/GrTextureOpList.h @@ -55,6 +55,8 @@ public: const SkIRect& srcRect, const SkIPoint& dstPoint); + GrTextureOpList* asTextureOpList() override { return this; } + SkDEBUGCODE(void dump() const override;) private: |