diff --git a/gn/gpu.gni b/gn/gpu.gni index 2b3423244e..92dc7d6092 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -122,8 +122,8 @@ skia_gpu_sources = [ "$_src/gpu/GrPathUtils.cpp", "$_src/gpu/GrPathUtils.h", "$_src/gpu/GrPendingProgramElement.h", - "$_src/gpu/GrPreFlushResourceProvider.cpp", - "$_src/gpu/GrPreFlushResourceProvider.h", + "$_src/gpu/GrOnFlushResourceProvider.cpp", + "$_src/gpu/GrOnFlushResourceProvider.h", "$_src/gpu/GrPipeline.cpp", "$_src/gpu/GrPipeline.h", "$_src/gpu/GrPipelineBuilder.h", diff --git a/gn/tests.gni b/gn/tests.gni index be4389be4f..a0343f5b26 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -156,7 +156,7 @@ tests_sources = [ "$_tests/PDFMetadataAttributeTest.cpp", "$_tests/PDFOpaqueSrcModeToSrcOverTest.cpp", "$_tests/PDFPrimitivesTest.cpp", - "$_tests/PreFlushCallbackTest.cpp", + "$_tests/OnFlushCallbackTest.cpp", "$_tests/PictureBBHTest.cpp", "$_tests/PictureShaderTest.cpp", "$_tests/PictureTest.cpp", diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index aa245b5672..2d46b5c02b 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -750,8 +750,8 @@ sk_sp GrContextPriv::makeBackendTextureAsRenderTargetRend surfaceProps); } -void GrContextPriv::addPreFlushCallbackObject(sk_sp preFlushCBObject) { - fContext->fDrawingManager->addPreFlushCallbackObject(std::move(preFlushCBObject)); +void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) { + fContext->fDrawingManager->addOnFlushCallbackObject(onFlushCBObject); } diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 08b26e56d5..c5f592b875 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -14,7 +14,7 @@ class GrBackendRenderTarget; class GrSemaphore; class GrSurfaceProxy; -class GrPreFlushCallbackObject; +class GrOnFlushCallbackObject; /** 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 @@ -76,11 +76,15 @@ public: */ void flush(GrSurfaceProxy*); - /* - * A ref will be taken on the preFlushCallbackObject which will be removed when the - * context is destroyed. + /** + * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.) + * + * NOTE: the drawing manager tracks this object as a raw pointer; it is up to the caller to + * ensure its lifetime is tied to that of the context. */ - void addPreFlushCallbackObject(sk_sp); + void addOnFlushCallbackObject(GrOnFlushCallbackObject*); + + void testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject*); /** * After this returns any pending writes to the surface will have been issued to the diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 9cc584527a..5b8d37b37d 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -101,9 +101,9 @@ void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType SkASSERT(result); #endif - GrPreFlushResourceProvider preFlushProvider(this); + GrOnFlushResourceProvider onFlushProvider(this); - if (fPreFlushCBObjects.count()) { + if (!fOnFlushCBObjects.empty()) { // MDB TODO: pre-MDB '1' is the correct pre-allocated size. Post-MDB it will need // to be larger. SkAutoSTArray<1, uint32_t> opListIds(fOpLists.count()); @@ -112,10 +112,10 @@ void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType } SkSTArray<1, sk_sp> renderTargetContexts; - for (int i = 0; i < fPreFlushCBObjects.count(); ++i) { - fPreFlushCBObjects[i]->preFlush(&preFlushProvider, - opListIds.get(), opListIds.count(), - &renderTargetContexts); + for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) { + onFlushCBObject->preFlush(&onFlushProvider, + opListIds.get(), opListIds.count(), + &renderTargetContexts); if (!renderTargetContexts.count()) { continue; // This is fine. No atlases of this type are required for this flush } @@ -178,6 +178,9 @@ void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType if (flushed || type == GrResourceCache::FlushType::kCacheRequested) { fContext->getResourceCache()->notifyFlushOccurred(type); } + for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) { + onFlushCBObject->postFlush(); + } fFlushing = false; } @@ -201,8 +204,8 @@ void GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) { } } -void GrDrawingManager::addPreFlushCallbackObject(sk_sp preFlushCBObject) { - fPreFlushCBObjects.push_back(preFlushCBObject); +void GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) { + fOnFlushCBObjects.push_back(onFlushCBObject); } sk_sp GrDrawingManager::newRTOpList(sk_sp rtp) { diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h index 1990f9d923..85a29df420 100644 --- a/src/gpu/GrDrawingManager.h +++ b/src/gpu/GrDrawingManager.h @@ -11,7 +11,7 @@ #include "GrOpFlushState.h" #include "GrPathRenderer.h" #include "GrPathRendererChain.h" -#include "GrPreFlushResourceProvider.h" +#include "GrOnFlushResourceProvider.h" #include "GrRenderTargetOpList.h" #include "GrResourceCache.h" #include "SkTArray.h" @@ -71,7 +71,8 @@ public: void prepareSurfaceForExternalIO(GrSurfaceProxy*); - void addPreFlushCallbackObject(sk_sp preFlushCBObject); + void addOnFlushCallbackObject(GrOnFlushCallbackObject*); + void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*); private: GrDrawingManager(GrContext* context, @@ -99,7 +100,7 @@ private: friend class GrContext; // for access to: ctor, abandon, reset & flush friend class GrContextPriv; // access to: flush - friend class GrPreFlushResourceProvider; // this is just a shallow wrapper around this class + friend class GrOnFlushResourceProvider; // this is just a shallow wrapper around this class static const int kNumPixelGeometries = 5; // The different pixel geometries static const int kNumDFTOptions = 2; // DFT or no DFT @@ -123,7 +124,7 @@ private: bool fIsImmediateMode; - SkTArray> fPreFlushCBObjects; + SkTArray fOnFlushCBObjects; // Lazily allocated std::unique_ptr fInstancingAllocator; diff --git a/src/gpu/GrPreFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp similarity index 94% rename from src/gpu/GrPreFlushResourceProvider.cpp rename to src/gpu/GrOnFlushResourceProvider.cpp index 43037be3ab..377c1f6bc6 100644 --- a/src/gpu/GrPreFlushResourceProvider.cpp +++ b/src/gpu/GrOnFlushResourceProvider.cpp @@ -5,12 +5,12 @@ * found in the LICENSE file. */ -#include "GrPreFlushResourceProvider.h" +#include "GrOnFlushResourceProvider.h" #include "GrDrawingManager.h" #include "GrSurfaceProxy.h" -sk_sp GrPreFlushResourceProvider::makeRenderTargetContext( +sk_sp GrOnFlushResourceProvider::makeRenderTargetContext( const GrSurfaceDesc& desc, sk_sp colorSpace, const SkSurfaceProps* props) { @@ -54,7 +54,7 @@ sk_sp GrPreFlushResourceProvider::makeRenderTargetContext // TODO: we only need this entry point as long as we have to pre-allocate the atlas. // Remove it ASAP. -sk_sp GrPreFlushResourceProvider::makeRenderTargetContext( +sk_sp GrOnFlushResourceProvider::makeRenderTargetContext( sk_sp proxy, sk_sp colorSpace, const SkSurfaceProps* props) { diff --git a/src/gpu/GrPreFlushResourceProvider.h b/src/gpu/GrOnFlushResourceProvider.h similarity index 65% rename from src/gpu/GrPreFlushResourceProvider.h rename to src/gpu/GrOnFlushResourceProvider.h index 5f4b96bd25..b29dc9c73e 100644 --- a/src/gpu/GrPreFlushResourceProvider.h +++ b/src/gpu/GrOnFlushResourceProvider.h @@ -5,19 +5,16 @@ * found in the LICENSE file. */ -#ifndef GrPreFlushResourceProvider_DEFINED -#define GrPreFlushResourceProvider_DEFINED +#ifndef GrOnFlushResourceProvider_DEFINED +#define GrOnFlushResourceProvider_DEFINED #include "GrTypes.h" -#include "GrNonAtomicRef.h" - -// These two are just for GrPreFlushCallbackObject #include "SkRefCnt.h" -#include "SkTDArray.h" +#include "SkTArray.h" class GrDrawingManager; class GrOpList; -class GrPreFlushResourceProvider; +class GrOnFlushResourceProvider; class GrRenderTargetOpList; class GrRenderTargetContext; class GrSurfaceProxy; @@ -27,32 +24,38 @@ class SkSurfaceProps; /* * This is the base class from which all pre-flush callback objects must be derived. It - * provides the "preFlush" interface. + * provides the "preFlush" / "postFlush" interface. */ -class GrPreFlushCallbackObject : public GrNonAtomicRef { +class GrOnFlushCallbackObject { public: - virtual ~GrPreFlushCallbackObject() { } + virtual ~GrOnFlushCallbackObject() { } /* - * The preFlush callback allows subsystems (e.g., text, path renderers) to create atlases + * The onFlush callback allows subsystems (e.g., text, path renderers) to create atlases * for a specific flush. All the GrOpList IDs required for the flush are passed into the * callback. The callback should return the render target contexts used to render the atlases * in 'results'. */ - virtual void preFlush(GrPreFlushResourceProvider*, + virtual void preFlush(GrOnFlushResourceProvider*, const uint32_t* opListIDs, int numOpListIDs, SkTArray>* results) = 0; + /** + * Called once flushing is complete and all ops indicated by preFlush have been executed and + * released. + */ + virtual void postFlush() {} + private: typedef SkRefCnt INHERITED; }; /* * This class is a shallow wrapper around the drawing manager. It is passed into the - * preFlush callbacks and is intended to limit the functionality available to them. + * onFlush callbacks and is intended to limit the functionality available to them. * It should never have additional data members or virtual methods. */ -class GrPreFlushResourceProvider { +class GrOnFlushResourceProvider { public: sk_sp makeRenderTargetContext(const GrSurfaceDesc& desc, sk_sp colorSpace, @@ -65,9 +68,9 @@ public: const SkSurfaceProps* props); private: - explicit GrPreFlushResourceProvider(GrDrawingManager* drawingMgr) : fDrawingMgr(drawingMgr) {} - GrPreFlushResourceProvider(const GrPreFlushResourceProvider&); // unimpl - GrPreFlushResourceProvider& operator=(const GrPreFlushResourceProvider&); // unimpl + explicit GrOnFlushResourceProvider(GrDrawingManager* drawingMgr) : fDrawingMgr(drawingMgr) {} + GrOnFlushResourceProvider(const GrOnFlushResourceProvider&) = delete; + GrOnFlushResourceProvider& operator=(const GrOnFlushResourceProvider&) = delete; GrDrawingManager* fDrawingMgr; diff --git a/tests/PreFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp similarity index 97% rename from tests/PreFlushCallbackTest.cpp rename to tests/OnFlushCallbackTest.cpp index fc736a4647..4adcad93c6 100644 --- a/tests/PreFlushCallbackTest.cpp +++ b/tests/OnFlushCallbackTest.cpp @@ -12,7 +12,7 @@ #include "GrClip.h" #include "GrContextPriv.h" #include "GrDefaultGeoProcFactory.h" -#include "GrPreFlushResourceProvider.h" +#include "GrOnFlushResourceProvider.h" #include "GrRenderTargetContextPriv.h" #include "GrResourceProvider.h" #include "GrQuad.h" @@ -244,7 +244,7 @@ static const int kAtlasTileSize = 2; /* * This class aggregates the op information required for atlasing */ -class AtlasObject final : public GrPreFlushCallbackObject { +class AtlasObject final : public GrOnFlushCallbackObject { public: AtlasObject() : fDone(false) { } @@ -299,7 +299,7 @@ public: /* * This callback back creates the atlas and updates the AtlasedRectOps to read from it */ - void preFlush(GrPreFlushResourceProvider* resourceProvider, + void preFlush(GrOnFlushResourceProvider* resourceProvider, const uint32_t* opListIDs, int numOpListIDs, SkTArray>* results) override { SkASSERT(!results->count()); @@ -530,7 +530,7 @@ static void test_color(skiatest::Reporter* reporter, const SkBitmap& bm, int x, * Note: until MDB lands, the atlas will actually have width= 9*kAtlasTileSize and look like: * R G B C M Y K Grey White */ -DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(PreFlushCallbackTest, reporter, ctxInfo) { +DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(OnFlushCallbackTest, reporter, ctxInfo) { static const int kNumProxies = 3; GrContext* context = ctxInfo.grContext(); @@ -540,19 +540,19 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(PreFlushCallbackTest, reporter, ctxInfo) { return; } - sk_sp object = sk_make_sp(); + AtlasObject object; // For now (until we add a GrSuperDeferredSimpleTextureEffect), we create the final atlas // proxy ahead of time. sk_sp atlasDest = pre_create_atlas(context); - object->setAtlasDest(atlasDest); + object.setAtlasDest(atlasDest); - context->contextPriv().addPreFlushCallbackObject(object); + context->contextPriv().addOnFlushCallbackObject(&object); sk_sp proxies[kNumProxies]; for (int i = 0; i < kNumProxies; ++i) { - proxies[i] = make_upstream_image(context, object.get(), i*3, atlasDest); + proxies[i] = make_upstream_image(context, &object, i*3, atlasDest); } static const int kFinalWidth = 6*kDrawnTileSize; @@ -592,7 +592,9 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(PreFlushCallbackTest, reporter, ctxInfo) { readBack.rowBytes(), 0, 0); SkASSERT(result); - object->markAsDone(); + context->contextPriv().testingOnly_flushAndRemoveOnFlushCallbackObject(&object); + + object.markAsDone(); #if 0 save_bm(readBack, "atlas-final-image.png"); diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index f5459b1bba..6dc21bb836 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -9,6 +9,7 @@ #include "GrBackendSurface.h" #include "GrContextOptions.h" +#include "GrContextPriv.h" #include "GrDrawOpAtlas.h" #include "GrDrawingManager.h" #include "GrGpuResourceCacheAccess.h" @@ -26,6 +27,8 @@ #include "text/GrAtlasGlyphCache.h" #include "text/GrTextBlobCache.h" +#include + namespace GrTest { void SetupAlwaysEvictAtlas(GrContext* context) { // These sizes were selected because they allow each atlas to hold a single plot and will thus @@ -436,3 +439,15 @@ void GrContext::initMockContext() { // resources in the buffer pools. fDrawingManager->abandon(); } + +void GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) { + fContext->flush(); + fContext->fDrawingManager->testingOnly_removeOnFlushCallbackObject(cb); +} + +void GrDrawingManager::testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject* cb) { + int n = std::find(fOnFlushCBObjects.begin(), fOnFlushCBObjects.end(), cb) - + fOnFlushCBObjects.begin(); + SkASSERT(n < fOnFlushCBObjects.count()); + fOnFlushCBObjects.removeShuffle(n); +}