diff options
author | Robert Phillips <robertphillips@google.com> | 2018-02-01 09:10:04 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-01 15:00:53 +0000 |
commit | 620003692923dc6c6df5a1b66288988b6783a69f (patch) | |
tree | 5010067f4d26fb23f28964e74b5e37c38e3dddc3 | |
parent | 5f9ee7cc53d28c8ff2d000436bfee195c493ccdf (diff) |
Implement GPU/OpList DDLs
This relies on https://skia-review.googlesource.com/c/skia/+/102101 (Add SkSurface_Gpu::MakeWrappedRenderTarget method) landing first
TBR=bsalomon@google.com
Change-Id: I4d2d66af5800407f638ef32d7b19ce49084bd4e4
Reviewed-on: https://skia-review.googlesource.com/102263
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | gn/core.gni | 1 | ||||
-rw-r--r-- | gn/gpu.gni | 6 | ||||
-rw-r--r-- | include/core/SkDeferredDisplayListRecorder.h | 13 | ||||
-rw-r--r-- | include/private/GrOpList.h (renamed from src/gpu/GrOpList.h) | 4 | ||||
-rw-r--r-- | include/private/GrSurfaceProxyRef.h | 71 | ||||
-rw-r--r-- | include/private/SkDeferredDisplayList.h | 54 | ||||
-rw-r--r-- | include/private/SkSurfaceCharacterization.h | 10 | ||||
-rw-r--r-- | src/core/SkDeferredDisplayList.cpp | 28 | ||||
-rw-r--r-- | src/core/SkDeferredDisplayListRecorder.cpp | 95 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 9 | ||||
-rw-r--r-- | src/gpu/GrContextPriv.h | 5 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.cpp | 18 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.h | 3 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceRef.cpp | 112 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceRef.h | 60 | ||||
-rw-r--r-- | src/gpu/GrProcessor.h | 1 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxyRef.cpp | 118 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 8 |
18 files changed, 407 insertions, 209 deletions
diff --git a/gn/core.gni b/gn/core.gni index f0612cb973..d94bda4c4c 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -100,6 +100,7 @@ skia_core_sources = [ "$_src/core/SkData.cpp", "$_src/core/SkDataTable.cpp", "$_src/core/SkDebug.cpp", + "$_src/core/SkDeferredDisplayList.cpp", "$_src/core/SkDeferredDisplayListRecorder.cpp", "$_src/core/SkDeque.cpp", "$_src/core/SkDescriptor.h", diff --git a/gn/gpu.gni b/gn/gpu.gni index 97d5df9135..4d8f3d8973 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -35,9 +35,11 @@ skia_gpu_sources = [ # Private includes "$_include/private/GrAuditTrail.h", "$_include/private/GrGLSL.h", + "$_include/private/GrOpList.h", "$_include/private/GrSingleOwner.h", "$_include/private/GrRenderTargetProxy.h", "$_include/private/GrSurfaceProxy.h", + "$_include/private/GrSurfaceProxyRef.h", "$_include/private/GrSwizzle.h", "$_include/private/GrTextureProxy.h", "$_include/private/GrTypesPriv.h", @@ -95,6 +97,7 @@ skia_gpu_sources = [ "$_src/gpu/GrGpuCommandBuffer.h", "$_src/gpu/GrGpuResourcePriv.h", "$_src/gpu/GrGpuResource.cpp", + "$_src/gpu/GrGpuResourceRef.cpp", "$_src/gpu/GrGpuResourceRef.h", "$_src/gpu/GrGpuFactory.cpp", "$_src/gpu/GrGpuFactory.h", @@ -107,7 +110,6 @@ skia_gpu_sources = [ "$_src/gpu/GrOpFlushState.cpp", "$_src/gpu/GrOpFlushState.h", "$_src/gpu/GrOpList.cpp", - "$_src/gpu/GrOpList.h", "$_src/gpu/GrPaint.cpp", "$_src/gpu/GrPaint.h", "$_src/gpu/GrPath.cpp", @@ -144,7 +146,6 @@ skia_gpu_sources = [ "$_src/gpu/GrProcessorUnitTest.h", "$_src/gpu/GrProxyProvider.cpp", "$_src/gpu/GrProxyProvider.h", - "$_src/gpu/GrGpuResourceRef.cpp", "$_src/gpu/GrQuad.h", "$_src/gpu/GrRect.h", "$_src/gpu/GrRectanizer.h", @@ -186,6 +187,7 @@ skia_gpu_sources = [ "$_src/gpu/GrStyle.h", "$_src/gpu/GrSurfaceContextPriv.h", "$_src/gpu/GrSurfaceProxyPriv.h", + "$_src/gpu/GrSurfaceProxyRef.cpp", "$_src/gpu/GrTessellator.cpp", "$_src/gpu/GrTessellator.h", "$_src/gpu/GrTextureOpList.cpp", diff --git a/include/core/SkDeferredDisplayListRecorder.h b/include/core/SkDeferredDisplayListRecorder.h index b50d4f8c1f..f0a71c27d6 100644 --- a/include/core/SkDeferredDisplayListRecorder.h +++ b/include/core/SkDeferredDisplayListRecorder.h @@ -18,8 +18,6 @@ class GrContext; class SkCanvas; class SkSurface; -#define SK_RASTER_RECORDER_IMPLEMENTATION 1 - /* * This class is intended to be used as: * Get an SkSurfaceCharacterization representing the intended gpu-backed destination SkSurface @@ -35,6 +33,7 @@ class SkSurface; class SkDeferredDisplayListRecorder { public: SkDeferredDisplayListRecorder(const SkSurfaceCharacterization&); + ~SkDeferredDisplayListRecorder(); const SkSurfaceCharacterization& characterization() const { return fCharacterization; @@ -50,11 +49,15 @@ public: private: bool init(); - const SkSurfaceCharacterization fCharacterization; + const SkSurfaceCharacterization fCharacterization; + #ifndef SK_RASTER_RECORDER_IMPLEMENTATION - sk_sp<GrContext> fContext; +#if SK_SUPPORT_GPU + sk_sp<GrContext> fContext; +#endif + sk_sp<SkDeferredDisplayList::LazyProxyData> fLazyProxyData; #endif - sk_sp<SkSurface> fSurface; + sk_sp<SkSurface> fSurface; }; #endif diff --git a/src/gpu/GrOpList.h b/include/private/GrOpList.h index f1989fd591..c9abd6d4e5 100644 --- a/src/gpu/GrOpList.h +++ b/include/private/GrOpList.h @@ -9,7 +9,8 @@ #define GrOpList_DEFINED #include "GrColor.h" -#include "GrGpuResourceRef.h" +#include "GrSurfaceProxyRef.h" +#include "GrTextureProxy.h" #include "SkRefCnt.h" #include "SkTDArray.h" @@ -31,7 +32,6 @@ class GrRenderTargetOpList; class GrResourceAllocator; class GrResourceProvider; class GrSurfaceProxy; -class GrTextureProxy; class GrTextureOpList; struct SkIPoint; diff --git a/include/private/GrSurfaceProxyRef.h b/include/private/GrSurfaceProxyRef.h new file mode 100644 index 0000000000..2319357251 --- /dev/null +++ b/include/private/GrSurfaceProxyRef.h @@ -0,0 +1,71 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrSurfaceProxyRef_DEFINED +#define GrSurfaceProxyRef_DEFINED + +#include "GrTypesPriv.h" + +class GrSurfaceProxy; + +class GrSurfaceProxyRef : SkNoncopyable { +public: + virtual ~GrSurfaceProxyRef(); + + GrSurfaceProxy* get() const { return fProxy; } + + /** Does this object own a pending read or write on the resource it is wrapping. */ + bool ownsPendingIO() const { return fPendingIO; } + + /** What type of IO does this represent? This is independent of whether a normal ref or a + pending IO is currently held. */ + GrIOType ioType() const { return fIOType; } + + /** Shortcut for calling setProxy() with NULL. It cannot be called after markingPendingIO + is called. */ + void reset(); + +protected: + GrSurfaceProxyRef(); + + /** ioType expresses what type of IO operations will be marked as + pending on the resource when markPendingIO is called. */ + GrSurfaceProxyRef(sk_sp<GrSurfaceProxy>, GrIOType); + + /** ioType expresses what type of IO operations will be marked as + pending on the resource when markPendingIO is called. */ + void setProxy(sk_sp<GrSurfaceProxy>, GrIOType); + +private: + /** Called by owning GrProgramElement when the program element is first scheduled for + execution. It can only be called once. */ + void markPendingIO() const; + + /** Called when the program element/draw state is no longer owned by GrOpList-client code. + This lets the cache know that the drawing code will no longer schedule additional reads or + writes to the resource using the program element or draw state. It can only be called once. + */ + void removeRef() const; + + /** Called to indicate that the previous pending IO is complete. Useful when the owning object + still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously + pending executions have been complete. Can only be called if removeRef() was not previously + called. */ + void pendingIOComplete() const; + + friend class GrResourceIOProcessor; + friend class GrOpList; // for setProxy + + GrSurfaceProxy* fProxy; + mutable bool fOwnRef; + mutable bool fPendingIO; + GrIOType fIOType; + + typedef SkNoncopyable INHERITED; +}; + +#endif diff --git a/include/private/SkDeferredDisplayList.h b/include/private/SkDeferredDisplayList.h index 392a952a1d..a3517bb6a0 100644 --- a/include/private/SkDeferredDisplayList.h +++ b/include/private/SkDeferredDisplayList.h @@ -10,7 +10,14 @@ #include "SkSurfaceCharacterization.h" -class SkImage; // TODO: rm this since it is just for the temporary placeholder implementation +#if SK_SUPPORT_GPU +#include "GrOpList.h" +#endif + +#ifdef SK_RASTER_RECORDER_IMPLEMENTATION +class SkImage; // DDL TODO: rm this since it is just for the temporary placeholder implementation +#endif + class SkSurface; /* @@ -21,24 +28,55 @@ class SkSurface; */ class SkDeferredDisplayList { public: - SkDeferredDisplayList(const SkSurfaceCharacterization& characterization, - sk_sp<SkImage> image) // TODO rm this parameter + +#ifdef SK_RASTER_RECORDER_IMPLEMENTATION + SkDeferredDisplayList(const SkSurfaceCharacterization& characterization, sk_sp<SkImage> image) : fCharacterization(characterization) , fImage(std::move(image)) { } + // DDL TODO: remove this. It is just scaffolding to get something up & running + bool draw(SkSurface*) const; +#endif + +#if SK_SUPPORT_GPU + // This object is the source from which the lazy proxy backing the DDL will pull its backing + // texture when the DDL is replayed. It has to be separately ref counted bc the lazy proxy + // can outlive the DDL. + class LazyProxyData : public SkRefCnt { + public: + // Upon being replayed - this field will be filled in (by the DrawingManager) with the proxy + // backing the destination SkSurface. Note that, since there is no good place to clear it + // it can become a dangling pointer. + GrRenderTargetProxy* fReplayDest = nullptr; + }; +#else + class LazyProxyData : public SkRefCnt {}; +#endif + + SkDeferredDisplayList(const SkSurfaceCharacterization& characterization, + sk_sp<LazyProxyData>); + const SkSurfaceCharacterization& characterization() const { return fCharacterization; } - // TODO: remove this. It is just scaffolding to get something up & running - bool draw(SkSurface*) const; - private: + friend class GrDrawingManager; // for access to 'fOpLists' and 'fLazyProxyData' + friend class SkDeferredDisplayListRecorder; // for access to 'fLazyProxyData' + const SkSurfaceCharacterization fCharacterization; - // TODO: actually store the GPU opLists - sk_sp<SkImage> fImage; +#ifdef SK_RASTER_RECORDER_IMPLEMENTATION + sk_sp<SkImage> fImage; +#else + +#if SK_SUPPORT_GPU + SkTArray<sk_sp<GrOpList>> fOpLists; +#endif + sk_sp<LazyProxyData> fLazyProxyData; + +#endif }; #endif diff --git a/include/private/SkSurfaceCharacterization.h b/include/private/SkSurfaceCharacterization.h index 40be90c685..07838968b9 100644 --- a/include/private/SkSurfaceCharacterization.h +++ b/include/private/SkSurfaceCharacterization.h @@ -10,14 +10,18 @@ #include "GrTypes.h" +#include "SkColorSpace.h" +#include "SkRefCnt.h" #include "SkSurfaceProps.h" class SkColorSpace; -#if SK_SUPPORT_GPU -#include "GrTypesPriv.h" +// This define can be used to swap between the default (raster) DDL implementation and the +// gpu implementation. +#define SK_RASTER_RECORDER_IMPLEMENTATION 1 -class GrContextThreadSafeProxy; +#if SK_SUPPORT_GPU +#include "GrContext.h" /** \class SkSurfaceCharacterization A surface characterization contains all the information Ganesh requires to makes its internal diff --git a/src/core/SkDeferredDisplayList.cpp b/src/core/SkDeferredDisplayList.cpp new file mode 100644 index 0000000000..c4cf0686e6 --- /dev/null +++ b/src/core/SkDeferredDisplayList.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkDeferredDisplayList.h" + +#include "SkCanvas.h" +#include "SkSurface.h" + +#ifndef SK_RASTER_RECORDER_IMPLEMENTATION +SkDeferredDisplayList::SkDeferredDisplayList(const SkSurfaceCharacterization& characterization, + sk_sp<LazyProxyData> lazyProxyData) + : fCharacterization(characterization) + , fLazyProxyData(std::move(lazyProxyData)) { +} +#endif + +#ifdef SK_RASTER_RECORDER_IMPLEMENTATION +// Placeholder. Ultimately, the SkSurface_Gpu will pass the wrapped opLists to its +// renderTargetContext. +bool SkDeferredDisplayList::draw(SkSurface* surface) const { + surface->getCanvas()->drawImage(fImage.get(), 0, 0); + return true; +} +#endif diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp index 3f703733bc..b5442c69f8 100644 --- a/src/core/SkDeferredDisplayListRecorder.cpp +++ b/src/core/SkDeferredDisplayListRecorder.cpp @@ -9,7 +9,12 @@ #if SK_SUPPORT_GPU #include "GrContextPriv.h" +#include "GrProxyProvider.h" +#include "GrTexture.h" + +#include "SkGpuDevice.h" #include "SkGr.h" +#include "SkSurface_Gpu.h" #endif #include "SkCanvas.h" // TODO: remove @@ -22,6 +27,17 @@ SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder( : fCharacterization(characterization) { } +SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() { +#if SK_SUPPORT_GPU && !defined(SK_RASTER_RECORDER_IMPLEMENTATION) + auto proxyProvider = fContext->contextPriv().proxyProvider(); + + // DDL TODO: Remove this. DDL contexts should allow for deletion while still having live + // uniquely keyed proxies. + proxyProvider->removeAllUniqueKeys(); +#endif +} + + bool SkDeferredDisplayListRecorder::init() { SkASSERT(!fSurface); @@ -32,7 +48,11 @@ bool SkDeferredDisplayListRecorder::init() { fCharacterization.refColorSpace()); fSurface = SkSurface::MakeRaster(ii, &fCharacterization.surfaceProps()); + return SkToBool(fSurface.get()); #else + SkASSERT(!fLazyProxyData); + +#if SK_SUPPORT_GPU if (!fContext) { fContext = GrContextPriv::MakeDDL(fCharacterization.contextInfo()); if (!fContext) { @@ -40,21 +60,51 @@ bool SkDeferredDisplayListRecorder::init() { } } - SkColorType colorType = kUnknown_SkColorType; - if (!GrPixelConfigToColorType(fCharacterization.config(), &colorType)) { - return false; - } + fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>( + new SkDeferredDisplayList::LazyProxyData); - const SkImageInfo ii = SkImageInfo::Make(fCharacterization.width(), fCharacterization.height(), - colorType, kPremul_SkAlphaType, - fCharacterization.refColorSpace()); + auto proxyProvider = fContext->contextPriv().proxyProvider(); - fSurface = SkSurface::MakeRenderTarget(fContext.get(), SkBudgeted::kYes, - ii, fCharacterization.stencilCount(), - fCharacterization.origin(), - &fCharacterization.surfaceProps()); -#endif + GrSurfaceDesc desc; + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fOrigin = fCharacterization.origin(); + desc.fWidth = fCharacterization.width(); + desc.fHeight = fCharacterization.height(); + desc.fConfig = fCharacterization.config(); + desc.fSampleCnt = fCharacterization.stencilCount(); + + sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData; + + // What we're doing here is we're creating a lazy proxy to back the SkSurface. The lazy + // proxy, when instantiated, will use the GrTexture that backs the SkSurface that the + // DDL is being replayed into. + + sk_sp<GrSurfaceProxy> proxy = proxyProvider->createLazyProxy( + [ lazyProxyData ] (GrResourceProvider* resourceProvider, GrSurfaceOrigin* /* outOrigin */) { + if (!resourceProvider) { + return sk_sp<GrTexture>(); + } + + // The proxy backing the destination surface had better have been instantiated + // prior to the proxy backing the DLL's surface. Steal its GrTexture. + // DDL TODO: What do we do in the case where the Surface we're replaying into + // isn't texturable? + SkASSERT(lazyProxyData->fReplayDest->priv().peekTexture()); + return sk_ref_sp<GrTexture>(lazyProxyData->fReplayDest->priv().peekTexture()); + }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kYes); + + sk_sp<GrSurfaceContext> c = fContext->contextPriv().makeWrappedSurfaceContext( + std::move(proxy), + fCharacterization.refColorSpace(), + &fCharacterization.surfaceProps()); + fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(), + sk_ref_sp(c->asRenderTargetContext())); return SkToBool(fSurface.get()); +#else + return false; +#endif + +#endif } SkCanvas* SkDeferredDisplayListRecorder::getCanvas() { @@ -68,6 +118,7 @@ SkCanvas* SkDeferredDisplayListRecorder::getCanvas() { } std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { +#ifdef SK_RASTER_RECORDER_IMPLEMENTATION sk_sp<SkImage> img = fSurface->makeImageSnapshot(); fSurface.reset(); @@ -75,11 +126,19 @@ std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { // in the SkDeferredDisplayList. return std::unique_ptr<SkDeferredDisplayList>( new SkDeferredDisplayList(fCharacterization, std::move(img))); -} +#else + +#if SK_SUPPORT_GPU + auto ddl = std::unique_ptr<SkDeferredDisplayList>( + new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData))); + + fContext->contextPriv().moveOpListsToDDL(ddl.get()); + return ddl; +#else + return nullptr; +#endif + +#endif // SK_RASTER_RECORDER_IMPLEMENTATION -// Placeholder. Ultimately, the SkSurface_Gpu will pass the wrapped opLists to its -// renderTargetContext. -bool SkDeferredDisplayList::draw(SkSurface* surface) const { - surface->getCanvas()->drawImage(fImage.get(), 0, 0); - return true; } + diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 0d7705dea3..b427e70beb 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -914,6 +914,15 @@ void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBO fContext->fDrawingManager->addOnFlushCallbackObject(onFlushCBObject); } +void GrContextPriv::moveOpListsToDDL(SkDeferredDisplayList* ddl) { + fContext->fDrawingManager->moveOpListsToDDL(ddl); +} + +void GrContextPriv::copyOpListsFromDDL(const SkDeferredDisplayList* ddl, + GrRenderTargetProxy* newDest) { + fContext->fDrawingManager->copyOpListsFromDDL(ddl, newDest); +} + static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) { switch (config) { case kAlpha_8_GrPixelConfig: diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index cf74e70fd6..bd0931cc08 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -17,6 +17,8 @@ class GrSemaphore; class GrSurfaceProxy; class GrTextureContext; +class SkDeferredDisplayList; + /** 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. */ @@ -183,6 +185,9 @@ public: GrAtlasGlyphCache* getAtlasGlyphCache() { return fContext->fAtlasGlyphCache; } GrTextBlobCache* getTextBlobCache() { return fContext->fTextBlobCache.get(); } + void moveOpListsToDDL(SkDeferredDisplayList*); + void copyOpListsFromDDL(const SkDeferredDisplayList*, GrRenderTargetProxy* newDest); + private: explicit GrContextPriv(GrContext* context) : fContext(context) {} GrContextPriv(const GrContextPriv&); // unimpl diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 616ac581e4..3bcff1106b 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -24,6 +24,8 @@ #include "GrTextureOpList.h" #include "GrTextureProxy.h" #include "GrTextureProxyPriv.h" + +#include "SkDeferredDisplayList.h" #include "SkSurface_Gpu.h" #include "SkTTopoSort.h" @@ -320,6 +322,22 @@ void GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlush fOnFlushCBObjects.push_back(onFlushCBObject); } +void GrDrawingManager::moveOpListsToDDL(SkDeferredDisplayList* ddl) { +#ifndef SK_RASTER_RECORDER_IMPLEMENTATION + ddl->fOpLists = std::move(fOpLists); +#endif +} + +void GrDrawingManager::copyOpListsFromDDL(const SkDeferredDisplayList* ddl, + GrRenderTargetProxy* newDest) { +#ifndef SK_RASTER_RECORDER_IMPLEMENTATION + // Here we jam the proxy that backs the current replay SkSurface into the LazyProxyData. + // The lazy proxy that references it (in the copied opLists) will steal its GrTexture. + ddl->fLazyProxyData->fReplayDest = newDest; + fOpLists.push_back_n(ddl->fOpLists.count(), ddl->fOpLists.begin()); +#endif +} + sk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* rtp, bool managedOpList) { SkASSERT(fContext); diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h index 2b01fc3119..58b755f005 100644 --- a/src/gpu/GrDrawingManager.h +++ b/src/gpu/GrDrawingManager.h @@ -79,6 +79,9 @@ public: void addOnFlushCallbackObject(GrOnFlushCallbackObject*); void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*); + void moveOpListsToDDL(SkDeferredDisplayList* ddl); + void copyOpListsFromDDL(const SkDeferredDisplayList*, GrRenderTargetProxy* newDest); + private: GrDrawingManager(GrContext* context, const GrPathRendererChain::Options& optionsForPathRendererChain, diff --git a/src/gpu/GrGpuResourceRef.cpp b/src/gpu/GrGpuResourceRef.cpp index b4703830ec..532e0655d8 100644 --- a/src/gpu/GrGpuResourceRef.cpp +++ b/src/gpu/GrGpuResourceRef.cpp @@ -125,115 +125,3 @@ void GrGpuResourceRef::removeRef() const { fResource->unref(); fOwnRef = false; } - -/////////////////////////////////////////////////////////////////////////////// -#include "GrTextureProxy.h" - -GrSurfaceProxyRef::GrSurfaceProxyRef() { - fProxy = nullptr; - fOwnRef = false; - fPendingIO = false; -} - -GrSurfaceProxyRef::GrSurfaceProxyRef(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { - fProxy = nullptr; - fOwnRef = false; - fPendingIO = false; - this->setProxy(std::move(proxy), ioType); -} - -GrSurfaceProxyRef::~GrSurfaceProxyRef() { - this->reset(); -} - -void GrSurfaceProxyRef::reset() { - if (fPendingIO) { - SkASSERT(fProxy); - switch (fIOType) { - case kRead_GrIOType: - fProxy->completedRead(); - break; - case kWrite_GrIOType: - fProxy->completedWrite(); - break; - case kRW_GrIOType: - fProxy->completedRead(); - fProxy->completedWrite(); - break; - } - fPendingIO = false; - } - if (fOwnRef) { - SkASSERT(fProxy); - fProxy->unref(); - fOwnRef = false; - } - - fProxy = nullptr; -} - -void GrSurfaceProxyRef::setProxy(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { - SkASSERT(!fPendingIO); - SkASSERT(SkToBool(fProxy) == fOwnRef); - SkSafeUnref(fProxy); - if (!proxy) { - fProxy = nullptr; - fOwnRef = false; - } else { - fProxy = proxy.release(); // due to the semantics of this class we unpack from sk_sp - fOwnRef = true; - fIOType = ioType; - } -} - -void GrSurfaceProxyRef::markPendingIO() const { - // This should only be called when the owning GrProgramElement gets its first - // pendingExecution ref. - SkASSERT(!fPendingIO); - SkASSERT(fProxy); - fPendingIO = true; - switch (fIOType) { - case kRead_GrIOType: - fProxy->addPendingRead(); - break; - case kWrite_GrIOType: - fProxy->addPendingWrite(); - break; - case kRW_GrIOType: - fProxy->addPendingRead(); - fProxy->addPendingWrite(); - break; - } -} - -void GrSurfaceProxyRef::pendingIOComplete() const { - // This should only be called when the owner's pending executions have ocurred but it is still - // reffed. - SkASSERT(fOwnRef); - SkASSERT(fPendingIO); - switch (fIOType) { - case kRead_GrIOType: - fProxy->completedRead(); - break; - case kWrite_GrIOType: - fProxy->completedWrite(); - break; - case kRW_GrIOType: - fProxy->completedRead(); - fProxy->completedWrite(); - break; - - } - fPendingIO = false; -} - -void GrSurfaceProxyRef::removeRef() const { - // This should only be called once, when the owners last ref goes away and - // there is a pending execution. - SkASSERT(fOwnRef); - SkASSERT(fPendingIO); - SkASSERT(fProxy); - fProxy->unref(); - fOwnRef = false; -} - diff --git a/src/gpu/GrGpuResourceRef.h b/src/gpu/GrGpuResourceRef.h index f9e122d9e8..410513944f 100644 --- a/src/gpu/GrGpuResourceRef.h +++ b/src/gpu/GrGpuResourceRef.h @@ -87,65 +87,6 @@ private: typedef SkNoncopyable INHERITED; }; -class GrSurfaceProxy; - -class GrSurfaceProxyRef : SkNoncopyable { -public: - virtual ~GrSurfaceProxyRef(); - - GrSurfaceProxy* get() const { return fProxy; } - - /** Does this object own a pending read or write on the resource it is wrapping. */ - bool ownsPendingIO() const { return fPendingIO; } - - /** What type of IO does this represent? This is independent of whether a normal ref or a - pending IO is currently held. */ - GrIOType ioType() const { return fIOType; } - - /** Shortcut for calling setProxy() with NULL. It cannot be called after markingPendingIO - is called. */ - void reset(); - -protected: - GrSurfaceProxyRef(); - - /** ioType expresses what type of IO operations will be marked as - pending on the resource when markPendingIO is called. */ - GrSurfaceProxyRef(sk_sp<GrSurfaceProxy>, GrIOType); - - /** ioType expresses what type of IO operations will be marked as - pending on the resource when markPendingIO is called. */ - void setProxy(sk_sp<GrSurfaceProxy>, GrIOType); - -private: - /** Called by owning GrProgramElement when the program element is first scheduled for - execution. It can only be called once. */ - void markPendingIO() const; - - /** Called when the program element/draw state is no longer owned by GrOpList-client code. - This lets the cache know that the drawing code will no longer schedule additional reads or - writes to the resource using the program element or draw state. It can only be called once. - */ - void removeRef() const; - - /** Called to indicate that the previous pending IO is complete. Useful when the owning object - still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously - pending executions have been complete. Can only be called if removeRef() was not previously - called. */ - void pendingIOComplete() const; - - friend class GrResourceIOProcessor; - friend class GrOpList; // for setProxy - - GrSurfaceProxy* fProxy; - mutable bool fOwnRef; - mutable bool fPendingIO; - GrIOType fIOType; - - typedef SkNoncopyable INHERITED; -}; - - /** * Templated version of GrGpuResourceRef to enforce type safety. */ @@ -233,4 +174,5 @@ private: T* fResource; }; + #endif diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 9fae1b01ef..c87d4ff262 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -17,6 +17,7 @@ #include "GrSamplerState.h" #include "GrShaderVar.h" #include "GrSurfaceProxyPriv.h" +#include "GrSurfaceProxyRef.h" #include "GrTextureProxy.h" #include "SkMath.h" #include "SkString.h" diff --git a/src/gpu/GrSurfaceProxyRef.cpp b/src/gpu/GrSurfaceProxyRef.cpp new file mode 100644 index 0000000000..ad13e4a450 --- /dev/null +++ b/src/gpu/GrSurfaceProxyRef.cpp @@ -0,0 +1,118 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrSurfaceProxyRef.h" +#include "GrTextureProxy.h" + +GrSurfaceProxyRef::GrSurfaceProxyRef() { + fProxy = nullptr; + fOwnRef = false; + fPendingIO = false; +} + +GrSurfaceProxyRef::GrSurfaceProxyRef(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { + fProxy = nullptr; + fOwnRef = false; + fPendingIO = false; + this->setProxy(std::move(proxy), ioType); +} + +GrSurfaceProxyRef::~GrSurfaceProxyRef() { + this->reset(); +} + +void GrSurfaceProxyRef::reset() { + if (fPendingIO) { + SkASSERT(fProxy); + switch (fIOType) { + case kRead_GrIOType: + fProxy->completedRead(); + break; + case kWrite_GrIOType: + fProxy->completedWrite(); + break; + case kRW_GrIOType: + fProxy->completedRead(); + fProxy->completedWrite(); + break; + } + fPendingIO = false; + } + if (fOwnRef) { + SkASSERT(fProxy); + fProxy->unref(); + fOwnRef = false; + } + + fProxy = nullptr; +} + +void GrSurfaceProxyRef::setProxy(sk_sp<GrSurfaceProxy> proxy, GrIOType ioType) { + SkASSERT(!fPendingIO); + SkASSERT(SkToBool(fProxy) == fOwnRef); + SkSafeUnref(fProxy); + if (!proxy) { + fProxy = nullptr; + fOwnRef = false; + } else { + fProxy = proxy.release(); // due to the semantics of this class we unpack from sk_sp + fOwnRef = true; + fIOType = ioType; + } +} + +void GrSurfaceProxyRef::markPendingIO() const { + // This should only be called when the owning GrProgramElement gets its first + // pendingExecution ref. + SkASSERT(!fPendingIO); + SkASSERT(fProxy); + fPendingIO = true; + switch (fIOType) { + case kRead_GrIOType: + fProxy->addPendingRead(); + break; + case kWrite_GrIOType: + fProxy->addPendingWrite(); + break; + case kRW_GrIOType: + fProxy->addPendingRead(); + fProxy->addPendingWrite(); + break; + } +} + +void GrSurfaceProxyRef::pendingIOComplete() const { + // This should only be called when the owner's pending executions have ocurred but it is still + // reffed. + SkASSERT(fOwnRef); + SkASSERT(fPendingIO); + switch (fIOType) { + case kRead_GrIOType: + fProxy->completedRead(); + break; + case kWrite_GrIOType: + fProxy->completedWrite(); + break; + case kRW_GrIOType: + fProxy->completedRead(); + fProxy->completedWrite(); + break; + + } + fPendingIO = false; +} + +void GrSurfaceProxyRef::removeRef() const { + // This should only be called once, when the owners last ref goes away and + // there is a pending execution. + SkASSERT(fOwnRef); + SkASSERT(fPendingIO); + SkASSERT(fProxy); + fProxy->unref(); + fOwnRef = false; +} + diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index ab2a64f707..9f7ec3b7f5 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -200,9 +200,17 @@ bool SkSurface_Gpu::onDraw(const SkDeferredDisplayList* ddl) { return false; } +#ifdef SK_RASTER_RECORDER_IMPLEMENTATION // Ultimately need to pass opLists from the DeferredDisplayList on to the // SkGpuDevice's renderTargetContext. return ddl->draw(this); +#else + GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext(); + GrContext* ctx = fDevice->context(); + + ctx->contextPriv().copyOpListsFromDDL(ddl, rtc->asRenderTargetProxy()); + return true; +#endif } |