Put SkImageInfo on SkImage to avoid cost of reconstructing for queries.

Previously calling SkImage::alphaType(), for example, woult call
the virtual SkImage_Base::onImageInfo() which would construct
and return a temporary SkImageInfo. This often meant ref-ing a
SkColorSpace.


Change-Id: I54975a6b20dea5bc84739068df0c81c022a12067
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/202711
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Salomon 2019-03-21 15:30:08 -04:00 committed by Skia Commit-Bot
parent adc94d96bb
commit 5ad6fd3160
19 changed files with 134 additions and 167 deletions

View File

@ -88,7 +88,7 @@ protected:
sk_sp<GrTextureProxy> proxy;
if (fFilter == GrSamplerState::Filter::kMipMap) {
SkBitmap copy;
SkImageInfo info = as_IB(fImage)->onImageInfo().makeColorType(kN32_SkColorType);
SkImageInfo info = fImage->imageInfo().makeColorType(kN32_SkColorType);
if (!copy.tryAllocPixels(info) || !fImage->readPixels(copy.pixmap(), 0, 0)) {
*errorMsg = "Failed to read pixels.";
return DrawResult::kFail;

View File

@ -1111,7 +1111,7 @@ protected:
y += kTileWidthHeight + kPad;
SkBitmap readBack;
readBack.allocPixels(as_IB(yuv)->onImageInfo());
readBack.allocPixels(yuv->imageInfo());
yuv->readPixels(readBack.pixmap(), 0, 0);
canvas->drawBitmap(readBack, x, y);

View File

@ -584,29 +584,36 @@ public:
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
#endif
/** Returns a SkImageInfo describing the width, height, color type, alpha type, and color space
of the SkImage.
@return image info of SkImage.
*/
const SkImageInfo& imageInfo() const { return fInfo; }
/** Returns pixel count in each row.
@return pixel width in SkImage
*/
int width() const { return fWidth; }
int width() const { return fInfo.width(); }
/** Returns pixel row count.
@return pixel height in SkImage
*/
int height() const { return fHeight; }
int height() const { return fInfo.height(); }
/** Returns SkISize { width(), height() }.
@return integral size of width() and height()
*/
SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
SkISize dimensions() const { return SkISize::Make(fInfo.width(), fInfo.height()); }
/** Returns SkIRect { 0, 0, width(), height() }.
@return integral rectangle from origin to width() and height()
*/
SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
SkIRect bounds() const { return SkIRect::MakeWH(fInfo.width(), fInfo.height()); }
/** Returns value unique to image. SkImage contents cannot change after SkImage is
created. Any operation to create a new SkImage will receive generate a new
@ -1071,11 +1078,10 @@ public:
sk_sp<SkColorSpace> targetColorSpace) const;
private:
SkImage(int width, int height, uint32_t uniqueID);
SkImage(const SkImageInfo& info, uint32_t uniqueID);
friend class SkImage_Base;
const int fWidth;
const int fHeight;
SkImageInfo fInfo;
const uint32_t fUniqueID;
typedef SkRefCnt INHERITED;

View File

@ -199,7 +199,7 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(GrRecordingContext* context,
}
return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(proxy),
as_IB(image)->onImageInfo().refColorSpace(), props);
image->refColorSpace(), props);
} else
#endif
{

View File

@ -115,9 +115,9 @@ std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProc
auto fp = GrYUVtoRGBEffect::Make(fImage->fProxies, fImage->fYUVAIndices,
fImage->fYUVColorSpace, filter);
if (fImage->fTargetColorSpace) {
fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fColorSpace.get(),
fImage->alphaType(), fImage->fTargetColorSpace.get());
if (fImage->fFromColorSpace) {
fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fFromColorSpace.get(),
fImage->alphaType(), fImage->colorSpace());
}
return fp;
}

View File

@ -202,7 +202,7 @@ sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(sk_sp<SkImage> srcImag
return nullptr;
}
SkImageInfo info = as_IB(srcImage)->onImageInfo();
const SkImageInfo& info = srcImage->imageInfo();
GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
if (kUnknown_GrPixelConfig == config) {

View File

@ -1187,7 +1187,7 @@ sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) {
SkIRect::MakeWH(image->width(), image->height()),
image->uniqueID(),
std::move(proxy),
as_IB(image)->onImageInfo().refColorSpace(),
image->refColorSpace(),
&this->surfaceProps());
} else if (image->peekPixels(&pm)) {
SkBitmap bm;
@ -1307,9 +1307,8 @@ void SkGpuDevice::drawImageNine(const SkImage* image,
auto iter = skstd::make_unique<SkLatticeIter>(image->width(), image->height(), center, dst);
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(this->context(),
&pinnedUniqueID)) {
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
image->alphaType(), pinnedUniqueID,
as_IB(image)->onImageInfo().colorSpace());
GrTextureAdjuster adjuster(this->context(), std::move(proxy), image->alphaType(),
pinnedUniqueID, image->colorSpace());
this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
} else {
SkBitmap bm;
@ -1368,9 +1367,8 @@ void SkGpuDevice::drawImageLattice(const SkImage* image,
auto iter = skstd::make_unique<SkLatticeIter>(lattice, dst);
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(this->context(),
&pinnedUniqueID)) {
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
image->alphaType(), pinnedUniqueID,
as_IB(image)->onImageInfo().colorSpace());
GrTextureAdjuster adjuster(this->context(), std::move(proxy), image->alphaType(),
pinnedUniqueID, image->colorSpace());
this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
} else {
SkBitmap bm;

View File

@ -32,13 +32,11 @@
#endif
#include "GrBackendSurface.h"
SkImage::SkImage(int width, int height, uint32_t uniqueID)
: fWidth(width)
, fHeight(height)
, fUniqueID(kNeedNewImageUniqueID == uniqueID ? SkNextID::ImageID() : uniqueID)
{
SkASSERT(width > 0);
SkASSERT(height > 0);
SkImage::SkImage(const SkImageInfo& info, uint32_t uniqueID)
: fInfo(info)
, fUniqueID(kNeedNewImageUniqueID == uniqueID ? SkNextID::ImageID() : uniqueID) {
SkASSERT(info.width() > 0);
SkASSERT(info.height() > 0);
}
bool SkImage::peekPixels(SkPixmap* pm) const {
@ -49,8 +47,8 @@ bool SkImage::peekPixels(SkPixmap* pm) const {
return as_IB(this)->onPeekPixels(pm);
}
bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY, CachingHint chint) const {
bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, int srcX,
int srcY, CachingHint chint) const {
return as_IB(this)->onReadPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY, chint);
}
@ -76,21 +74,13 @@ bool SkImage::scalePixels(const SkPixmap& dst, SkFilterQuality quality, CachingH
///////////////////////////////////////////////////////////////////////////////////////////////////
SkColorType SkImage::colorType() const {
return as_IB(this)->onImageInfo().colorType();
}
SkColorType SkImage::colorType() const { return fInfo.colorType(); }
SkAlphaType SkImage::alphaType() const {
return as_IB(this)->onImageInfo().alphaType();
}
SkAlphaType SkImage::alphaType() const { return fInfo.alphaType(); }
SkColorSpace* SkImage::colorSpace() const {
return as_IB(this)->onImageInfo().colorSpace();
}
SkColorSpace* SkImage::colorSpace() const { return fInfo.colorSpace(); }
sk_sp<SkColorSpace> SkImage::refColorSpace() const {
return as_IB(this)->onImageInfo().refColorSpace();
}
sk_sp<SkColorSpace> SkImage::refColorSpace() const { return fInfo.refColorSpace(); }
sk_sp<SkShader> SkImage::makeShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
const SkMatrix* localMatrix) const {
@ -192,10 +182,8 @@ bool SkImage::isValid(GrContext* context) const {
///////////////////////////////////////////////////////////////////////////////
SkImage_Base::SkImage_Base(int width, int height, uint32_t uniqueID)
: INHERITED(width, height, uniqueID)
, fAddedToRasterCache(false)
{}
SkImage_Base::SkImage_Base(const SkImageInfo& info, uint32_t uniqueID)
: INHERITED(info, uniqueID), fAddedToRasterCache(false) {}
SkImage_Base::~SkImage_Base() {
if (fAddedToRasterCache.load()) {
@ -234,7 +222,7 @@ sk_sp<SkCachedData> SkImage_Base::getPlanes(SkYUVASizeInfo*, SkYUVAIndex[4],
bool SkImage_Base::onAsLegacyBitmap(SkBitmap* bitmap) const {
// As the base-class, all we can do is make a copy (regardless of mode).
// Subclasses that want to be more optimal should override.
SkImageInfo info = this->onImageInfo().makeColorType(kN32_SkColorType).makeColorSpace(nullptr);
SkImageInfo info = fInfo.makeColorType(kN32_SkColorType).makeColorSpace(nullptr);
if (!bitmap->tryAllocPixels(info)) {
return false;
}
@ -282,8 +270,7 @@ sk_sp<SkImage> SkImage::makeWithFilter(GrContext* grContext,
sk_sp<SkImageFilterCache> cache(
SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize));
SkImageFilter::OutputProperties outputProperties(as_IB(this)->onImageInfo().colorType(),
as_IB(this)->onImageInfo().colorSpace());
SkImageFilter::OutputProperties outputProperties(fInfo.colorType(), fInfo.colorSpace());
SkImageFilter::Context context(SkMatrix::I(), clipBounds, cache.get(), outputProperties);
sk_sp<SkSpecialImage> result = filter->filterImage(srcSpecialImage.get(), context, offset);
@ -307,9 +294,7 @@ bool SkImage::isLazyGenerated() const {
return as_IB(this)->onIsLazyGenerated();
}
bool SkImage::isAlphaOnly() const {
return as_IB(this)->onImageInfo().colorType() == kAlpha_8_SkColorType;
}
bool SkImage::isAlphaOnly() const { return SkColorTypeIsAlphaOnly(fInfo.colorType()); }
sk_sp<SkImage> SkImage::makeColorSpace(sk_sp<SkColorSpace> target) const {
if (!target) {
@ -374,20 +359,19 @@ sk_sp<SkImage> SkImage::makeRasterImage() const {
return sk_ref_sp(const_cast<SkImage*>(this));
}
const SkImageInfo info = as_IB(this)->onImageInfo();
const size_t rowBytes = info.minRowBytes();
size_t size = info.computeByteSize(rowBytes);
const size_t rowBytes = fInfo.minRowBytes();
size_t size = fInfo.computeByteSize(rowBytes);
if (SkImageInfo::ByteSizeOverflowed(size)) {
return nullptr;
}
sk_sp<SkData> data = SkData::MakeUninitialized(size);
pm = { info.makeColorSpace(nullptr), data->writable_data(), info.minRowBytes() };
pm = {fInfo.makeColorSpace(nullptr), data->writable_data(), fInfo.minRowBytes()};
if (!this->readPixels(pm, 0, 0)) {
return nullptr;
}
return SkImage::MakeRasterData(info, std::move(data), rowBytes);
return SkImage::MakeRasterData(fInfo, std::move(data), rowBytes);
}
//////////////////////////////////////////////////////////////////////////////////////
@ -498,7 +482,7 @@ SkIRect SkImage_getSubset(const SkImage* image) {
sk_sp<SkImage> SkImageMakeRasterCopyAndAssignColorSpace(const SkImage* src,
SkColorSpace* colorSpace) {
// Read the pixels out of the source image, with no conversion
SkImageInfo info = as_IB(src)->onImageInfo();
const SkImageInfo& info = src->imageInfo();
if (kUnknown_SkColorType == info.colorType()) {
SkDEBUGFAIL("Unexpected color type");
return nullptr;

View File

@ -34,11 +34,6 @@ class SkImage_Base : public SkImage {
public:
virtual ~SkImage_Base();
// User: returns image info for this SkImage.
// Implementors: if you can not return the value, return an invalid ImageInfo with w=0 & h=0
// & unknown color space.
virtual SkImageInfo onImageInfo() const = 0;
virtual SkIRect onGetSubset() const {
return { 0, 0, this->width(), this->height() };
}
@ -104,7 +99,7 @@ public:
virtual sk_sp<SkImage> onMakeColorTypeAndColorSpace(GrRecordingContext*,
SkColorType, sk_sp<SkColorSpace>) const = 0;
protected:
SkImage_Base(int width, int height, uint32_t uniqueID);
SkImage_Base(const SkImageInfo& info, uint32_t uniqueID);
private:
// Set true by caches when they cache content that's derived from the current pixels.

View File

@ -48,23 +48,22 @@
#include "effects/GrYUVtoRGBEffect.h"
#include "gl/GrGLTexture.h"
static SkColorType proxy_color_type(GrTextureProxy* proxy) {
SkColorType colorType;
if (!GrPixelConfigToColorType(proxy->config(), &colorType)) {
colorType = kUnknown_SkColorType;
}
return colorType;
}
SkImage_Gpu::SkImage_Gpu(sk_sp<GrContext> context, uint32_t uniqueID, SkAlphaType at,
sk_sp<GrTextureProxy> proxy, sk_sp<SkColorSpace> colorSpace)
: INHERITED(std::move(context), proxy->worstCaseWidth(), proxy->worstCaseHeight(), uniqueID,
at, colorSpace)
proxy_color_type(proxy.get()), at, colorSpace)
, fProxy(std::move(proxy)) {}
SkImage_Gpu::~SkImage_Gpu() {}
SkImageInfo SkImage_Gpu::onImageInfo() const {
SkColorType colorType;
if (!GrPixelConfigToColorType(fProxy->config(), &colorType)) {
colorType = kUnknown_SkColorType;
}
return SkImageInfo::Make(fProxy->width(), fProxy->height(), colorType, fAlphaType, fColorSpace);
}
sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(GrRecordingContext* context,
SkColorType targetCT,
sk_sp<SkColorSpace> targetCS) const {
@ -72,8 +71,8 @@ sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(GrRecordingContext* con
return nullptr;
}
auto xform = GrColorSpaceXformEffect::Make(fColorSpace.get(), fAlphaType,
targetCS.get(), fAlphaType);
auto xform = GrColorSpaceXformEffect::Make(this->colorSpace(), this->alphaType(),
targetCS.get(), this->alphaType());
SkASSERT(xform || targetCT != this->colorType());
sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef(context);
@ -105,7 +104,7 @@ sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(GrRecordingContext* con
}
// MDB: this call is okay bc we know 'renderTargetContext' was exact
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, fAlphaType,
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, this->alphaType(),
renderTargetContext->asTextureProxyRef(), std::move(targetCS));
}
@ -469,7 +468,7 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<Sk
if (limitToMaxTextureSize &&
(codecImage->width() > maxTextureSize || codecImage->height() > maxTextureSize)) {
SkAutoPixmapStorage pmap;
SkImageInfo info = as_IB(codecImage)->onImageInfo();
SkImageInfo info = codecImage->imageInfo();
if (!dstColorSpace) {
info = info.makeColorSpace(nullptr);
}
@ -504,11 +503,9 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<Sk
GrGpu* gpu = context->priv().getGpu();
sk_sp<GrSemaphore> sema = gpu->prepareTextureForCrossContextUsage(texture.get());
auto gen = GrBackendTextureImageGenerator::Make(std::move(texture), proxy->origin(),
std::move(sema),
as_IB(codecImage)->onImageInfo().colorType(),
codecImage->alphaType(),
codecImage->refColorSpace());
auto gen = GrBackendTextureImageGenerator::Make(
std::move(texture), proxy->origin(), std::move(sema), codecImage->colorType(),
codecImage->alphaType(), codecImage->refColorSpace());
return SkImage::MakeFromGenerator(std::move(gen));
}

View File

@ -26,8 +26,6 @@ public:
sk_sp<SkColorSpace>);
~SkImage_Gpu() override;
SkImageInfo onImageInfo() const override;
GrTextureProxy* peekProxy() const override {
return fProxy.get();
}

View File

@ -23,11 +23,9 @@
#include "effects/GrYUVtoRGBEffect.h"
SkImage_GpuBase::SkImage_GpuBase(sk_sp<GrContext> context, int width, int height, uint32_t uniqueID,
SkAlphaType at, sk_sp<SkColorSpace> cs)
: INHERITED(width, height, uniqueID)
, fContext(std::move(context))
, fAlphaType(at)
, fColorSpace(std::move(cs)) {}
SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
: INHERITED(SkImageInfo::Make(width, height, ct, at, std::move(cs)), uniqueID)
, fContext(std::move(context)) {}
SkImage_GpuBase::~SkImage_GpuBase() {}
@ -79,18 +77,18 @@ bool SkImage_GpuBase::getROPixels(SkBitmap* dst, CachingHint chint) const {
SkBitmapCache::RecPtr rec = nullptr;
SkPixmap pmap;
if (kAllow_CachingHint == chint) {
rec = SkBitmapCache::Alloc(desc, this->onImageInfo(), &pmap);
rec = SkBitmapCache::Alloc(desc, this->imageInfo(), &pmap);
if (!rec) {
return false;
}
} else {
if (!dst->tryAllocPixels(this->onImageInfo()) || !dst->peekPixels(&pmap)) {
if (!dst->tryAllocPixels(this->imageInfo()) || !dst->peekPixels(&pmap)) {
return false;
}
}
sk_sp<GrSurfaceContext> sContext = direct->priv().makeWrappedSurfaceContext(
this->asTextureProxyRef(direct), fColorSpace);
this->asTextureProxyRef(direct), this->refColorSpace());
if (!sContext) {
return false;
}
@ -137,7 +135,7 @@ sk_sp<SkImage> SkImage_GpuBase::onMakeSubset(GrRecordingContext* context,
}
// MDB: this call is okay bc we know 'sContext' was kExact
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, fAlphaType,
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, this->alphaType(),
sContext->asTextureProxyRef(), this->refColorSpace());
}
@ -171,7 +169,7 @@ bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
return false;
}
if (!SkImageInfoValidConversion(dstInfo, this->onImageInfo())) {
if (!SkImageInfoValidConversion(dstInfo, this->imageInfo())) {
return false;
}
@ -183,7 +181,8 @@ bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
// 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) {
if (kUnpremul_SkAlphaType == rec.fInfo.alphaType() &&
kPremul_SkAlphaType == this->alphaType()) {
// let the GPU perform this transformation for us
flags = GrContextPriv::kUnpremul_PixelOpsFlag;
}
@ -206,7 +205,8 @@ bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
//
// Should this be handled by Ganesh? todo:?
//
if (kPremul_SkAlphaType == rec.fInfo.alphaType() && kUnpremul_SkAlphaType == fAlphaType) {
if (kPremul_SkAlphaType == rec.fInfo.alphaType() &&
kUnpremul_SkAlphaType == this->alphaType()) {
apply_premul(rec.fInfo, rec.fPixels, rec.fRowBytes);
}
return true;
@ -220,8 +220,8 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::asTextureProxyRef(GrRecordingContext* con
return nullptr;
}
GrTextureAdjuster adjuster(fContext.get(), this->asTextureProxyRef(context), fAlphaType,
this->uniqueID(), fColorSpace.get());
GrTextureAdjuster adjuster(fContext.get(), this->asTextureProxyRef(context), this->alphaType(),
this->uniqueID(), this->colorSpace());
return adjuster.refTextureProxyForParams(params, scaleAdjust);
}

View File

@ -20,8 +20,8 @@ class SkColorSpace;
class SkImage_GpuBase : public SkImage_Base {
public:
SkImage_GpuBase(sk_sp<GrContext>, int width, int height, uint32_t uniqueID, SkAlphaType,
sk_sp<SkColorSpace>);
SkImage_GpuBase(sk_sp<GrContext>, int width, int height, uint32_t uniqueID, SkColorType,
SkAlphaType, sk_sp<SkColorSpace>);
~SkImage_GpuBase() override;
GrContext* context() const final { return fContext.get(); }
@ -94,9 +94,7 @@ protected:
const sk_sp<GrTextureProxy> proxies[4],
const SkYUVAIndex yuvaIndices[4]);
sk_sp<GrContext> fContext;
const SkAlphaType fAlphaType; // alpha type for final image
sk_sp<SkColorSpace> fColorSpace; // color space for final image
sk_sp<GrContext> fContext;
private:
typedef SkImage_Base INHERITED;

View File

@ -27,15 +27,17 @@
#include "SkYUVASizeInfo.h"
#include "effects/GrYUVtoRGBEffect.h"
static constexpr auto kAssumedColorType = kRGBA_8888_SkColorType;
SkImage_GpuYUVA::SkImage_GpuYUVA(sk_sp<GrContext> context, int width, int height, uint32_t uniqueID,
SkYUVColorSpace colorSpace, sk_sp<GrTextureProxy> proxies[],
int numProxies, const SkYUVAIndex yuvaIndices[4],
GrSurfaceOrigin origin, sk_sp<SkColorSpace> imageColorSpace)
: INHERITED(std::move(context), width, height, uniqueID,
: INHERITED(std::move(context), width, height, uniqueID, kAssumedColorType,
// If an alpha channel is present we always switch to kPremul. This is because,
// although the planar data is always un-premul, the final interleaved RGB image
// is/would-be premul.
GetAlphaTypeFromYUVAIndices(yuvaIndices), imageColorSpace)
GetAlphaTypeFromYUVAIndices(yuvaIndices), std::move(imageColorSpace))
, fNumProxies(numProxies)
, fYUVColorSpace(colorSpace)
, fOrigin(origin) {
@ -52,16 +54,19 @@ SkImage_GpuYUVA::SkImage_GpuYUVA(sk_sp<GrContext> context, int width, int height
// For onMakeColorSpace()
SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpace> targetCS)
: INHERITED(image->fContext, image->width(), image->height(), kNeedNewImageUniqueID,
// If an alpha channel is present we always switch to kPremul. This is because,
// although the planar data is always un-premul, the final interleaved RGB image
// is/would-be premul.
GetAlphaTypeFromYUVAIndices(image->fYUVAIndices), image->fColorSpace)
, fNumProxies(image->fNumProxies)
, fYUVColorSpace(image->fYUVColorSpace)
, fOrigin(image->fOrigin)
, fTargetColorSpace(targetCS) {
// The caller should have done this work, just verifying
: INHERITED(image->fContext, image->width(), image->height(), kNeedNewImageUniqueID,
kAssumedColorType,
// If an alpha channel is present we always switch to kPremul. This is because,
// although the planar data is always un-premul, the final interleaved RGB image
// is/would-be premul.
GetAlphaTypeFromYUVAIndices(image->fYUVAIndices), std::move(targetCS))
, fNumProxies(image->fNumProxies)
, fYUVColorSpace(image->fYUVColorSpace)
, fOrigin(image->fOrigin)
// Since null fFromColorSpace means no GrColorSpaceXform, we turn a null
// image->refColorSpace() into an explicit SRGB.
, fFromColorSpace(image->colorSpace() ? image->refColorSpace() : SkColorSpace::MakeSRGB()) {
// The caller should have done this work, just verifying
SkDEBUGCODE(int textureCount;)
SkASSERT(SkYUVAIndex::AreValidIndices(image->fYUVAIndices, &textureCount));
SkASSERT(textureCount == fNumProxies);
@ -74,12 +79,6 @@ SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpac
SkImage_GpuYUVA::~SkImage_GpuYUVA() {}
SkImageInfo SkImage_GpuYUVA::onImageInfo() const {
// Note: this is the imageInfo for the flattened image, not the YUV planes
return SkImageInfo::Make(this->width(), this->height(), kRGBA_8888_SkColorType,
fAlphaType, fTargetColorSpace ? fTargetColorSpace : fColorSpace);
}
bool SkImage_GpuYUVA::setupMipmapsForPlanes(GrRecordingContext* context) const {
if (!context || !fContext->priv().matches(context)) {
return false;
@ -118,19 +117,22 @@ sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef(GrRecordingContext* con
}
const GrBackendFormat format =
fContext->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
fContext->priv().caps()->getBackendFormatFromColorType(kAssumedColorType);
// Needs to create a render target in order to draw to it for the yuv->rgb conversion.
sk_sp<GrRenderTargetContext> renderTargetContext(
context->priv().makeDeferredRenderTargetContext(
format, SkBackingFit::kExact, this->width(), this->height(),
kRGBA_8888_GrPixelConfig, fColorSpace, 1, GrMipMapped::kNo, fOrigin));
context->priv().makeDeferredRenderTargetContext(
format, SkBackingFit::kExact, this->width(), this->height(),
kRGBA_8888_GrPixelConfig, this->refColorSpace(), 1, GrMipMapped::kNo, fOrigin));
if (!renderTargetContext) {
return nullptr;
}
auto colorSpaceXform = GrColorSpaceXform::Make(fColorSpace.get(), fAlphaType,
fTargetColorSpace.get(), fAlphaType);
sk_sp<GrColorSpaceXform> colorSpaceXform;
if (fFromColorSpace) {
colorSpaceXform = GrColorSpaceXform::Make(fFromColorSpace.get(), this->alphaType(),
this->colorSpace(), this->alphaType());
}
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
if (!RenderYUVAToRGBA(fContext.get(), renderTargetContext.get(), rect, fYUVColorSpace,
std::move(colorSpaceXform), fProxies, fYUVAIndices)) {
@ -314,7 +316,7 @@ sk_sp<SkImage> SkImage_GpuYUVA::MakePromiseYUVATexture(
SkAlphaType at = (-1 != yuvaIndices[SkYUVAIndex::kA_Index].fIndex) ? kPremul_SkAlphaType
: kOpaque_SkAlphaType;
SkImageInfo info = SkImageInfo::Make(imageWidth, imageHeight, kRGBA_8888_SkColorType,
SkImageInfo info = SkImageInfo::Make(imageWidth, imageHeight, kAssumedColorType,
at, imageColorSpace);
if (!SkImageInfoIsValid(info)) {
return nullptr;

View File

@ -29,8 +29,6 @@ public:
GrSurfaceOrigin, sk_sp<SkColorSpace>);
~SkImage_GpuYUVA() override;
SkImageInfo onImageInfo() const override;
// This returns the single backing proxy if the YUV channels have already been flattened but
// nullptr if they have not.
GrTextureProxy* peekProxy() const override;
@ -86,7 +84,10 @@ private:
SkYUVAIndex fYUVAIndices[4];
const SkYUVColorSpace fYUVColorSpace;
GrSurfaceOrigin fOrigin;
const sk_sp<SkColorSpace> fTargetColorSpace;
// If this is non-null then the planar data should be converted from fFromColorSpace to
// this->colorSpace(). Otherwise we assume the planar data (post YUV->RGB conversion) is already
// in this->colorSpace().
const sk_sp<SkColorSpace> fFromColorSpace;
// Repeated calls to onMakeColorSpace will result in a proliferation of unique IDs and
// SkImage_GpuYUVA instances. Cache the result of the last successful onMakeColorSpace call.

View File

@ -123,9 +123,8 @@ private:
///////////////////////////////////////////////////////////////////////////////
SkImage_Lazy::SkImage_Lazy(Validator* validator)
: INHERITED(validator->fInfo.width(), validator->fInfo.height(), validator->fUniqueID)
: INHERITED(validator->fInfo, validator->fUniqueID)
, fSharedGenerator(std::move(validator->fSharedGenerator))
, fInfo(validator->fInfo)
, fOrigin(validator->fOrigin) {
SkASSERT(fSharedGenerator);
fUniqueID = validator->fUniqueID;
@ -193,7 +192,7 @@ bool SkImage_Lazy::getROPixels(SkBitmap* bitmap, SkImage::CachingHint chint) con
if (SkImage::kAllow_CachingHint == chint) {
SkPixmap pmap;
SkBitmapCache::RecPtr cacheRec = SkBitmapCache::Alloc(desc, fInfo, &pmap);
SkBitmapCache::RecPtr cacheRec = SkBitmapCache::Alloc(desc, this->imageInfo(), &pmap);
if (!cacheRec ||
!generate_pixels(ScopedGenerator(fSharedGenerator), pmap,
fOrigin.x(), fOrigin.y())) {
@ -202,9 +201,9 @@ bool SkImage_Lazy::getROPixels(SkBitmap* bitmap, SkImage::CachingHint chint) con
SkBitmapCache::Add(std::move(cacheRec), bitmap);
this->notifyAddedToRasterCache();
} else {
if (!bitmap->tryAllocPixels(fInfo) ||
!generate_pixels(ScopedGenerator(fSharedGenerator), bitmap->pixmap(),
fOrigin.x(), fOrigin.y())) {
if (!bitmap->tryAllocPixels(this->imageInfo()) ||
!generate_pixels(ScopedGenerator(fSharedGenerator), bitmap->pixmap(), fOrigin.x(),
fOrigin.y())) {
return false;
}
bitmap->setImmutable();
@ -252,12 +251,12 @@ sk_sp<GrTextureProxy> SkImage_Lazy::asTextureProxyRef(GrRecordingContext* contex
sk_sp<SkImage> SkImage_Lazy::onMakeSubset(GrRecordingContext* context,
const SkIRect& subset) const {
SkASSERT(fInfo.bounds().contains(subset));
SkASSERT(fInfo.bounds() != subset);
SkASSERT(this->bounds().contains(subset));
SkASSERT(this->bounds() != subset);
const SkIRect generatorSubset = subset.makeOffset(fOrigin.x(), fOrigin.y());
const SkColorType colorType = fInfo.colorType();
Validator validator(fSharedGenerator, &generatorSubset, &colorType, fInfo.refColorSpace());
const SkColorType colorType = this->colorType();
Validator validator(fSharedGenerator, &generatorSubset, &colorType, this->refColorSpace());
return validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
}
@ -271,7 +270,7 @@ sk_sp<SkImage> SkImage_Lazy::onMakeColorTypeAndColorSpace(GrRecordingContext*,
return fOnMakeColorTypeAndSpaceResult;
}
const SkIRect generatorSubset =
SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width(), fInfo.height());
SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), this->width(), this->height());
Validator validator(fSharedGenerator, &generatorSubset, &targetCT, targetCS);
sk_sp<SkImage> result = validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
if (result) {
@ -414,7 +413,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(
SkImageGenerator::TexGenType::kCheap != generator->onCanGenerateTexture()) {
return nullptr;
}
if ((proxy = generator->generateTexture(ctx, fInfo, fOrigin, willBeMipped))) {
if ((proxy = generator->generateTexture(ctx, this->imageInfo(), fOrigin, willBeMipped))) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kNative_LockTexturePath,
kLockTexturePathCount);
set_key_on_proxy(proxyProvider, proxy.get(), nullptr, key);
@ -429,9 +428,9 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(
// 3. Ask the generator to return YUV planes, which the GPU can convert. If we will be mipping
// the texture we fall through here and have the CPU generate the mip maps for us.
if (!proxy && !willBeMipped && !ctx->priv().options().fDisableGpuYUVConversion) {
const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(fInfo);
const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(this->imageInfo());
SkColorType colorType = fInfo.colorType();
SkColorType colorType = this->colorType();
GrBackendFormat format =
ctx->priv().caps()->getBackendFormatFromColorType(colorType);
@ -443,7 +442,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(
// color space. To correct this, apply a color space conversion from the generator's color
// space to this image's color space.
SkColorSpace* generatorColorSpace = fSharedGenerator->fGenerator->getInfo().colorSpace();
SkColorSpace* thisColorSpace = fInfo.colorSpace();
SkColorSpace* thisColorSpace = this->colorSpace();
// TODO: Update to create the mipped surface in the YUV generator and draw the base
// layer directly into the mipped surface.

View File

@ -35,12 +35,8 @@ public:
SkImage_Lazy(Validator* validator);
~SkImage_Lazy() override;
SkImageInfo onImageInfo() const override {
return fInfo;
}
SkIRect onGetSubset() const override {
return SkIRect::MakeXYWH(fOrigin.fX, fOrigin.fY, fInfo.width(), fInfo.height());
return SkIRect::MakeXYWH(fOrigin.fX, fOrigin.fY, this->width(), this->height());
}
bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY,
@ -77,10 +73,10 @@ public:
private:
class ScopedGenerator;
// Note that this->imageInfo() is not necessarily the info from the generator. It may be
// cropped by onMakeSubset and its color type/space may be changed by
// onMakeColorTypeAndColorSpace.
sk_sp<SharedGenerator> fSharedGenerator;
// Note that fInfo is not necessarily the info from the generator. It may be cropped by
// onMakeSubset and its color type/space may be changed by onMakeColorTypeAndColorSpace.
const SkImageInfo fInfo;
const SkIPoint fOrigin;
uint32_t fUniqueID;

View File

@ -72,10 +72,6 @@ public:
uint32_t id = kNeedNewImageUniqueID);
~SkImage_Raster() override;
SkImageInfo onImageInfo() const override {
return fBitmap.info();
}
bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
bool onPeekPixels(SkPixmap*) const override;
const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
@ -93,11 +89,9 @@ public:
bool onAsLegacyBitmap(SkBitmap*) const override;
SkImage_Raster(const SkBitmap& bm, bool bitmapMayBeMutable = false)
: INHERITED(bm.width(), bm.height(),
is_not_subset(bm) ? bm.getGenerationID()
: (uint32_t)kNeedNewImageUniqueID)
, fBitmap(bm)
{
: INHERITED(bm.info(),
is_not_subset(bm) ? bm.getGenerationID() : (uint32_t)kNeedNewImageUniqueID)
, fBitmap(bm) {
SkASSERT(bitmapMayBeMutable || fBitmap.isImmutable());
}
@ -141,8 +135,7 @@ static void release_data(void* addr, void* context) {
SkImage_Raster::SkImage_Raster(const SkImageInfo& info, sk_sp<SkData> data, size_t rowBytes,
uint32_t id)
: INHERITED(info.width(), info.height(), id)
{
: INHERITED(info, id) {
void* addr = const_cast<void*>(data->data());
fBitmap.installPixels(info, addr, rowBytes, release_data, data.release());

View File

@ -41,7 +41,7 @@
using namespace sk_gpu_test;
SkImageInfo read_pixels_info(SkImage* image) {
if (as_IB(image)->onImageInfo().colorSpace()) {
if (image->colorSpace()) {
return SkImageInfo::MakeS32(image->width(), image->height(), image->alphaType());
}