From 7ee385e1dc3cd6a47dc8f7297fef6e175eaba224 Mon Sep 17 00:00:00 2001 From: Robert Phillips Date: Thu, 30 Mar 2017 08:02:11 -0400 Subject: [PATCH] Add GrSurfaceProxy* parameter to GrContext::flush Split out of: https://skia-review.googlesource.com/c/10284/ (Omnibus: Remove GrSurface-derived classes from ops) Change-Id: I12c66a6fa826c2363b21ece56391fb352d12d6b3 Reviewed-on: https://skia-review.googlesource.com/10541 Reviewed-by: Brian Salomon Commit-Queue: Robert Phillips --- include/gpu/GrContext.h | 22 +----- include/private/GrSurfaceProxy.h | 21 +++++- src/gpu/GrContext.cpp | 69 ++++++++++++------- src/gpu/GrContextPriv.h | 31 +++++++++ src/gpu/GrDrawingManager.cpp | 23 ++++--- src/gpu/GrDrawingManager.h | 13 ++-- src/gpu/GrRenderTargetContext.cpp | 11 +-- src/gpu/GrSurfaceProxyPriv.h | 5 ++ src/gpu/GrTextureContext.cpp | 14 ++-- src/gpu/effects/GrTextureStripAtlas.cpp | 2 +- src/gpu/gl/GrGLTexture.cpp | 3 +- src/image/SkImage_Gpu.cpp | 16 ++--- tests/GLProgramsTest.cpp | 4 +- tests/ProxyRefTest.cpp | 89 +++++++++++++------------ 14 files changed, 190 insertions(+), 133 deletions(-) diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index bd9c079fa0..ccd27286c7 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -34,6 +34,7 @@ class GrResourceEntry; class GrResourceCache; class GrResourceProvider; class GrSamplerParams; +class GrSurfaceProxy; class GrTextBlobCache; class GrTextContext; class GrTextureProxy; @@ -307,27 +308,6 @@ public: size_t rowBytes, uint32_t pixelOpsFlags = 0); - /** - * After this returns any pending writes to the surface will have been issued to the backend 3D API. - */ - void flushSurfaceWrites(GrSurface* surface); - - /** - * After this returns any pending reads or writes to the surface will have been issued to the - * backend 3D API. - */ - void flushSurfaceIO(GrSurface* surface); - - /** - * Finalizes all pending reads and writes to the surface and also performs an MSAA resolve - * if necessary. - * - * It is not necessary to call this before reading the render target via Skia/GrContext. - * GrContext will detect when it must perform a resolve before reading pixels back from the - * surface or using it as a texture. - */ - void prepareSurfaceForExternalIO(GrSurface*); - /** * An ID associated with this context, guaranteed to be unique. */ diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 0443227d3c..3c65cd84ce 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -107,6 +107,14 @@ protected: return SkToBool(fPendingWrites | fPendingReads); } + bool internalHasPendingWrite() const { + if (fTarget) { + return fTarget->internalHasPendingWrite(); + } + + return SkToBool(fPendingWrites); + } + // For deferred proxies this will be null. For wrapped proxies it will point to the // wrapped resource. GrSurface* fTarget; @@ -195,6 +203,10 @@ public: class UniqueID { public: + static UniqueID InvalidID() { + return UniqueID(uint32_t(SK_InvalidUniqueID)); + } + // wrapped explicit UniqueID(const GrGpuResource::UniqueID& id) : fID(id.asUInt()) { } // deferred @@ -209,10 +221,13 @@ public: return !(*this == other); } + void makeInvalid() { fID = SK_InvalidUniqueID; } bool isInvalid() const { return SK_InvalidUniqueID == fID; } private: - const uint32_t fID; + explicit UniqueID(uint32_t id) : fID(id) {} + + uint32_t fID; }; /* @@ -329,6 +344,10 @@ protected: return this->internalHasPendingIO(); } + bool hasPendingWrite() const { + return this->internalHasPendingWrite(); + } + // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource. GrSurfaceDesc fDesc; SkBackingFit fFit; // always exact for wrapped resources diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index fbfaa22609..98f709a962 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -26,12 +26,16 @@ #include "effects/GrConfigConversionEffect.h" #include "text/GrTextBlobCache.h" +#define ASSERT_OWNED_PROXY_PRIV(P) \ +SkASSERT(!(P) || !((P)->priv().peekTexture()) || (P)->priv().peekTexture()->getContext() == fContext) + #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) #define ASSERT_SINGLE_OWNER \ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fSingleOwner);) #define ASSERT_SINGLE_OWNER_PRIV \ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fContext->fSingleOwner);) #define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; } +#define RETURN_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return; } #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; } #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; } @@ -226,7 +230,16 @@ void GrContext::TextBlobCacheOverBudgetCB(void* data) { void GrContext::flush() { ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED - fDrawingManager->flush(); + + fDrawingManager->flush(nullptr); +} + +void GrContextPriv::flush(GrSurfaceProxy* proxy) { + ASSERT_SINGLE_OWNER_PRIV + RETURN_IF_ABANDONED_PRIV + ASSERT_OWNED_PROXY_PRIV(proxy); + + fContext->fDrawingManager->flush(proxy); } bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes, @@ -296,7 +309,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa } if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().hasPendingIO()) { - this->flush(); + this->contextPriv().flush(nullptr); // MDB TODO: tighten this } sk_sp tempProxy; @@ -336,13 +349,13 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa return false; } } + if (tempProxy->priv().hasPendingIO()) { + this->contextPriv().flush(tempProxy.get()); + } GrTexture* texture = tempProxy->instantiate(this->resourceProvider()); if (!texture) { return false; } - if (texture->surfacePriv().hasPendingIO()) { - this->flush(); - } if (applyPremulToSrc) { size_t tmpRowBytes = 4 * width; tmpPixels.reset(width * height); @@ -381,7 +394,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa nullptr); if (kFlushWrites_PixelOp & pixelOpsFlags) { - this->flushSurfaceWrites(surface); + this->contextPriv().flushSurfaceWrites(renderTargetContext->asRenderTargetProxy()); } } } @@ -425,7 +438,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, } if (!(kDontFlush_PixelOpsFlag & flags) && src->surfacePriv().hasPendingWrite()) { - this->flush(); + this->contextPriv().flush(nullptr); // MDB TODO: tighten this } bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); @@ -452,6 +465,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, } sk_sp surfaceToRead(SkRef(src)); + sk_sp drawnProxy; bool didTempDraw = false; if (GrGpu::kNoDraw_DrawPreference != drawPreference) { if (SkBackingFit::kExact == tempDrawInfo.fTempSurfaceFit) { @@ -500,7 +514,8 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); tempRTC->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect, nullptr); - surfaceToRead.reset(tempRTC->asTexture().release()); + drawnProxy = tempRTC->asTextureProxyRef(); + surfaceToRead = sk_ref_sp(drawnProxy->instantiate(this->resourceProvider())); left = 0; top = 0; didTempDraw = true; @@ -517,7 +532,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, } GrPixelConfig configToRead = dstConfig; if (didTempDraw) { - this->flushSurfaceWrites(surfaceToRead.get()); + this->contextPriv().flushSurfaceWrites(drawnProxy.get()); configToRead = tempDrawInfo.fReadConfig; } if (!fGpu->readPixels(surfaceToRead.get(), left, top, width, height, configToRead, buffer, @@ -542,27 +557,31 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, return true; } -void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) { - ASSERT_SINGLE_OWNER - RETURN_IF_ABANDONED - SkASSERT(surface); - ASSERT_OWNED_RESOURCE(surface); - fDrawingManager->prepareSurfaceForExternalIO(surface); +void GrContextPriv::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) { + ASSERT_SINGLE_OWNER_PRIV + RETURN_IF_ABANDONED_PRIV + SkASSERT(proxy); + ASSERT_OWNED_PROXY_PRIV(proxy); + fContext->fDrawingManager->prepareSurfaceForExternalIO(proxy); } -void GrContext::flushSurfaceWrites(GrSurface* surface) { - ASSERT_SINGLE_OWNER - RETURN_IF_ABANDONED - if (surface->surfacePriv().hasPendingWrite()) { - this->flush(); +void GrContextPriv::flushSurfaceWrites(GrSurfaceProxy* proxy) { + ASSERT_SINGLE_OWNER_PRIV + RETURN_IF_ABANDONED_PRIV + SkASSERT(proxy); + ASSERT_OWNED_PROXY_PRIV(proxy); + if (proxy->priv().hasPendingWrite()) { + this->flush(proxy); } } -void GrContext::flushSurfaceIO(GrSurface* surface) { - ASSERT_SINGLE_OWNER - RETURN_IF_ABANDONED - if (surface->surfacePriv().hasPendingIO()) { - this->flush(); +void GrContextPriv::flushSurfaceIO(GrSurfaceProxy* proxy) { + ASSERT_SINGLE_OWNER_PRIV + RETURN_IF_ABANDONED_PRIV + SkASSERT(proxy); + ASSERT_OWNED_PROXY_PRIV(proxy); + if (proxy->priv().hasPendingIO()) { + this->flush(proxy); } } diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 3357636605..0f77ec2d4c 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -59,12 +59,43 @@ public: bool disableGpuYUVConversion() const { return fContext->fDisableGpuYUVConversion; } + /** + * Call to ensure all drawing to the context has been issued to the + * underlying 3D API. + * The 'proxy' parameter is a hint. If it is supplied the context will guarantee that + * the draws required for that proxy are flushed but it could do more. If no 'proxy' is + * provided then all current work will be flushed. + */ + void flush(GrSurfaceProxy*); + /* * A ref will be taken on the preFlushCallbackObject which will be removed when the * context is destroyed. */ void addPreFlushCallbackObject(sk_sp); + /** + * After this returns any pending writes to the surface will have been issued to the + * backend 3D API. + */ + void flushSurfaceWrites(GrSurfaceProxy*); + + /** + * After this returns any pending reads or writes to the surface will have been issued to the + * backend 3D API. + */ + void flushSurfaceIO(GrSurfaceProxy*); + + /** + * Finalizes all pending reads and writes to the surface and also performs an MSAA resolve + * if necessary. + * + * It is not necessary to call this before reading the render target via Skia/GrContext. + * GrContext will detect when it must perform a resolve before reading pixels back from the + * surface or using it as a texture. + */ + void prepareSurfaceForExternalIO(GrSurfaceProxy*); + private: explicit GrContextPriv(GrContext* context) : fContext(context) {} GrContextPriv(const GrContextPriv&); // unimpl diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 449cae6b61..b64b9ee23a 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -14,6 +14,7 @@ #include "GrResourceProvider.h" #include "GrSoftwarePathRenderer.h" #include "GrSurfacePriv.h" +#include "GrSurfaceProxyPriv.h" #include "GrTextureContext.h" #include "GrTextureOpList.h" #include "SkSurface_Gpu.h" @@ -69,7 +70,8 @@ void GrDrawingManager::reset() { fFlushState.reset(); } -void GrDrawingManager::internalFlush(GrResourceCache::FlushType type) { +// MDB TODO: make use of the 'proxy' parameter. +void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType type) { if (fFlushing || this->wasAbandoned()) { return; } @@ -171,20 +173,23 @@ void GrDrawingManager::internalFlush(GrResourceCache::FlushType type) { fFlushing = false; } -void GrDrawingManager::prepareSurfaceForExternalIO(GrSurface* surface) { +void GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) { if (this->wasAbandoned()) { return; } - SkASSERT(surface); - SkASSERT(surface->getContext() == fContext); + SkASSERT(proxy); - if (surface->surfacePriv().hasPendingIO()) { - this->flush(); + if (proxy->priv().hasPendingIO()) { + this->flush(proxy); } - GrRenderTarget* rt = surface->asRenderTarget(); - if (fContext->getGpu() && rt) { - fContext->getGpu()->resolveRenderTarget(rt); + GrSurface* surface = proxy->instantiate(fContext->resourceProvider()); + if (!surface) { + return; + } + + if (fContext->getGpu() && surface->asRenderTarget()) { + fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget()); } } diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h index d914b03a75..f30273f7f1 100644 --- a/src/gpu/GrDrawingManager.h +++ b/src/gpu/GrDrawingManager.h @@ -58,15 +58,15 @@ public: void flushIfNecessary() { if (fContext->getResourceCache()->requestsFlush()) { - this->internalFlush(GrResourceCache::kCacheRequested); + this->internalFlush(nullptr, GrResourceCache::kCacheRequested); } else if (fIsImmediateMode) { - this->internalFlush(GrResourceCache::kImmediateMode); + this->internalFlush(nullptr, GrResourceCache::kImmediateMode); } } static bool ProgramUnitTest(GrContext* context, int maxStages); - void prepareSurfaceForExternalIO(GrSurface*); + void prepareSurfaceForExternalIO(GrSurfaceProxy*); void addPreFlushCallbackObject(sk_sp preFlushCBObject); @@ -91,10 +91,13 @@ private: void abandon(); void cleanup(); void reset(); - void flush() { this->internalFlush(GrResourceCache::FlushType::kExternal); } - void internalFlush(GrResourceCache::FlushType); + void flush(GrSurfaceProxy* proxy) { + this->internalFlush(proxy, GrResourceCache::FlushType::kExternal); + } + void internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType); 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 static const int kNumPixelGeometries = 5; // The different pixel geometries diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index babdb1a566..13413287d7 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -1334,16 +1334,7 @@ void GrRenderTargetContext::prepareForExternalIO() { SkDEBUGCODE(this->validate();) GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::prepareForExternalIO"); - // Deferral of the VRAM resources must end in this instance anyway - sk_sp rt( - sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider()))); - if (!rt) { - return; - } - - ASSERT_OWNED_RESOURCE(rt); - - this->drawingManager()->prepareSurfaceForExternalIO(rt.get()); + this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get()); } void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip, diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h index 64f1dc5f40..24c69939b7 100644 --- a/src/gpu/GrSurfaceProxyPriv.h +++ b/src/gpu/GrSurfaceProxyPriv.h @@ -26,6 +26,11 @@ public: // future when the proxy is actually used/instantiated. bool hasPendingIO() const { return fProxy->hasPendingIO(); } + // Beware! This call is only guaranteed to tell you if the proxy in question has + // any pending writes in its current state. It won't tell you about the IO state in the + // future when the proxy is actually used/instantiated. + bool hasPendingWrite() const { return fProxy->hasPendingWrite(); } + // Don't abuse this call!!!!!!! bool isExact() const { return SkBackingFit::kExact == fProxy->fFit; } diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp index bc48e8eeb1..00cc97cf53 100644 --- a/src/gpu/GrTextureContext.cpp +++ b/src/gpu/GrTextureContext.cpp @@ -6,6 +6,8 @@ */ #include "GrTextureContext.h" + +#include "GrContextPriv.h" #include "GrDrawingManager.h" #include "GrResourceProvider.h" #include "GrTextureOpList.h" @@ -76,18 +78,18 @@ bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy, SkDEBUGCODE(this->validate();) GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copy"); +#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. + fContext->contextPriv().flushSurfaceWrites(srcProxy); +#endif + // TODO: defer instantiation until flush time sk_sp src(sk_ref_sp(srcProxy->instantiate(fContext->resourceProvider()))); 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. - fContext->flushSurfaceWrites(src.get()); -#endif - // TODO: this needs to be fixed up since it ends the deferrable of the GrTexture sk_sp tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider()))); if (!tex) { diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp index 0f6ca58204..5785be2a26 100644 --- a/src/gpu/effects/GrTextureStripAtlas.cpp +++ b/src/gpu/effects/GrTextureStripAtlas.cpp @@ -122,7 +122,7 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) { if (nullptr == row) { // force a flush, which should unlock all the rows; then try again - fDesc.fContext->flush(); + fDesc.fContext->contextPriv().flush(nullptr); // tighten this up? row = this->getLRU(); if (nullptr == row) { --fLockedRows; diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp index 2f75001680..95c8c8fa5e 100644 --- a/src/gpu/gl/GrGLTexture.cpp +++ b/src/gpu/gl/GrGLTexture.cpp @@ -116,8 +116,7 @@ GrBackendObject GrGLTexture::getTextureHandle() const { } std::unique_ptr GrGLTexture::detachBackendTexture() { - // Flush any pending writes to this texture - this->getContext()->prepareSurfaceForExternalIO(this); + SkASSERT(!this->hasPendingIO()); // Set up a semaphore to be signaled once the data is ready, and flush GL sk_sp semaphore = this->getContext()->resourceProvider()->makeSemaphore(); diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 1dcc69c041..9c9aaa79b3 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -142,16 +142,15 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) GrBackendObject SkImage_Gpu::onGetTextureHandle(bool flushPendingGrContextIO, GrSurfaceOrigin* origin) const { - GrTextureProxy* proxy = this->peekProxy(); - SkASSERT(proxy); + SkASSERT(fProxy); - GrSurface* surface = proxy->instantiate(fContext->resourceProvider()); + GrSurface* surface = fProxy->instantiate(fContext->resourceProvider()); if (surface && surface->asTexture()) { if (flushPendingGrContextIO) { - fContext->prepareSurfaceForExternalIO(surface); + fContext->contextPriv().prepareSurfaceForExternalIO(fProxy.get()); } if (origin) { - *origin = surface->origin(); + *origin = fProxy->origin(); } return surface->asTexture()->getTextureHandle(); } @@ -364,10 +363,10 @@ static sk_sp make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect); - if (!renderTargetContext->accessRenderTarget()) { + if (!renderTargetContext->asSurfaceProxy()) { return nullptr; } - ctx->flushSurfaceWrites(renderTargetContext->accessRenderTarget()); + ctx->contextPriv().flushSurfaceWrites(renderTargetContext->asSurfaceProxy()); // MDB: this call is okay bc we know 'renderTargetContext' was exact return sk_make_sp(ctx, kNeedNewImageUniqueID, @@ -460,6 +459,7 @@ std::unique_ptr SkCrossContextImageData::MakeFromEncode desc.fConfig = texture->config(); desc.fSampleCnt = 0; + context->contextPriv().prepareSurfaceForExternalIO(as_IB(textureImage)->peekProxy()); auto textureData = texture->texturePriv().detachBackendTexture(); SkASSERT(textureData); @@ -866,7 +866,7 @@ sk_sp SkImage_Gpu::onMakeColorSpace(sk_sp colorSpace) con renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect); - if (!renderTargetContext->accessRenderTarget()) { + if (!renderTargetContext->asTextureProxy()) { return nullptr; } diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index a8434eca86..125f5d064c 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -340,7 +340,7 @@ bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages) { std::move(op), uss, snapToCenters); } // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes) - drawingManager->flush(); + drawingManager->flush(nullptr); // Validate that GrFPs work correctly without an input. sk_sp renderTargetContext(context->makeRenderTargetContext( @@ -372,7 +372,7 @@ bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages) { renderTargetContext->priv().testingOnly_addMeshDrawOp( std::move(grPaint), GrAAType::kNone, std::move(op)); - drawingManager->flush(); + drawingManager->flush(nullptr); } } diff --git a/tests/ProxyRefTest.cpp b/tests/ProxyRefTest.cpp index 67132a1a21..f5fe6a4047 100644 --- a/tests/ProxyRefTest.cpp +++ b/tests/ProxyRefTest.cpp @@ -10,6 +10,7 @@ #include "Test.h" #if SK_SUPPORT_GPU +#include "GrContextPriv.h" #include "GrRenderTargetPriv.h" #include "GrRenderTargetProxy.h" #include "GrResourceProvider.h" @@ -49,7 +50,7 @@ int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const { static const int kWidthHeight = 128; static void check_refs(skiatest::Reporter* reporter, - GrSurfaceProxy* proxy, + GrTextureProxy* proxy, int32_t expectedProxyRefs, int32_t expectedBackingRefs, int32_t expectedNumReads, @@ -65,7 +66,7 @@ static void check_refs(skiatest::Reporter* reporter, SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); } -static sk_sp make_deferred(GrContext* context) { +static sk_sp make_deferred(GrContext* context) { GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidthHeight; @@ -76,7 +77,7 @@ static sk_sp make_deferred(GrContext* context) { SkBackingFit::kApprox, SkBudgeted::kYes); } -static sk_sp make_wrapped(GrContext* context) { +static sk_sp make_wrapped(GrContext* context) { GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidthHeight; @@ -85,10 +86,12 @@ static sk_sp make_wrapped(GrContext* context) { sk_sp tex(context->resourceProvider()->createTexture(desc, SkBudgeted::kNo)); + sk_sp proxy = GrSurfaceProxy::MakeWrapped(std::move(tex)); + // Flush the IOWrite from the initial discard or it will confuse the later ref count checks - context->flushSurfaceWrites(tex.get()); + context->contextPriv().flushSurfaceWrites(proxy.get()); - return GrSurfaceProxy::MakeWrapped(std::move(tex)); + return proxy; } DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) { @@ -100,108 +103,108 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) { for (auto make : { make_deferred, make_wrapped }) { // A single write { - sk_sp sProxy((*make)(ctxInfo.grContext())); + sk_sp proxy((*make)(ctxInfo.grContext())); - GrPendingIOResource fWrite(sProxy.get()); + GrPendingIOResource fWrite(proxy.get()); - check_refs(reporter, sProxy.get(), 1, 1, 0, 1); + check_refs(reporter, proxy.get(), 1, 1, 0, 1); // In the deferred case, the discard op created on instantiation adds an // extra ref and write - bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + bool proxyGetsDiscardRef = !proxy->isWrapped_ForTesting() && caps.discardRenderTargetSupport(); int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0); - sProxy->instantiate(provider); + proxy->instantiate(provider); // In the deferred case, this checks that the refs transfered to the GrSurface - check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites); + check_refs(reporter, proxy.get(), 1, 1, 0, expectedWrites); } // A single read { - sk_sp sProxy((*make)(ctxInfo.grContext())); + sk_sp proxy((*make)(ctxInfo.grContext())); - GrPendingIOResource fRead(sProxy.get()); + GrPendingIOResource fRead(proxy.get()); - check_refs(reporter, sProxy.get(), 1, 1, 1, 0); + check_refs(reporter, proxy.get(), 1, 1, 1, 0); // In the deferred case, the discard op created on instantiation adds an // extra ref and write - bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + bool proxyGetsDiscardRef = !proxy->isWrapped_ForTesting() && caps.discardRenderTargetSupport(); int expectedWrites = proxyGetsDiscardRef ? kWritesForDiscard : 0; - sProxy->instantiate(provider); + proxy->instantiate(provider); // In the deferred case, this checks that the refs transfered to the GrSurface - check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); + check_refs(reporter, proxy.get(), 1, 1, 1, expectedWrites); } // A single read/write pair { - sk_sp sProxy((*make)(ctxInfo.grContext())); + sk_sp proxy((*make)(ctxInfo.grContext())); - GrPendingIOResource fRW(sProxy.get()); + GrPendingIOResource fRW(proxy.get()); - check_refs(reporter, sProxy.get(), 1, 1, 1, 1); + check_refs(reporter, proxy.get(), 1, 1, 1, 1); // In the deferred case, the discard op created on instantiation adds an // extra ref and write - bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + bool proxyGetsDiscardRef = !proxy->isWrapped_ForTesting() && caps.discardRenderTargetSupport(); int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0); - sProxy->instantiate(provider); + proxy->instantiate(provider); // In the deferred case, this checks that the refs transferred to the GrSurface - check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); + check_refs(reporter, proxy.get(), 1, 1, 1, expectedWrites); } // Multiple normal refs { - sk_sp sProxy((*make)(ctxInfo.grContext())); - sProxy->ref(); - sProxy->ref(); + sk_sp proxy((*make)(ctxInfo.grContext())); + proxy->ref(); + proxy->ref(); - check_refs(reporter, sProxy.get(), 3, 3, 0, 0); + check_refs(reporter, proxy.get(), 3, 3, 0, 0); - bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + bool proxyGetsDiscardRef = !proxy->isWrapped_ForTesting() && caps.discardRenderTargetSupport(); int expectedWrites = proxyGetsDiscardRef ? kWritesForDiscard : 0; - sProxy->instantiate(provider); + proxy->instantiate(provider); // In the deferred case, this checks that the refs transferred to the GrSurface - check_refs(reporter, sProxy.get(), 3, 3, 0, expectedWrites); + check_refs(reporter, proxy.get(), 3, 3, 0, expectedWrites); - sProxy->unref(); - sProxy->unref(); + proxy->unref(); + proxy->unref(); } // Continue using (reffing) proxy after instantiation { - sk_sp sProxy((*make)(ctxInfo.grContext())); - sProxy->ref(); + sk_sp proxy((*make)(ctxInfo.grContext())); + proxy->ref(); - GrPendingIOResource fWrite(sProxy.get()); + GrPendingIOResource fWrite(proxy.get()); - check_refs(reporter, sProxy.get(), 2, 2, 0, 1); + check_refs(reporter, proxy.get(), 2, 2, 0, 1); - bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + bool proxyGetsDiscardRef = !proxy->isWrapped_ForTesting() && caps.discardRenderTargetSupport(); int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0); - sProxy->instantiate(provider); + proxy->instantiate(provider); // In the deferred case, this checks that the refs transfered to the GrSurface - check_refs(reporter, sProxy.get(), 2, 2, 0, expectedWrites); + check_refs(reporter, proxy.get(), 2, 2, 0, expectedWrites); - sProxy->unref(); - check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites); + proxy->unref(); + check_refs(reporter, proxy.get(), 1, 1, 0, expectedWrites); - GrPendingIOResource fRead(sProxy.get()); - check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); + GrPendingIOResource fRead(proxy.get()); + check_refs(reporter, proxy.get(), 1, 1, 1, expectedWrites); } } } -- 2.34.1