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:
parent
d1443efcb8
commit
7ee385e1dc
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user