diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp index 1f273dc615..a6e0bdfcdd 100644 --- a/gm/image_pict.cpp +++ b/gm/image_pict.cpp @@ -360,8 +360,7 @@ protected: return; } // No API to draw a GrTexture directly, so we cheat and create a private image subclass - sk_sp image(new SkImage_Gpu(cache->info().width(), cache->info().height(), - cache->uniqueID(), kPremul_SkAlphaType, + sk_sp image(new SkImage_Gpu(cache->uniqueID(), kPremul_SkAlphaType, std::move(texture), std::move(texColorSpace), SkBudgeted::kNo)); canvas->drawImage(image.get(), x, y); diff --git a/include/gpu/GrSurfaceContext.h b/include/gpu/GrSurfaceContext.h index ed049be506..109c4a0ffa 100644 --- a/include/gpu/GrSurfaceContext.h +++ b/include/gpu/GrSurfaceContext.h @@ -74,12 +74,12 @@ public: * unsupported pixel config. */ bool readPixels(const SkImageInfo& dstInfo, void* dstBuffer, size_t dstRowBytes, - int x, int y) { - return this->onReadPixels(dstInfo, dstBuffer, dstRowBytes, x, y); + int x, int y, uint32_t flags = 0) { + return this->onReadPixels(dstInfo, dstBuffer, dstRowBytes, x, y, flags); } /** - * Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the + * Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the * renderTargetContext at the specified position. * @param srcInfo image info for the source pixels * @param srcBuffer source for the write @@ -137,7 +137,7 @@ private: const SkIRect& srcRect, const SkIPoint& dstPoint) = 0; virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, - size_t dstRowBytes, int x, int y) = 0; + size_t dstRowBytes, int x, int y, uint32_t flags) = 0; virtual bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes, int x, int y, uint32_t flags) = 0; diff --git a/include/gpu/GrTextureContext.h b/include/gpu/GrTextureContext.h index 6b2f0e379f..d5e1eb9b7c 100644 --- a/include/gpu/GrTextureContext.h +++ b/include/gpu/GrTextureContext.h @@ -48,7 +48,7 @@ private: bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, - size_t dstRowBytes, int x, int y) override; + size_t dstRowBytes, int x, int y, uint32_t flags) override; bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes, int x, int y, uint32_t flags) override; diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index dd06f323fb..31e0f1d1ca 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -331,7 +331,8 @@ protected: // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource. const GrSurfaceDesc fDesc; const SkBackingFit fFit; // always exact for wrapped resources - const SkBudgeted fBudgeted; // set from the backing resource for wrapped resources + mutable SkBudgeted fBudgeted; // set from the backing resource for wrapped resources + // mutable bc of SkSurface/SkImage wishy-washiness const uint32_t fFlags; const UniqueID fUniqueID; // set from the backing resource for wrapped resources diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp index 1940fb9fc7..dc717095a8 100644 --- a/src/core/SkSpecialImage.cpp +++ b/src/core/SkSpecialImage.cpp @@ -353,10 +353,7 @@ static sk_sp wrap_proxy_in_image(GrContext* context, GrTextureProxy* pr return nullptr; } - // Note that we're explicitly using the GrTexture's width & height here b.c. SkImages - // must be tight. - return sk_make_sp(tex->width(), tex->height(), - kNeedNewImageUniqueID, alphaType, + return sk_make_sp(kNeedNewImageUniqueID, alphaType, sk_ref_sp(tex), std::move(colorSpace), SkBudgeted::kYes); } @@ -400,8 +397,7 @@ public: // instantiates itself it is going to have to either be okay with having a larger // than expected backing texture (unlikely) or the 'fit' of the SurfaceProxy needs // to be tightened (if it is deferred). - auto img = sk_sp(new SkImage_Gpu(tex->width(), tex->height(), - this->uniqueID(), fAlphaType, + auto img = sk_sp(new SkImage_Gpu(this->uniqueID(), fAlphaType, sk_ref_sp(tex), fColorSpace, SkBudgeted::kNo)); diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 5937054dcf..051af824b0 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -157,16 +157,16 @@ bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy, // TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext? bool GrRenderTargetContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, - size_t dstRowBytes, int x, int y) { + size_t dstRowBytes, int x, int y, uint32_t flags) { // TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps()); if (kUnknown_GrPixelConfig == config) { return false; } - uint32_t flags = 0; + // TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { - flags = GrContext::kUnpremul_PixelOpsFlag; + flags |= GrContext::kUnpremul_PixelOpsFlag; } // Deferral of the VRAM resources must end in this instance anyway diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 479fc932e8..dc4944abf9 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -469,7 +469,7 @@ private: bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override; bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, - size_t dstRowBytes, int x, int y) override; + size_t dstRowBytes, int x, int y, uint32_t flags) override; bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes, int x, int y, uint32_t flags) override; diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 0c497506e1..180a7f06b2 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -6,6 +6,7 @@ */ #include "GrSurfaceProxy.h" +#include "GrSurfaceProxyPriv.h" #include "GrCaps.h" #include "GrContext.h" @@ -302,3 +303,19 @@ sk_sp GrSurfaceProxy::TestCopy(GrContext* context, const GrSur return dstContext; } + +void GrSurfaceProxyPriv::makeBudgeted() { + if (fProxy->fTarget) { + fProxy->fTarget->resourcePriv().makeBudgeted(); + } + + fProxy->fBudgeted = SkBudgeted::kYes; +} + +void GrSurfaceProxyPriv::makeUnbudgeted() { + if (fProxy->fTarget) { + fProxy->fTarget->resourcePriv().makeUnbudgeted(); + } + + fProxy->fBudgeted = SkBudgeted::kNo; +} diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h index 4e43daea9d..390806f0c0 100644 --- a/src/gpu/GrSurfaceProxyPriv.h +++ b/src/gpu/GrSurfaceProxyPriv.h @@ -23,6 +23,18 @@ public: // Don't abuse this!!!!!!! bool isExact() const { return SkBackingFit::kExact == fProxy->fFit; } + // These next two are very specialized and wacky - don't use them! + + // In the case where an unbudgeted, deferred SkSurface_Gpu has snapped a budgeted, deferred + // SkImage_Gpu, this serves to propagate the budgeting forward in time. For now, and + // presumably forever, this will not change any flushing decisions but may make Ganesh + // appear to have gone over budget. In the case of non-deferred proxies this will immediately + // propagate the budget decision to the resource, which in itself is dubious. + void makeBudgeted(); + // In the case where a budgeted, deferred SkSurface_Gpu has snapped an unbudgeted, deferred + // SkImage_Gpu, this serves to propagate the lack of budgeting forward in time. + void makeUnbudgeted(); + private: explicit GrSurfaceProxyPriv(GrSurfaceProxy* proxy) : fProxy(proxy) {} GrSurfaceProxyPriv(const GrSurfaceProxyPriv&) {} // unimpl diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp index ffcddbc289..0fbc951ff3 100644 --- a/src/gpu/GrTextureContext.cpp +++ b/src/gpu/GrTextureContext.cpp @@ -109,16 +109,16 @@ bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy, // TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext? bool GrTextureContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, - size_t dstRowBytes, int x, int y) { + size_t dstRowBytes, int x, int y, uint32_t flags) { // TODO: teach GrTexture to take ImageInfo directly to specify the src pixels GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps()); if (kUnknown_GrPixelConfig == config) { return false; } - uint32_t flags = 0; + // TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { - flags = GrContext::kUnpremul_PixelOpsFlag; + flags |= GrContext::kUnpremul_PixelOpsFlag; } // Deferral of the VRAM resources must end in this instance anyway diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp index 4f739f3893..de225ccd27 100644 --- a/src/image/SkImageShader.cpp +++ b/src/image/SkImageShader.cpp @@ -154,25 +154,29 @@ sk_sp SkImageShader::asFragmentProcessor(const AsFPArgs& ar GrSamplerParams params(tm, textureFilterMode); sk_sp texColorSpace; SkScalar scaleAdjust[2] = { 1.0f, 1.0f }; - sk_sp texture(as_IB(fImage)->asTextureRef(args.fContext, params, args.fDstColorSpace, - &texColorSpace, scaleAdjust)); - if (!texture) { + sk_sp proxy(as_IB(fImage)->asTextureProxyRef(args.fContext, params, + args.fDstColorSpace, + &texColorSpace, scaleAdjust)); + if (!proxy) { return nullptr; } + bool isAlphaOnly = GrPixelConfigIsAlphaOnly(proxy->config()); + lmInverse.postScale(scaleAdjust[0], scaleAdjust[1]); sk_sp colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(), args.fDstColorSpace); sk_sp inner; if (doBicubic) { - inner = GrBicubicEffect::Make(texture.get(), std::move(colorSpaceXform), lmInverse, tm); + inner = GrBicubicEffect::Make(args.fContext, std::move(proxy), std::move(colorSpaceXform), + lmInverse, tm); } else { - inner = GrSimpleTextureEffect::Make(texture.get(), std::move(colorSpaceXform), - lmInverse, params); + inner = GrSimpleTextureEffect::Make(args.fContext, std::move(proxy), + std::move(colorSpaceXform), lmInverse, params); } - if (GrPixelConfigIsAlphaOnly(texture->config())) { + if (isAlphaOnly) { return inner; } return sk_sp(GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner))); diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h index cc5335833f..e08d7610f7 100644 --- a/src/image/SkImage_Base.h +++ b/src/image/SkImage_Base.h @@ -50,6 +50,9 @@ public: virtual GrTexture* peekTexture() const { return nullptr; } #if SK_SUPPORT_GPU virtual sk_sp asTextureProxyRef() const { return nullptr; } + virtual sk_sp asTextureProxyRef(GrContext*, const GrSamplerParams&, + SkColorSpace*, sk_sp*, + SkScalar scaleAdjust[2]) const = 0; virtual sk_sp refPinnedTexture(uint32_t* uniqueID) const { return nullptr; } #endif virtual SkImageCacherator* peekCacherator() const { return nullptr; } diff --git a/src/image/SkImage_Generator.cpp b/src/image/SkImage_Generator.cpp index 14516e4d5c..ae3f9f83f4 100644 --- a/src/image/SkImage_Generator.cpp +++ b/src/image/SkImage_Generator.cpp @@ -26,7 +26,13 @@ public: return fCache.info().alphaType(); } - bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override; + bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, + CachingHint) const override; +#if SK_SUPPORT_GPU + sk_sp asTextureProxyRef(GrContext*, const GrSamplerParams&, + SkColorSpace*, sk_sp*, + SkScalar scaleAdjust[2]) const override; +#endif SkImageCacherator* peekCacherator() const override { return &fCache; } SkData* onRefEncoded(GrContext*) const override; sk_sp onMakeSubset(const SkIRect&) const override; @@ -77,6 +83,22 @@ bool SkImage_Generator::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpac return fCache.lockAsBitmap(nullptr, bitmap, this, dstColorSpace, chint); } +#if SK_SUPPORT_GPU +sk_sp SkImage_Generator::asTextureProxyRef(GrContext* context, + const GrSamplerParams& params, + SkColorSpace* dstColorSpace, + sk_sp* texColorSpace, + SkScalar scaleAdjust[2]) const { + sk_sp tex(fCache.lockAsTexture(context, params, dstColorSpace, + texColorSpace, this, scaleAdjust)); + if (!tex) { + return nullptr; + } + + return GrSurfaceProxy::MakeWrapped(std::move(tex)); +} +#endif + GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, const GrSamplerParams& params, SkColorSpace* dstColorSpace, sk_sp* texColorSpace, diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 9ca790c300..a3649acf19 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -35,17 +35,27 @@ #include "SkPixelRef.h" #include "SkReadPixelsRec.h" -SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, sk_sp tex, +SkImage_Gpu::SkImage_Gpu(uint32_t uniqueID, SkAlphaType at, sk_sp tex, sk_sp colorSpace, SkBudgeted budgeted) - : INHERITED(w, h, uniqueID) - , fTexture(std::move(tex)) + : INHERITED(tex->width(), tex->height(), uniqueID) + , fContext(tex->getContext()) + , fProxy(GrSurfaceProxy::MakeWrapped(std::move(tex))) , fAlphaType(at) , fBudgeted(budgeted) , fColorSpace(std::move(colorSpace)) - , fAddedRasterVersionToCache(false) -{ - SkASSERT(fTexture->width() == w); - SkASSERT(fTexture->height() == h); + , fAddedRasterVersionToCache(false) { +} + +SkImage_Gpu::SkImage_Gpu(GrContext* context, uint32_t uniqueID, SkAlphaType at, + sk_sp proxy, + sk_sp colorSpace, SkBudgeted budgeted) + : INHERITED(proxy->width(), proxy->height(), uniqueID) + , fContext(context) + , fProxy(std::move(proxy)) + , fAlphaType(at) + , fBudgeted(budgeted) + , fColorSpace(std::move(colorSpace)) + , fAddedRasterVersionToCache(false) { } SkImage_Gpu::~SkImage_Gpu() { @@ -62,10 +72,10 @@ extern void SkTextureImageApplyBudgetedDecision(SkImage* image) { SkImageInfo SkImage_Gpu::onImageInfo() const { SkColorType ct; - if (!GrPixelConfigToColorType(fTexture->config(), &ct)) { + if (!GrPixelConfigToColorType(fProxy->config(), &ct)) { ct = kUnknown_SkColorType; } - return SkImageInfo::Make(fTexture->width(), fTexture->height(), ct, fAlphaType, fColorSpace); + return SkImageInfo::Make(fProxy->width(), fProxy->height(), ct, fAlphaType, fColorSpace); } static SkImageInfo make_info(int w, int h, SkAlphaType at, sk_sp colorSpace) { @@ -81,12 +91,20 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst, SkColorSpace* dstColorSpace, return true; } - if (!dst->tryAllocPixels(make_info(this->width(), this->height(), this->alphaType(), - this->fColorSpace))) { + SkImageInfo ii = make_info(this->width(), this->height(), this->alphaType(), + sk_ref_sp(dstColorSpace)); + if (!dst->tryAllocPixels(ii)) { return false; } - if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_GrPixelConfig, - dst->getPixels(), dst->rowBytes())) { + + sk_sp sContext = fContext->contextPriv().makeWrappedSurfaceContext( + fProxy, + fColorSpace); + if (!sContext) { + return false; + } + + if (!sContext->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0)) { return false; } @@ -98,18 +116,35 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst, SkColorSpace* dstColorSpace, return true; } -sk_sp SkImage_Gpu::asTextureProxyRef() const { - return GrSurfaceProxy::MakeWrapped(fTexture); +sk_sp SkImage_Gpu::asTextureProxyRef(GrContext* context, + const GrSamplerParams& params, + SkColorSpace* dstColorSpace, + sk_sp* texColorSpace, + SkScalar scaleAdjust[2]) const { + sk_sp tex(this->asTextureRef(context, params, dstColorSpace, + texColorSpace, scaleAdjust)); + + return GrSurfaceProxy::MakeWrapped(std::move(tex)); } GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, const GrSamplerParams& params, SkColorSpace* dstColorSpace, sk_sp* texColorSpace, SkScalar scaleAdjust[2]) const { + if (ctx != fContext) { + SkASSERT(0); + return nullptr; + } + if (texColorSpace) { *texColorSpace = this->fColorSpace; } - GrTextureAdjuster adjuster(fTexture.get(), this->alphaType(), this->bounds(), + GrTexture* texture = fProxy->instantiate(fContext->resourceProvider()); + if (!texture) { + return nullptr; + } + + GrTextureAdjuster adjuster(texture, this->alphaType(), this->bounds(), this->uniqueID(), this->fColorSpace.get()); return adjuster.refTextureSafeForParams(params, nullptr, scaleAdjust); } @@ -137,11 +172,8 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) bool SkImage_Gpu::onReadYUV8Planes(const SkISize sizes[3], void* const planes[3], const size_t rowBytes[3], SkYUVColorSpace colorSpace) const { - if (sk_sp proxy = as_IB(this)->asTextureProxyRef()) { - if (GrTextureToYUVPlanes(fTexture->getContext(), std::move(proxy), sizes, planes, - rowBytes, colorSpace)) { - return true; - } + if (GrTextureToYUVPlanes(fContext, fProxy, sizes, planes, rowBytes, colorSpace)) { + return true; } return INHERITED::onReadYUV8Planes(sizes, planes, rowBytes, colorSpace); @@ -158,17 +190,25 @@ bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size return false; } - GrPixelConfig config = SkImageInfo2GrPixelConfig(rec.fInfo, *fTexture->getContext()->caps()); + // TODO: this seems to duplicate code in GrTextureContext::onReadPixels and + // GrRenderTargetContext::onReadPixels uint32_t flags = 0; if (kUnpremul_SkAlphaType == rec.fInfo.alphaType() && kPremul_SkAlphaType == fAlphaType) { // let the GPU perform this transformation for us flags = GrContext::kUnpremul_PixelOpsFlag; } - if (!fTexture->readPixels(fColorSpace.get(), rec.fX, rec.fY, rec.fInfo.width(), - rec.fInfo.height(), config, rec.fInfo.colorSpace(), rec.fPixels, - rec.fRowBytes, flags)) { + + sk_sp sContext = fContext->contextPriv().makeWrappedSurfaceContext( + fProxy, + fColorSpace); + if (!sContext) { return false; } + + if (!sContext->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY, flags)) { + return false; + } + // do we have to manually fix-up the alpha channel? // src dst // unpremul premul fix manually @@ -184,12 +224,11 @@ bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size } sk_sp SkImage_Gpu::onMakeSubset(const SkIRect& subset) const { - GrContext* ctx = fTexture->getContext(); - GrSurfaceDesc desc = fTexture->desc(); + GrSurfaceDesc desc = fProxy->desc(); desc.fWidth = subset.width(); desc.fHeight = subset.height(); - sk_sp sContext(ctx->contextPriv().makeDeferredSurfaceContext( + sk_sp sContext(fContext->contextPriv().makeDeferredSurfaceContext( desc, SkBackingFit::kExact, fBudgeted)); @@ -197,24 +236,13 @@ sk_sp SkImage_Gpu::onMakeSubset(const SkIRect& subset) const { return nullptr; } - // TODO: make gpu images be proxy-backed so we don't need to do this - sk_sp tmpSrc(GrSurfaceProxy::MakeWrapped(fTexture)); - if (!tmpSrc) { + if (!sContext->copy(fProxy.get(), subset, SkIPoint::Make(0, 0))) { return nullptr; } - if (!sContext->copy(tmpSrc.get(), subset, SkIPoint::Make(0, 0))) { - return nullptr; - } - - // TODO: make gpu images be proxy-backed so we don't need to do this - GrSurface* subTx = sContext->asSurfaceProxy()->instantiate(ctx->resourceProvider()); - if (!subTx) { - return nullptr; - } - - return sk_make_sp(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, - fAlphaType, sk_ref_sp(subTx->asTexture()), + // MDB: this call is okay bc we know 'sContext' was kExact + return sk_make_sp(fContext, kNeedNewImageUniqueID, + fAlphaType, sContext->asTextureProxyRef(), fColorSpace, fBudgeted); } @@ -237,7 +265,7 @@ static sk_sp new_wrapped_texture_common(GrContext* ctx, const GrBackend } const SkBudgeted budgeted = SkBudgeted::kNo; - return sk_make_sp(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, + return sk_make_sp(kNeedNewImageUniqueID, at, std::move(tex), std::move(colorSpace), budgeted); } @@ -332,7 +360,7 @@ static sk_sp make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac sk_ref_sp(uProxy->asTextureProxy()), sk_ref_sp(vProxy->asTextureProxy()), yuvSizes, colorSpace, nv12)); - const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); + const SkRect rect = SkRect::MakeIWH(width, height); renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect); @@ -340,8 +368,10 @@ static sk_sp make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac return nullptr; } ctx->flushSurfaceWrites(renderTargetContext->accessRenderTarget()); - return sk_make_sp(width, height, kNeedNewImageUniqueID, - kOpaque_SkAlphaType, renderTargetContext->asTexture(), + + // MDB: this call is okay bc we know 'renderTargetContext' was exact + return sk_make_sp(ctx, kNeedNewImageUniqueID, + kOpaque_SkAlphaType, renderTargetContext->asTextureProxyRef(), renderTargetContext->refColorSpace(), budgeted); } @@ -370,7 +400,7 @@ static sk_sp create_image_from_maker(GrTextureMaker* maker, SkAlphaType if (!texture) { return nullptr; } - return sk_make_sp(texture->width(), texture->height(), id, at, std::move(texture), + return sk_make_sp(id, at, std::move(texture), std::move(texColorSpace), SkBudgeted::kNo); } @@ -477,7 +507,7 @@ sk_sp SkImage::MakeTextureFromPixmap(GrContext* ctx, const SkPixmap& pi if (!texture) { return nullptr; } - return sk_make_sp(texture->width(), texture->height(), kNeedNewImageUniqueID, + return sk_make_sp(kNeedNewImageUniqueID, pixmap.alphaType(), std::move(texture), sk_ref_sp(pixmap.info().colorSpace()), budgeted); } @@ -808,7 +838,7 @@ sk_sp SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo& return nullptr; } texture->texturePriv().setMipColorMode(colorMode); - return sk_make_sp(texture->width(), texture->height(), kNeedNewImageUniqueID, + return sk_make_sp(kNeedNewImageUniqueID, info.alphaType(), std::move(texture), sk_ref_sp(info.colorSpace()), budgeted); } diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h index 0ad44d3a59..c70c18ac78 100644 --- a/src/image/SkImage_Gpu.h +++ b/src/image/SkImage_Gpu.h @@ -10,6 +10,7 @@ #include "GrClip.h" #include "GrGpuResourcePriv.h" +#include "GrSurfaceProxyPriv.h" #include "GrTexture.h" #include "SkAtomics.h" #include "SkBitmap.h" @@ -20,12 +21,9 @@ class SkImage_Gpu : public SkImage_Base { public: - /** - * An "image" can be a subset/window into a larger texture, so we explicit take the - * width and height. - */ - SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType, sk_sp, sk_sp, - SkBudgeted); + SkImage_Gpu(uint32_t uniqueID, SkAlphaType, sk_sp, sk_sp, SkBudgeted); + SkImage_Gpu(GrContext*, uint32_t uniqueID, SkAlphaType, sk_sp, + sk_sp, SkBudgeted); ~SkImage_Gpu() override; SkImageInfo onImageInfo() const override; @@ -33,22 +31,29 @@ public: void applyBudgetDecision() const { if (SkBudgeted::kYes == fBudgeted) { - fTexture->resourcePriv().makeBudgeted(); + fProxy->priv().makeBudgeted(); } else { - fTexture->resourcePriv().makeUnbudgeted(); + fProxy->priv().makeUnbudgeted(); } } bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override; - GrTexture* asTextureRef(GrContext* ctx, const GrSamplerParams& params, SkColorSpace*, + GrTexture* asTextureRef(GrContext*, const GrSamplerParams&, SkColorSpace*, sk_sp*, SkScalar scaleAdjust[2]) const override; sk_sp onMakeSubset(const SkIRect&) const override; - GrTexture* peekTexture() const override { return fTexture.get(); } - sk_sp asTextureProxyRef() const override; + GrTexture* peekTexture() const override { + return fProxy->instantiate(fContext->resourceProvider()); + } + sk_sp asTextureProxyRef() const override { + return fProxy; + } + sk_sp asTextureProxyRef(GrContext*, const GrSamplerParams&, SkColorSpace*, + sk_sp*, + SkScalar scaleAdjust[2]) const override; sk_sp refPinnedTexture(uint32_t* uniqueID) const override { *uniqueID = this->uniqueID(); - return fTexture; + return sk_ref_sp(this->peekTexture()); } bool onReadYUV8Planes(const SkISize sizes[3], void* const planes[3], @@ -57,11 +62,12 @@ public: bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint) const override; - GrContext* context() { return fTexture->getContext(); } + GrContext* context() { return fContext; } sk_sp refColorSpace() { return fColorSpace; } private: - sk_sp fTexture; + GrContext* fContext; + sk_sp fProxy; const SkAlphaType fAlphaType; const SkBudgeted fBudgeted; sk_sp fColorSpace; diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp index 61be7b715a..220cc01b11 100644 --- a/src/image/SkImage_Raster.cpp +++ b/src/image/SkImage_Raster.cpp @@ -86,9 +86,16 @@ public: bool onPeekPixels(SkPixmap*) const override; const SkBitmap* onPeekBitmap() const override { return &fBitmap; } - bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override; +#if SK_SUPPORT_GPU + sk_sp asTextureProxyRef(GrContext*, const GrSamplerParams&, + SkColorSpace*, sk_sp*, + SkScalar scaleAdjust[2]) const override; +#endif + GrTexture* asTextureRef(GrContext*, const GrSamplerParams&, SkColorSpace*, sk_sp*, SkScalar scaleAdjust[2]) const override; + + bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override; sk_sp onMakeSubset(const SkIRect&) const override; SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } @@ -170,6 +177,18 @@ bool SkImage_Raster::getROPixels(SkBitmap* dst, SkColorSpace* dstColorSpace, Cac return true; } +#if SK_SUPPORT_GPU +sk_sp SkImage_Raster::asTextureProxyRef(GrContext* context, + const GrSamplerParams& params, + SkColorSpace* dstColorSpace, + sk_sp* texColorSpace, + SkScalar scaleAdjust[2]) const { + sk_sp tex(this->asTextureRef(context, params, dstColorSpace, texColorSpace, + scaleAdjust)); + return GrSurfaceProxy::MakeWrapped(std::move(tex)); +} +#endif + GrTexture* SkImage_Raster::asTextureRef(GrContext* ctx, const GrSamplerParams& params, SkColorSpace* dstColorSpace, sk_sp* texColorSpace, @@ -192,9 +211,9 @@ GrTexture* SkImage_Raster::asTextureRef(GrContext* ctx, const GrSamplerParams& p } return GrRefCachedBitmapTexture(ctx, fBitmap, params, scaleAdjust); -#endif - +#else return nullptr; +#endif } #if SK_SUPPORT_GPU diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index d1f6d24a0c..0bd34f8150 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -120,7 +120,7 @@ sk_sp SkSurface_Gpu::onNewImageSnapshot(SkBudgeted budgeted) { const SkImageInfo info = fDevice->imageInfo(); sk_sp image; if (tex) { - image = sk_make_sp(info.width(), info.height(), kNeedNewImageUniqueID, + image = sk_make_sp(kNeedNewImageUniqueID, info.alphaType(), sk_ref_sp(tex), sk_ref_sp(info.colorSpace()), budgeted); } diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index fa0556d11f..15faffadac 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -130,15 +130,9 @@ sk_sp GrContext::getFontAtlasImage_ForTesting(GrMaskFormat format) { return nullptr; } - GrTexture* tex = proxy->instantiate(this->resourceProvider()); - if (!tex) { - return nullptr; - } - - // MDB TODO: add proxy-backed SkImage_Gpu's - sk_sp image(new SkImage_Gpu(tex->width(), tex->height(), - kNeedNewImageUniqueID, kPremul_SkAlphaType, - sk_ref_sp(tex), nullptr, SkBudgeted::kNo)); + SkASSERT(proxy->priv().isExact()); + sk_sp image(new SkImage_Gpu(this, kNeedNewImageUniqueID, kPremul_SkAlphaType, + std::move(proxy), nullptr, SkBudgeted::kNo)); return image; }