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 <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2017-03-30 08:02:11 -04:00 committed by Skia Commit-Bot
parent d1443efcb8
commit 7ee385e1dc
14 changed files with 191 additions and 134 deletions

View File

@ -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.
*/

View File

@ -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

View File

@ -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<GrTextureProxy> 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<GrSurface> surfaceToRead(SkRef(src));
sk_sp<GrTextureProxy> 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);
}
}

View File

@ -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<GrPreFlushCallbackObject>);
/**
* 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

View File

@ -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());
}
}

View File

@ -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<GrPreFlushCallbackObject> 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

View File

@ -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<GrRenderTarget> 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,

View File

@ -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; }

View File

@ -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<GrSurface> 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<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider())));
if (!tex) {

View File

@ -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;

View File

@ -116,8 +116,7 @@ GrBackendObject GrGLTexture::getTextureHandle() const {
}
std::unique_ptr<GrExternalTextureData> 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<GrSemaphore> semaphore = this->getContext()->resourceProvider()->makeSemaphore();

View File

@ -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<SkImage> 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<SkImage_Gpu>(ctx, kNeedNewImageUniqueID,
@ -460,6 +459,7 @@ std::unique_ptr<SkCrossContextImageData> 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> SkImage_Gpu::onMakeColorSpace(sk_sp<SkColorSpace> colorSpace) con
renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
if (!renderTargetContext->accessRenderTarget()) {
if (!renderTargetContext->asTextureProxy()) {
return nullptr;
}

View File

@ -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<GrRenderTargetContext> 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);
}
}

View File

@ -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<GrSurfaceProxy> make_deferred(GrContext* context) {
static sk_sp<GrTextureProxy> make_deferred(GrContext* context) {
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = kWidthHeight;
@ -76,7 +77,7 @@ static sk_sp<GrSurfaceProxy> make_deferred(GrContext* context) {
SkBackingFit::kApprox, SkBudgeted::kYes);
}
static sk_sp<GrSurfaceProxy> make_wrapped(GrContext* context) {
static sk_sp<GrTextureProxy> make_wrapped(GrContext* context) {
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = kWidthHeight;
@ -85,10 +86,12 @@ static sk_sp<GrSurfaceProxy> make_wrapped(GrContext* context) {
sk_sp<GrTexture> tex(context->resourceProvider()->createTexture(desc, SkBudgeted::kNo));
// Flush the IOWrite from the initial discard or it will confuse the later ref count checks
context->flushSurfaceWrites(tex.get());
sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex));
return GrSurfaceProxy::MakeWrapped(std::move(tex));
// Flush the IOWrite from the initial discard or it will confuse the later ref count checks
context->contextPriv().flushSurfaceWrites(proxy.get());
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<GrSurfaceProxy> sProxy((*make)(ctxInfo.grContext()));
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get());
GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> 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<GrSurfaceProxy> sProxy((*make)(ctxInfo.grContext()));
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get());
GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> 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<GrSurfaceProxy> sProxy((*make)(ctxInfo.grContext()));
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(sProxy.get());
GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> 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<GrSurfaceProxy> sProxy((*make)(ctxInfo.grContext()));
sProxy->ref();
sProxy->ref();
sk_sp<GrTextureProxy> 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<GrSurfaceProxy> sProxy((*make)(ctxInfo.grContext()));
sProxy->ref();
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
proxy->ref();
GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get());
GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> 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<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get());
check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites);
GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
check_refs(reporter, proxy.get(), 1, 1, 1, expectedWrites);
}
}
}