Make instantiate return a Boolean

From an off-line conversation:
The longer term idea will be to create a helper class isolates the
ability to instantiate proxies until flush time. The peek* methods
could then be moved to GrSurfaceProxy.

Change-Id: I8e8c02c098475b77d515791c0d6b81f7e4a327dd
Reviewed-on: https://skia-review.googlesource.com/18076
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Robert Phillips 2017-06-05 09:26:07 -04:00 committed by Skia Commit-Bot
parent 9beafc41af
commit eee4d6e4e8
22 changed files with 112 additions and 98 deletions

View File

@ -24,13 +24,7 @@ public:
const GrRenderTargetProxy* asRenderTargetProxy() const override { return this; }
// Actually instantiate the backing rendertarget, if necessary.
GrSurface* instantiate(GrResourceProvider* resourceProvider) override;
GrRenderTarget* instantiateRenderTarget(GrResourceProvider* resourceProvider) {
if (auto surf = this->instantiate(resourceProvider)) {
return surf->asRenderTarget();
}
return nullptr;
}
bool instantiate(GrResourceProvider* resourceProvider) override;
GrFSAAType fsaaType() const {
if (!fSampleCnt) {

View File

@ -244,7 +244,7 @@ public:
*/
UniqueID uniqueID() const { return fUniqueID; }
virtual GrSurface* instantiate(GrResourceProvider* resourceProvider) = 0;
virtual bool instantiate(GrResourceProvider* resourceProvider) = 0;
/**
* Helper that gets the width and height of the surface as a bounding rectangle.
@ -347,9 +347,9 @@ protected:
return this->internalHasPendingWrite();
}
GrSurface* instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt,
GrSurfaceFlags flags, bool isMipMapped,
SkDestinationSurfaceColorMode mipColorMode);
bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt,
GrSurfaceFlags flags, bool isMipMapped,
SkDestinationSurfaceColorMode mipColorMode);
// For wrapped resources, 'fConfig', 'fWidth', 'fHeight', and 'fOrigin; will always be filled in
// from the wrapped resource.

View File

@ -22,13 +22,7 @@ public:
const GrTextureProxy* asTextureProxy() const override { return this; }
// Actually instantiate the backing texture, if necessary
GrSurface* instantiate(GrResourceProvider*) override;
GrTexture* instantiateTexture(GrResourceProvider* resourceProvider) {
if (auto surf = this->instantiate(resourceProvider)) {
return surf->asTexture();
}
return nullptr;
}
bool instantiate(GrResourceProvider*) override;
void setMipColorMode(SkDestinationSurfaceColorMode colorMode);

View File

@ -198,11 +198,11 @@ sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context,
SkASSERT(context);
{
// MDB TODO: remove this
// Chrome is crashing with proxies when they need to be instantiated.
// Force an instantiation here (where, in olden days, we used to require a GrTexture)
// to see if the input is already un-instantiable.
GrTexture* temp = srcProxy->instantiateTexture(context->resourceProvider());
if (!temp) {
if (!srcProxy->instantiate(context->resourceProvider())) {
return nullptr;
}
}

View File

@ -308,11 +308,12 @@ bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst,
ASSERT_OWNED_PROXY_PRIV(dst->asSurfaceProxy());
GR_AUDIT_TRAIL_AUTO_FRAME(&fContext->fAuditTrail, "GrContextPriv::writeSurfacePixels");
GrSurface* dstSurface = dst->asSurfaceProxy()->instantiate(fContext->resourceProvider());
if (!dstSurface) {
if (!dst->asSurfaceProxy()->instantiate(fContext->resourceProvider())) {
return false;
}
GrSurface* dstSurface = dst->asSurfaceProxy()->priv().peekSurface();
// The src is unpremul but the dst is premul -> premul the src before or as part of the write
const bool premul = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
if (!valid_pixel_conversion(srcConfig, dstSurface->config(), premul)) {
@ -389,10 +390,10 @@ bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst,
if (tempProxy->priv().hasPendingIO()) {
this->flush(tempProxy.get());
}
GrTexture* texture = tempProxy->instantiateTexture(fContext->resourceProvider());
if (!texture) {
if (!tempProxy->instantiate(fContext->resourceProvider())) {
return false;
}
GrTexture* texture = tempProxy->priv().peekTexture();
if (!fContext->fGpu->writePixels(texture, 0, 0, width, height, tempDrawInfo.fWriteConfig,
buffer, rowBytes)) {
return false;
@ -435,11 +436,12 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src,
GR_AUDIT_TRAIL_AUTO_FRAME(&fContext->fAuditTrail, "GrContextPriv::readSurfacePixels");
// MDB TODO: delay this instantiation until later in the method
GrSurface* srcSurface = src->asSurfaceProxy()->instantiate(fContext->resourceProvider());
if (!srcSurface) {
if (!src->asSurfaceProxy()->instantiate(fContext->resourceProvider())) {
return false;
}
GrSurface* srcSurface = src->asSurfaceProxy()->priv().peekSurface();
// The src is premul but the dst is unpremul -> unpremul the src after or as part of the read
bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
if (!valid_pixel_conversion(srcSurface->config(), dstConfig, unpremul)) {
@ -530,11 +532,12 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src,
return false;
}
GrSurface* surfaceToRead = proxyToRead->instantiate(fContext->resourceProvider());
if (!surfaceToRead) {
if (!proxyToRead->instantiate(fContext->resourceProvider())) {
return false;
}
GrSurface* surfaceToRead = proxyToRead->priv().peekSurface();
if (GrGpu::kRequireDraw_DrawPreference == drawPreference && !didTempDraw) {
return false;
}

View File

@ -207,10 +207,10 @@ inline bool GrDrawOpAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, Plo
// MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated.
// Once it is deferred more care must be taken upon instantiation failure.
GrTexture* texture = fProxy->instantiateTexture(fContext->resourceProvider());
if (!texture) {
if (!fProxy->instantiate(fContext->resourceProvider())) {
return false;
}
GrTexture* texture = fProxy->priv().peekTexture();
GrDrawOpUploadToken lastUploadToken = target->addAsapUpload(
[plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) {
@ -286,10 +286,10 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width,
sk_sp<Plot> plotsp(SkRef(newPlot.get()));
// MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated.
// Once it is deferred more care must be taken upon instantiation failure.
GrTexture* texture = fProxy->instantiateTexture(fContext->resourceProvider());
if (!texture) {
if (!fProxy->instantiate(fContext->resourceProvider())) {
return false;
}
GrTexture* texture = fProxy->priv().peekTexture();
GrDrawOpUploadToken lastUploadToken = target->addInlineUpload(
[plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) {

View File

@ -208,11 +208,12 @@ void GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) {
this->flush(proxy);
}
GrSurface* surface = proxy->instantiate(fContext->resourceProvider());
if (!surface) {
if (!proxy->instantiate(fContext->resourceProvider())) {
return;
}
GrSurface* surface = proxy->priv().peekSurface();
if (fContext->getGpu() && surface->asRenderTarget()) {
fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget());
}
@ -327,12 +328,12 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
GrFSAAType::kNone != rtp->fsaaType()) {
// TODO: defer stencil buffer attachment for PathRenderingDrawContext
sk_sp<GrRenderTarget> rt(
sk_ref_sp(rtp->instantiateRenderTarget(fContext->resourceProvider())));
if (!rt) {
if (!rtp->instantiate(fContext->resourceProvider())) {
return nullptr;
}
GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt.get());
GrRenderTarget* rt = rtp->priv().peekRenderTarget();
GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt);
if (sb) {
return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
fContext, this, std::move(rtp),

View File

@ -324,7 +324,10 @@ public:
GrRenderTarget* accessRenderTarget() {
// TODO: usage of this entry point needs to be reduced and potentially eliminated
// since it ends the deferral of the GrRenderTarget's allocation
return fRenderTargetProxy->instantiateRenderTarget(fContext->resourceProvider());
if (!fRenderTargetProxy->instantiate(fContext->resourceProvider())) {
return nullptr;
}
return fRenderTargetProxy->priv().peekRenderTarget();
}
GrSurfaceProxy* asSurfaceProxy() override { return fRenderTargetProxy.get(); }

View File

@ -45,20 +45,19 @@ int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
: 0;
}
GrSurface* GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
GrSurface* surf = this->instantiateImpl(resourceProvider, fSampleCnt, kFlags,
/* isMipped = */ false,
SkDestinationSurfaceColorMode::kLegacy);
if (!surf) {
return nullptr;
if (!this->instantiateImpl(resourceProvider, fSampleCnt, kFlags,
/* isMipped = */ false,
SkDestinationSurfaceColorMode::kLegacy)) {
return false;
}
SkASSERT(surf->asRenderTarget());
SkASSERT(fTarget->asRenderTarget());
// Check that our a priori computation matched the ultimate reality
SkASSERT(fRenderTargetFlags == surf->asRenderTarget()->renderTargetPriv().flags());
SkASSERT(fRenderTargetFlags == fTarget->asRenderTarget()->renderTargetPriv().flags());
return surf;
return true;
}
int GrRenderTargetProxy::worstCaseWidth() const {

View File

@ -313,10 +313,10 @@ void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextur
return;
}
GrTexture* texture = proxy->instantiateTexture(this);
if (!texture) {
if (!proxy->instantiate(this)) {
return;
}
GrTexture* texture = proxy->priv().peekTexture();
this->assignUniqueKeyToResource(key, texture);
}

View File

@ -40,11 +40,11 @@ GrSurfaceProxy::~GrSurfaceProxy() {
SkASSERT(!fLastOpList);
}
GrSurface* GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt,
GrSurfaceFlags flags, bool isMipMapped,
SkDestinationSurfaceColorMode mipColorMode) {
bool GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt,
GrSurfaceFlags flags, bool isMipMapped,
SkDestinationSurfaceColorMode mipColorMode) {
if (fTarget) {
return fTarget;
return true;
}
GrSurfaceDesc desc;
desc.fConfig = fConfig;
@ -64,7 +64,7 @@ GrSurface* GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider,
fTarget = resourceProvider->createTexture(desc, fBudgeted, fFlags).release();
}
if (!fTarget) {
return nullptr;
return false;
}
fTarget->asTexture()->texturePriv().setMipColorMode(mipColorMode);
@ -76,7 +76,7 @@ GrSurface* GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider,
}
#endif
return fTarget;
return true;
}
void GrSurfaceProxy::setLastOpList(GrOpList* opList) {

View File

@ -15,13 +15,21 @@
data members or virtual methods. */
class GrSurfaceProxyPriv {
public:
// This should only be called after a successful call to instantiate
GrSurface* peekSurface() const {
SkASSERT(fProxy->fTarget);
return fProxy->fTarget;
}
// If the proxy is already instantiated, return its backing GrTexture; if not,
// return null
GrTexture* peekTexture() const {
return fProxy->fTarget ? fProxy->fTarget->asTexture() : nullptr;
}
// This should only be called after a successful call to instantiate
GrRenderTarget* peekRenderTarget() const {
SkASSERT(fProxy->fTarget && fProxy->fTarget->asRenderTarget());
return fProxy->fTarget ? fProxy->fTarget->asRenderTarget() : nullptr;
}

View File

@ -21,17 +21,17 @@ GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, S
GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf)
: INHERITED(std::move(surf), SkBackingFit::kExact)
, fIsMipMapped(fTarget->asTexture()->texturePriv().hasMipMaps())
, fMipColorMode(fTarget->asTexture()->texturePriv().mipColorMode()) {}
, fMipColorMode(fTarget->asTexture()->texturePriv().mipColorMode()) {
}
GrSurface* GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
GrSurface* surf =
this->instantiateImpl(resourceProvider, 0, kNone_GrSurfaceFlags, fIsMipMapped,
fMipColorMode);
if (!surf) {
return nullptr;
bool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
if (!this->instantiateImpl(resourceProvider, 0, kNone_GrSurfaceFlags, fIsMipMapped,
fMipColorMode)) {
return false;
}
SkASSERT(surf->asTexture());
return surf;
SkASSERT(fTarget->asTexture());
return true;
}
void GrTextureProxy::setMipColorMode(SkDestinationSurfaceColorMode colorMode) {

View File

@ -44,16 +44,15 @@ size_t GrTextureRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
SkBackingFit::kApprox == fFit);
}
GrSurface* GrTextureRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
bool GrTextureRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag;
GrSurface* surf = this->instantiateImpl(resourceProvider, this->numStencilSamples(), kFlags,
this->isMipMapped(), this->mipColorMode());
if (!surf) {
return nullptr;
if (!this->instantiateImpl(resourceProvider, this->numStencilSamples(), kFlags,
this->isMipMapped(), this->mipColorMode())) {
return false;
}
SkASSERT(surf->asRenderTarget());
SkASSERT(surf->asTexture());
SkASSERT(fTarget->asRenderTarget());
SkASSERT(fTarget->asTexture());
return surf;
return true;
}

