Partially defer SkImage_Gpu
One of SkImageCacherator, GrBitmapTextureMaker, GrImageTextureMaker, GrTextureAdjuster, GrTextureProducer or SkImage has to take the first step. This is probably the least odd of the options. Change-Id: Ie167034553451f4b3633a5a1548dbd4d75839b3d Reviewed-on: https://skia-review.googlesource.com/9488 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
f700520072
commit
b726d58efc
@ -360,8 +360,7 @@ protected:
|
||||
return;
|
||||
}
|
||||
// No API to draw a GrTexture directly, so we cheat and create a private image subclass
|
||||
sk_sp<SkImage> image(new SkImage_Gpu(cache->info().width(), cache->info().height(),
|
||||
cache->uniqueID(), kPremul_SkAlphaType,
|
||||
sk_sp<SkImage> image(new SkImage_Gpu(cache->uniqueID(), kPremul_SkAlphaType,
|
||||
std::move(texture), std::move(texColorSpace),
|
||||
SkBudgeted::kNo));
|
||||
canvas->drawImage(image.get(), x, y);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -353,10 +353,7 @@ static sk_sp<SkImage> 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<SkImage_Gpu>(tex->width(), tex->height(),
|
||||
kNeedNewImageUniqueID, alphaType,
|
||||
return sk_make_sp<SkImage_Gpu>(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<SkImage>(new SkImage_Gpu(tex->width(), tex->height(),
|
||||
this->uniqueID(), fAlphaType,
|
||||
auto img = sk_sp<SkImage>(new SkImage_Gpu(this->uniqueID(), fAlphaType,
|
||||
sk_ref_sp(tex),
|
||||
fColorSpace, SkBudgeted::kNo));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "GrSurfaceProxy.h"
|
||||
#include "GrSurfaceProxyPriv.h"
|
||||
|
||||
#include "GrCaps.h"
|
||||
#include "GrContext.h"
|
||||
@ -302,3 +303,19 @@ sk_sp<GrSurfaceContext> 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -154,25 +154,29 @@ sk_sp<GrFragmentProcessor> SkImageShader::asFragmentProcessor(const AsFPArgs& ar
|
||||
GrSamplerParams params(tm, textureFilterMode);
|
||||
sk_sp<SkColorSpace> texColorSpace;
|
||||
SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
|
||||
sk_sp<GrTexture> texture(as_IB(fImage)->asTextureRef(args.fContext, params, args.fDstColorSpace,
|
||||
&texColorSpace, scaleAdjust));
|
||||
if (!texture) {
|
||||
sk_sp<GrTextureProxy> 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<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
|
||||
args.fDstColorSpace);
|
||||
sk_sp<GrFragmentProcessor> 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>(GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)));
|
||||
|
@ -50,6 +50,9 @@ public:
|
||||
virtual GrTexture* peekTexture() const { return nullptr; }
|
||||
#if SK_SUPPORT_GPU
|
||||
virtual sk_sp<GrTextureProxy> asTextureProxyRef() const { return nullptr; }
|
||||
virtual sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
|
||||
SkColorSpace*, sk_sp<SkColorSpace>*,
|
||||
SkScalar scaleAdjust[2]) const = 0;
|
||||
virtual sk_sp<GrTexture> refPinnedTexture(uint32_t* uniqueID) const { return nullptr; }
|
||||
#endif
|
||||
virtual SkImageCacherator* peekCacherator() const { return nullptr; }
|
||||
|
@ -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<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
|
||||
SkColorSpace*, sk_sp<SkColorSpace>*,
|
||||
SkScalar scaleAdjust[2]) const override;
|
||||
#endif
|
||||
SkImageCacherator* peekCacherator() const override { return &fCache; }
|
||||
SkData* onRefEncoded(GrContext*) const override;
|
||||
sk_sp<SkImage> 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<GrTextureProxy> SkImage_Generator::asTextureProxyRef(GrContext* context,
|
||||
const GrSamplerParams& params,
|
||||
SkColorSpace* dstColorSpace,
|
||||
sk_sp<SkColorSpace>* texColorSpace,
|
||||
SkScalar scaleAdjust[2]) const {
|
||||
sk_sp<GrTexture> 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<SkColorSpace>* texColorSpace,
|
||||
|
@ -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<GrTexture> tex,
|
||||
SkImage_Gpu::SkImage_Gpu(uint32_t uniqueID, SkAlphaType at, sk_sp<GrTexture> tex,
|
||||
sk_sp<SkColorSpace> 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<GrTextureProxy> proxy,
|
||||
sk_sp<SkColorSpace> 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<SkColorSpace> 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<GrSurfaceContext> 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<GrTextureProxy> SkImage_Gpu::asTextureProxyRef() const {
|
||||
return GrSurfaceProxy::MakeWrapped(fTexture);
|
||||
sk_sp<GrTextureProxy> SkImage_Gpu::asTextureProxyRef(GrContext* context,
|
||||
const GrSamplerParams& params,
|
||||
SkColorSpace* dstColorSpace,
|
||||
sk_sp<SkColorSpace>* texColorSpace,
|
||||
SkScalar scaleAdjust[2]) const {
|
||||
sk_sp<GrTexture> 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<SkColorSpace>* 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<GrTextureProxy> 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<GrSurfaceContext> 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> 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<GrSurfaceContext> sContext(ctx->contextPriv().makeDeferredSurfaceContext(
|
||||
sk_sp<GrSurfaceContext> sContext(fContext->contextPriv().makeDeferredSurfaceContext(
|
||||
desc,
|
||||
SkBackingFit::kExact,
|
||||
fBudgeted));
|
||||
@ -197,24 +236,13 @@ sk_sp<SkImage> 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<GrSurfaceProxy> 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<SkImage_Gpu>(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<SkImage_Gpu>(fContext, kNeedNewImageUniqueID,
|
||||
fAlphaType, sContext->asTextureProxyRef(),
|
||||
fColorSpace, fBudgeted);
|
||||
}
|
||||
|
||||
@ -237,7 +265,7 @@ static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx, const GrBackend
|
||||
}
|
||||
|
||||
const SkBudgeted budgeted = SkBudgeted::kNo;
|
||||
return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
|
||||
return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
|
||||
at, std::move(tex), std::move(colorSpace), budgeted);
|
||||
}
|
||||
|
||||
@ -332,7 +360,7 @@ static sk_sp<SkImage> 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<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
|
||||
return nullptr;
|
||||
}
|
||||
ctx->flushSurfaceWrites(renderTargetContext->accessRenderTarget());
|
||||
return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID,
|
||||
kOpaque_SkAlphaType, renderTargetContext->asTexture(),
|
||||
|
||||
// MDB: this call is okay bc we know 'renderTargetContext' was exact
|
||||
return sk_make_sp<SkImage_Gpu>(ctx, kNeedNewImageUniqueID,
|
||||
kOpaque_SkAlphaType, renderTargetContext->asTextureProxyRef(),
|
||||
renderTargetContext->refColorSpace(), budgeted);
|
||||
}
|
||||
|
||||
@ -370,7 +400,7 @@ static sk_sp<SkImage> create_image_from_maker(GrTextureMaker* maker, SkAlphaType
|
||||
if (!texture) {
|
||||
return nullptr;
|
||||
}
|
||||
return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), id, at, std::move(texture),
|
||||
return sk_make_sp<SkImage_Gpu>(id, at, std::move(texture),
|
||||
std::move(texColorSpace), SkBudgeted::kNo);
|
||||
}
|
||||
|
||||
@ -477,7 +507,7 @@ sk_sp<SkImage> SkImage::MakeTextureFromPixmap(GrContext* ctx, const SkPixmap& pi
|
||||
if (!texture) {
|
||||
return nullptr;
|
||||
}
|
||||
return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNewImageUniqueID,
|
||||
return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
|
||||
pixmap.alphaType(), std::move(texture),
|
||||
sk_ref_sp(pixmap.info().colorSpace()), budgeted);
|
||||
}
|
||||
@ -808,7 +838,7 @@ sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo&
|
||||
return nullptr;
|
||||
}
|
||||
texture->texturePriv().setMipColorMode(colorMode);
|
||||
return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNewImageUniqueID,
|
||||
return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
|
||||
info.alphaType(), std::move(texture),
|
||||
sk_ref_sp(info.colorSpace()), budgeted);
|
||||
}
|
||||
|
@ -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<GrTexture>, sk_sp<SkColorSpace>,
|
||||
SkBudgeted);
|
||||
SkImage_Gpu(uint32_t uniqueID, SkAlphaType, sk_sp<GrTexture>, sk_sp<SkColorSpace>, SkBudgeted);
|
||||
SkImage_Gpu(GrContext*, uint32_t uniqueID, SkAlphaType, sk_sp<GrTextureProxy>,
|
||||
sk_sp<SkColorSpace>, 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<SkColorSpace>*, SkScalar scaleAdjust[2]) const override;
|
||||
sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
|
||||
|
||||
GrTexture* peekTexture() const override { return fTexture.get(); }
|
||||
sk_sp<GrTextureProxy> asTextureProxyRef() const override;
|
||||
GrTexture* peekTexture() const override {
|
||||
return fProxy->instantiate(fContext->resourceProvider());
|
||||
}
|
||||
sk_sp<GrTextureProxy> asTextureProxyRef() const override {
|
||||
return fProxy;
|
||||
}
|
||||
sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&, SkColorSpace*,
|
||||
sk_sp<SkColorSpace>*,
|
||||
SkScalar scaleAdjust[2]) const override;
|
||||
sk_sp<GrTexture> 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<SkColorSpace> refColorSpace() { return fColorSpace; }
|
||||
|
||||
private:
|
||||
sk_sp<GrTexture> fTexture;
|
||||
GrContext* fContext;
|
||||
sk_sp<GrTextureProxy> fProxy;
|
||||
const SkAlphaType fAlphaType;
|
||||
const SkBudgeted fBudgeted;
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
|
@ -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<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
|
||||
SkColorSpace*, sk_sp<SkColorSpace>*,
|
||||
SkScalar scaleAdjust[2]) const override;
|
||||
#endif
|
||||
|
||||
GrTexture* asTextureRef(GrContext*, const GrSamplerParams&, SkColorSpace*,
|
||||
sk_sp<SkColorSpace>*, SkScalar scaleAdjust[2]) const override;
|
||||
|
||||
bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
|
||||
sk_sp<SkImage> 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<GrTextureProxy> SkImage_Raster::asTextureProxyRef(GrContext* context,
|
||||
const GrSamplerParams& params,
|
||||
SkColorSpace* dstColorSpace,
|
||||
sk_sp<SkColorSpace>* texColorSpace,
|
||||
SkScalar scaleAdjust[2]) const {
|
||||
sk_sp<GrTexture> 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<SkColorSpace>* 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
|
||||
|
@ -120,7 +120,7 @@ sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot(SkBudgeted budgeted) {
|
||||
const SkImageInfo info = fDevice->imageInfo();
|
||||
sk_sp<SkImage> image;
|
||||
if (tex) {
|
||||
image = sk_make_sp<SkImage_Gpu>(info.width(), info.height(), kNeedNewImageUniqueID,
|
||||
image = sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
|
||||
info.alphaType(), sk_ref_sp(tex),
|
||||
sk_ref_sp(info.colorSpace()), budgeted);
|
||||
}
|
||||
|
@ -130,15 +130,9 @@ sk_sp<SkImage> 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<SkImage> image(new SkImage_Gpu(tex->width(), tex->height(),
|
||||
kNeedNewImageUniqueID, kPremul_SkAlphaType,
|
||||
sk_ref_sp(tex), nullptr, SkBudgeted::kNo));
|
||||
SkASSERT(proxy->priv().isExact());
|
||||
sk_sp<SkImage> image(new SkImage_Gpu(this, kNeedNewImageUniqueID, kPremul_SkAlphaType,
|
||||
std::move(proxy), nullptr, SkBudgeted::kNo));
|
||||
return image;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user