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:
parent
adc94d96bb
commit
5ad6fd3160
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,6 @@ public:
|
||||
sk_sp<SkColorSpace>);
|
||||
~SkImage_Gpu() override;
|
||||
|
||||
SkImageInfo onImageInfo() const override;
|
||||
|
||||
GrTextureProxy* peekProxy() const override {
|
||||
return fProxy.get();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user