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:
Robert Phillips 2017-03-09 16:36:32 -05:00 committed by Skia Commit-Bot
parent f700520072
commit b726d58efc
18 changed files with 209 additions and 106 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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