View File

@ -32,7 +32,7 @@ private:
// Wrapped version
GrTextureRenderTargetProxy(sk_sp<GrSurface>);
GrSurface* instantiate(GrResourceProvider*) override;
bool instantiate(GrResourceProvider*) override;
size_t onUninstantiatedGpuMemorySize() const override;
};

View File

@ -28,8 +28,7 @@ public:
// MDB TODO: remove this instantiation once instantiation is pushed past the
// TextureSamplers. Instantiation failure in the TextureSampler is difficult to
// recover from.
GrTexture* temp = proxy->instantiateTexture(resourceProvider);
if (!temp) {
if (!proxy->instantiate(resourceProvider)) {
return nullptr;
}
@ -48,8 +47,7 @@ public:
// MDB TODO: remove this instantiation once instantiation is pushed past the
// TextureSamplers. Instantiation failure in the TextureSampler is difficult to
// recover from.
GrTexture* temp = proxy->instantiateTexture(resourceProvider);
if (!temp) {
if (!proxy->instantiate(resourceProvider)) {
return nullptr;
}
@ -67,8 +65,7 @@ public:
// MDB TODO: remove this instantiation once instantiation is pushed past the
// TextureSamplers. Instantiation failure in the TextureSampler is difficult to
// recover from.
GrTexture* temp = proxy->instantiateTexture(resourceProvider);
if (!temp) {
if (!proxy->instantiate(resourceProvider)) {
return nullptr;
}

View File

@ -56,13 +56,13 @@ private:
void onExecute(GrOpFlushState* state) override {
SkASSERT(!state->commandBuffer());
GrSurface* dst = fDst.get()->instantiate(state->resourceProvider());
GrSurface* src = fSrc.get()->instantiate(state->resourceProvider());
if (!dst || !src) {
if (!fDst.get()->instantiate(state->resourceProvider()) ||
!fSrc.get()->instantiate(state->resourceProvider())) {
return;
}
state->gpu()->copySurface(dst, src, fSrcRect, fDstPoint);
state->gpu()->copySurface(fDst.get()->priv().peekSurface(),
fSrc.get()->priv().peekSurface(), fSrcRect, fDstPoint);
}
// For RenderTargetContexts 'fDst' is redundant with the RenderTarget that will be passed

View File

@ -155,15 +155,20 @@ GrBackendObject SkImage_Gpu::onGetTextureHandle(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin) const {
SkASSERT(fProxy);
GrSurface* surface = fProxy->instantiate(fContext->resourceProvider());
if (surface && surface->asTexture()) {
if (!fProxy->instantiate(fContext->resourceProvider())) {
return 0;
}
GrTexture* texture = fProxy->priv().peekTexture();
if (texture) {
if (flushPendingGrContextIO) {
fContext->contextPriv().prepareSurfaceForExternalIO(fProxy.get());
}
if (origin) {
*origin = fProxy->origin();
}
return surface->asTexture()->getTextureHandle();
return texture->getTextureHandle();
}
return 0;
}
@ -174,7 +179,11 @@ GrTexture* SkImage_Gpu::onGetTexture() const {
return nullptr;
}
return proxy->instantiateTexture(fContext->resourceProvider());
if (!proxy->instantiate(fContext->resourceProvider())) {
return nullptr;
}
return proxy->priv().peekTexture();
}
bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
@ -489,10 +498,10 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<Sk
return codecImage;
}
sk_sp<GrTexture> texture(sk_ref_sp(proxy->instantiateTexture(context->resourceProvider())));
if (!texture) {
if (!proxy->instantiate(context->resourceProvider())) {
return codecImage;
}
sk_sp<GrTexture> texture = sk_ref_sp(proxy->priv().peekTexture());
// Flush any writes or uploads
context->contextPriv().prepareSurfaceForExternalIO(proxy.get());

View File

@ -36,7 +36,11 @@ public:
return fProxy.get();
}
GrTexture* peekTexture() const override {
return fProxy->instantiateTexture(fContext->resourceProvider());
if (!fProxy->instantiate(fContext->resourceProvider())) {
return nullptr;
}
return fProxy->priv().peekTexture();
}
sk_sp<GrTextureProxy> asTextureProxyRef() const override {
return fProxy;

View File

@ -16,6 +16,7 @@
#include "GrClipStackClip.h"
#include "GrReducedClip.h"
#include "GrResourceCache.h"
#include "GrSurfaceProxyPriv.h"
#include "GrTextureProxy.h"
typedef GrReducedClip::ElementList ElementList;
typedef GrReducedClip::InitialState InitialState;
@ -1442,7 +1443,8 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ClipMaskCache, reporter, ctxInfo) {
stack.save();
stack.clipPath(path, m, SkClipOp::kIntersect, true);
sk_sp<GrTextureProxy> mask = GrClipStackClip(&stack).testingOnly_createClipMask(context);
GrTexture* tex = mask->instantiateTexture(context->resourceProvider());
mask->instantiate(context->resourceProvider());
GrTexture* tex = mask->priv().peekTexture();
REPORTER_ASSERT(reporter, 0 == strcmp(tex->getUniqueKey().tag(), kTag));
// Make sure mask isn't pinned in cache.
mask.reset(nullptr);

View File

@ -206,10 +206,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ct
return;
}
GrTexture* tex = srcProxy->instantiateTexture(context->resourceProvider());
if (!tex) {
if (!srcProxy->instantiate(context->resourceProvider())) {
return;
}
GrTexture* tex = srcProxy->priv().peekTexture();
GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
kFullSize,

View File

@ -52,8 +52,8 @@ static void check_rendertarget(skiatest::Reporter* reporter,
REPORTER_ASSERT(reporter, rtProxy->numStencilSamples() == numSamples);
GrSurfaceProxy::UniqueID idBefore = rtProxy->uniqueID();
GrRenderTarget* rt = rtProxy->instantiateRenderTarget(provider);
REPORTER_ASSERT(reporter, rt);
REPORTER_ASSERT(reporter, rtProxy->instantiate(provider));
GrRenderTarget* rt = rtProxy->priv().peekRenderTarget();
REPORTER_ASSERT(reporter, rtProxy->uniqueID() == idBefore);
if (wasWrapped) {
@ -86,8 +86,9 @@ static void check_texture(skiatest::Reporter* reporter,
SkBackingFit fit,
bool wasWrapped) {
GrSurfaceProxy::UniqueID idBefore = texProxy->uniqueID();
GrTexture* tex = texProxy->instantiateTexture(provider);
REPORTER_ASSERT(reporter, tex);
REPORTER_ASSERT(reporter, texProxy->instantiate(provider));
GrTexture* tex = texProxy->priv().peekTexture();
REPORTER_ASSERT(reporter, texProxy->uniqueID() == idBefore);
if (wasWrapped) {