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;
|
sk_sp<GrTextureProxy> proxy;
|
||||||
if (fFilter == GrSamplerState::Filter::kMipMap) {
|
if (fFilter == GrSamplerState::Filter::kMipMap) {
|
||||||
SkBitmap copy;
|
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)) {
|
if (!copy.tryAllocPixels(info) || !fImage->readPixels(copy.pixmap(), 0, 0)) {
|
||||||
*errorMsg = "Failed to read pixels.";
|
*errorMsg = "Failed to read pixels.";
|
||||||
return DrawResult::kFail;
|
return DrawResult::kFail;
|
||||||
|
@ -1111,7 +1111,7 @@ protected:
|
|||||||
y += kTileWidthHeight + kPad;
|
y += kTileWidthHeight + kPad;
|
||||||
|
|
||||||
SkBitmap readBack;
|
SkBitmap readBack;
|
||||||
readBack.allocPixels(as_IB(yuv)->onImageInfo());
|
readBack.allocPixels(yuv->imageInfo());
|
||||||
yuv->readPixels(readBack.pixmap(), 0, 0);
|
yuv->readPixels(readBack.pixmap(), 0, 0);
|
||||||
canvas->drawBitmap(readBack, x, y);
|
canvas->drawBitmap(readBack, x, y);
|
||||||
|
|
||||||
|
@ -584,29 +584,36 @@ public:
|
|||||||
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
|
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
|
||||||
#endif
|
#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.
|
/** Returns pixel count in each row.
|
||||||
|
|
||||||
@return pixel width in SkImage
|
@return pixel width in SkImage
|
||||||
*/
|
*/
|
||||||
int width() const { return fWidth; }
|
int width() const { return fInfo.width(); }
|
||||||
|
|
||||||
/** Returns pixel row count.
|
/** Returns pixel row count.
|
||||||
|
|
||||||
@return pixel height in SkImage
|
@return pixel height in SkImage
|
||||||
*/
|
*/
|
||||||
int height() const { return fHeight; }
|
int height() const { return fInfo.height(); }
|
||||||
|
|
||||||
/** Returns SkISize { width(), height() }.
|
/** Returns SkISize { width(), height() }.
|
||||||
|
|
||||||
@return integral size of width() and 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() }.
|
/** Returns SkIRect { 0, 0, width(), height() }.
|
||||||
|
|
||||||
@return integral rectangle from origin to width() and 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
|
/** 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
|
created. Any operation to create a new SkImage will receive generate a new
|
||||||
@ -1071,11 +1078,10 @@ public:
|
|||||||
sk_sp<SkColorSpace> targetColorSpace) const;
|
sk_sp<SkColorSpace> targetColorSpace) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkImage(int width, int height, uint32_t uniqueID);
|
SkImage(const SkImageInfo& info, uint32_t uniqueID);
|
||||||
friend class SkImage_Base;
|
friend class SkImage_Base;
|
||||||
|
|
||||||
const int fWidth;
|
SkImageInfo fInfo;
|
||||||
const int fHeight;
|
|
||||||
const uint32_t fUniqueID;
|
const uint32_t fUniqueID;
|
||||||
|
|
||||||
typedef SkRefCnt INHERITED;
|
typedef SkRefCnt INHERITED;
|
||||||
|
@ -199,7 +199,7 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(GrRecordingContext* context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(proxy),
|
return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(proxy),
|
||||||
as_IB(image)->onImageInfo().refColorSpace(), props);
|
image->refColorSpace(), props);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -115,9 +115,9 @@ std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProc
|
|||||||
|
|
||||||
auto fp = GrYUVtoRGBEffect::Make(fImage->fProxies, fImage->fYUVAIndices,
|
auto fp = GrYUVtoRGBEffect::Make(fImage->fProxies, fImage->fYUVAIndices,
|
||||||
fImage->fYUVColorSpace, filter);
|
fImage->fYUVColorSpace, filter);
|
||||||
if (fImage->fTargetColorSpace) {
|
if (fImage->fFromColorSpace) {
|
||||||
fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fColorSpace.get(),
|
fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fFromColorSpace.get(),
|
||||||
fImage->alphaType(), fImage->fTargetColorSpace.get());
|
fImage->alphaType(), fImage->colorSpace());
|
||||||
}
|
}
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(sk_sp<SkImage> srcImag
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkImageInfo info = as_IB(srcImage)->onImageInfo();
|
const SkImageInfo& info = srcImage->imageInfo();
|
||||||
GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
|
GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
|
||||||
|
|
||||||
if (kUnknown_GrPixelConfig == config) {
|
if (kUnknown_GrPixelConfig == config) {
|
||||||
|
@ -1187,7 +1187,7 @@ sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) {
|
|||||||
SkIRect::MakeWH(image->width(), image->height()),
|
SkIRect::MakeWH(image->width(), image->height()),
|
||||||
image->uniqueID(),
|
image->uniqueID(),
|
||||||
std::move(proxy),
|
std::move(proxy),
|
||||||
as_IB(image)->onImageInfo().refColorSpace(),
|
image->refColorSpace(),
|
||||||
&this->surfaceProps());
|
&this->surfaceProps());
|
||||||
} else if (image->peekPixels(&pm)) {
|
} else if (image->peekPixels(&pm)) {
|
||||||
SkBitmap bm;
|
SkBitmap bm;
|
||||||
@ -1307,9 +1307,8 @@ void SkGpuDevice::drawImageNine(const SkImage* image,
|
|||||||
auto iter = skstd::make_unique<SkLatticeIter>(image->width(), image->height(), center, dst);
|
auto iter = skstd::make_unique<SkLatticeIter>(image->width(), image->height(), center, dst);
|
||||||
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(this->context(),
|
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(this->context(),
|
||||||
&pinnedUniqueID)) {
|
&pinnedUniqueID)) {
|
||||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
|
GrTextureAdjuster adjuster(this->context(), std::move(proxy), image->alphaType(),
|
||||||
image->alphaType(), pinnedUniqueID,
|
pinnedUniqueID, image->colorSpace());
|
||||||
as_IB(image)->onImageInfo().colorSpace());
|
|
||||||
this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
|
this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
|
||||||
} else {
|
} else {
|
||||||
SkBitmap bm;
|
SkBitmap bm;
|
||||||
@ -1368,9 +1367,8 @@ void SkGpuDevice::drawImageLattice(const SkImage* image,
|
|||||||
auto iter = skstd::make_unique<SkLatticeIter>(lattice, dst);
|
auto iter = skstd::make_unique<SkLatticeIter>(lattice, dst);
|
||||||
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(this->context(),
|
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(this->context(),
|
||||||
&pinnedUniqueID)) {
|
&pinnedUniqueID)) {
|
||||||
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
|
GrTextureAdjuster adjuster(this->context(), std::move(proxy), image->alphaType(),
|
||||||
image->alphaType(), pinnedUniqueID,
|
pinnedUniqueID, image->colorSpace());
|
||||||
as_IB(image)->onImageInfo().colorSpace());
|
|
||||||
this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
|
this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
|
||||||
} else {
|
} else {
|
||||||
SkBitmap bm;
|
SkBitmap bm;
|
||||||
|
@ -32,13 +32,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "GrBackendSurface.h"
|
#include "GrBackendSurface.h"
|
||||||
|
|
||||||
SkImage::SkImage(int width, int height, uint32_t uniqueID)
|
SkImage::SkImage(const SkImageInfo& info, uint32_t uniqueID)
|
||||||
: fWidth(width)
|
: fInfo(info)
|
||||||
, fHeight(height)
|
, fUniqueID(kNeedNewImageUniqueID == uniqueID ? SkNextID::ImageID() : uniqueID) {
|
||||||
, fUniqueID(kNeedNewImageUniqueID == uniqueID ? SkNextID::ImageID() : uniqueID)
|
SkASSERT(info.width() > 0);
|
||||||
{
|
SkASSERT(info.height() > 0);
|
||||||
SkASSERT(width > 0);
|
|
||||||
SkASSERT(height > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkImage::peekPixels(SkPixmap* pm) const {
|
bool SkImage::peekPixels(SkPixmap* pm) const {
|
||||||
@ -49,8 +47,8 @@ bool SkImage::peekPixels(SkPixmap* pm) const {
|
|||||||
return as_IB(this)->onPeekPixels(pm);
|
return as_IB(this)->onPeekPixels(pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
|
bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, int srcX,
|
||||||
int srcX, int srcY, CachingHint chint) const {
|
int srcY, CachingHint chint) const {
|
||||||
return as_IB(this)->onReadPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY, chint);
|
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 {
|
SkColorType SkImage::colorType() const { return fInfo.colorType(); }
|
||||||
return as_IB(this)->onImageInfo().colorType();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkAlphaType SkImage::alphaType() const {
|
SkAlphaType SkImage::alphaType() const { return fInfo.alphaType(); }
|
||||||
return as_IB(this)->onImageInfo().alphaType();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkColorSpace* SkImage::colorSpace() const {
|
SkColorSpace* SkImage::colorSpace() const { return fInfo.colorSpace(); }
|
||||||
return as_IB(this)->onImageInfo().colorSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<SkColorSpace> SkImage::refColorSpace() const {
|
sk_sp<SkColorSpace> SkImage::refColorSpace() const { return fInfo.refColorSpace(); }
|
||||||
return as_IB(this)->onImageInfo().refColorSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<SkShader> SkImage::makeShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
|
sk_sp<SkShader> SkImage::makeShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
|
||||||
const SkMatrix* localMatrix) const {
|
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)
|
SkImage_Base::SkImage_Base(const SkImageInfo& info, uint32_t uniqueID)
|
||||||
: INHERITED(width, height, uniqueID)
|
: INHERITED(info, uniqueID), fAddedToRasterCache(false) {}
|
||||||
, fAddedToRasterCache(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SkImage_Base::~SkImage_Base() {
|
SkImage_Base::~SkImage_Base() {
|
||||||
if (fAddedToRasterCache.load()) {
|
if (fAddedToRasterCache.load()) {
|
||||||
@ -234,7 +222,7 @@ sk_sp<SkCachedData> SkImage_Base::getPlanes(SkYUVASizeInfo*, SkYUVAIndex[4],
|
|||||||
bool SkImage_Base::onAsLegacyBitmap(SkBitmap* bitmap) const {
|
bool SkImage_Base::onAsLegacyBitmap(SkBitmap* bitmap) const {
|
||||||
// As the base-class, all we can do is make a copy (regardless of mode).
|
// As the base-class, all we can do is make a copy (regardless of mode).
|
||||||
// Subclasses that want to be more optimal should override.
|
// 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)) {
|
if (!bitmap->tryAllocPixels(info)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -282,8 +270,7 @@ sk_sp<SkImage> SkImage::makeWithFilter(GrContext* grContext,
|
|||||||
|
|
||||||
sk_sp<SkImageFilterCache> cache(
|
sk_sp<SkImageFilterCache> cache(
|
||||||
SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize));
|
SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize));
|
||||||
SkImageFilter::OutputProperties outputProperties(as_IB(this)->onImageInfo().colorType(),
|
SkImageFilter::OutputProperties outputProperties(fInfo.colorType(), fInfo.colorSpace());
|
||||||
as_IB(this)->onImageInfo().colorSpace());
|
|
||||||
SkImageFilter::Context context(SkMatrix::I(), clipBounds, cache.get(), outputProperties);
|
SkImageFilter::Context context(SkMatrix::I(), clipBounds, cache.get(), outputProperties);
|
||||||
|
|
||||||
sk_sp<SkSpecialImage> result = filter->filterImage(srcSpecialImage.get(), context, offset);
|
sk_sp<SkSpecialImage> result = filter->filterImage(srcSpecialImage.get(), context, offset);
|
||||||
@ -307,9 +294,7 @@ bool SkImage::isLazyGenerated() const {
|
|||||||
return as_IB(this)->onIsLazyGenerated();
|
return as_IB(this)->onIsLazyGenerated();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkImage::isAlphaOnly() const {
|
bool SkImage::isAlphaOnly() const { return SkColorTypeIsAlphaOnly(fInfo.colorType()); }
|
||||||
return as_IB(this)->onImageInfo().colorType() == kAlpha_8_SkColorType;
|
|
||||||
}
|
|
||||||
|
|
||||||
sk_sp<SkImage> SkImage::makeColorSpace(sk_sp<SkColorSpace> target) const {
|
sk_sp<SkImage> SkImage::makeColorSpace(sk_sp<SkColorSpace> target) const {
|
||||||
if (!target) {
|
if (!target) {
|
||||||
@ -374,20 +359,19 @@ sk_sp<SkImage> SkImage::makeRasterImage() const {
|
|||||||
return sk_ref_sp(const_cast<SkImage*>(this));
|
return sk_ref_sp(const_cast<SkImage*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
const SkImageInfo info = as_IB(this)->onImageInfo();
|
const size_t rowBytes = fInfo.minRowBytes();
|
||||||
const size_t rowBytes = info.minRowBytes();
|
size_t size = fInfo.computeByteSize(rowBytes);
|
||||||
size_t size = info.computeByteSize(rowBytes);
|
|
||||||
if (SkImageInfo::ByteSizeOverflowed(size)) {
|
if (SkImageInfo::ByteSizeOverflowed(size)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<SkData> data = SkData::MakeUninitialized(size);
|
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)) {
|
if (!this->readPixels(pm, 0, 0)) {
|
||||||
return nullptr;
|
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,
|
sk_sp<SkImage> SkImageMakeRasterCopyAndAssignColorSpace(const SkImage* src,
|
||||||
SkColorSpace* colorSpace) {
|
SkColorSpace* colorSpace) {
|
||||||
// Read the pixels out of the source image, with no conversion
|
// 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()) {
|
if (kUnknown_SkColorType == info.colorType()) {
|
||||||
SkDEBUGFAIL("Unexpected color type");
|
SkDEBUGFAIL("Unexpected color type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -34,11 +34,6 @@ class SkImage_Base : public SkImage {
|
|||||||
public:
|
public:
|
||||||
virtual ~SkImage_Base();
|
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 {
|
virtual SkIRect onGetSubset() const {
|
||||||
return { 0, 0, this->width(), this->height() };
|
return { 0, 0, this->width(), this->height() };
|
||||||
}
|
}
|
||||||
@ -104,7 +99,7 @@ public:
|
|||||||
virtual sk_sp<SkImage> onMakeColorTypeAndColorSpace(GrRecordingContext*,
|
virtual sk_sp<SkImage> onMakeColorTypeAndColorSpace(GrRecordingContext*,
|
||||||
SkColorType, sk_sp<SkColorSpace>) const = 0;
|
SkColorType, sk_sp<SkColorSpace>) const = 0;
|
||||||
protected:
|
protected:
|
||||||
SkImage_Base(int width, int height, uint32_t uniqueID);
|
SkImage_Base(const SkImageInfo& info, uint32_t uniqueID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Set true by caches when they cache content that's derived from the current pixels.
|
// Set true by caches when they cache content that's derived from the current pixels.
|
||||||
|
@ -48,23 +48,22 @@
|
|||||||
#include "effects/GrYUVtoRGBEffect.h"
|
#include "effects/GrYUVtoRGBEffect.h"
|
||||||
#include "gl/GrGLTexture.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,
|
SkImage_Gpu::SkImage_Gpu(sk_sp<GrContext> context, uint32_t uniqueID, SkAlphaType at,
|
||||||
sk_sp<GrTextureProxy> proxy, sk_sp<SkColorSpace> colorSpace)
|
sk_sp<GrTextureProxy> proxy, sk_sp<SkColorSpace> colorSpace)
|
||||||
: INHERITED(std::move(context), proxy->worstCaseWidth(), proxy->worstCaseHeight(), uniqueID,
|
: INHERITED(std::move(context), proxy->worstCaseWidth(), proxy->worstCaseHeight(), uniqueID,
|
||||||
at, colorSpace)
|
proxy_color_type(proxy.get()), at, colorSpace)
|
||||||
, fProxy(std::move(proxy)) {}
|
, fProxy(std::move(proxy)) {}
|
||||||
|
|
||||||
SkImage_Gpu::~SkImage_Gpu() {}
|
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,
|
sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(GrRecordingContext* context,
|
||||||
SkColorType targetCT,
|
SkColorType targetCT,
|
||||||
sk_sp<SkColorSpace> targetCS) const {
|
sk_sp<SkColorSpace> targetCS) const {
|
||||||
@ -72,8 +71,8 @@ sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(GrRecordingContext* con
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto xform = GrColorSpaceXformEffect::Make(fColorSpace.get(), fAlphaType,
|
auto xform = GrColorSpaceXformEffect::Make(this->colorSpace(), this->alphaType(),
|
||||||
targetCS.get(), fAlphaType);
|
targetCS.get(), this->alphaType());
|
||||||
SkASSERT(xform || targetCT != this->colorType());
|
SkASSERT(xform || targetCT != this->colorType());
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef(context);
|
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
|
// 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));
|
renderTargetContext->asTextureProxyRef(), std::move(targetCS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +468,7 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<Sk
|
|||||||
if (limitToMaxTextureSize &&
|
if (limitToMaxTextureSize &&
|
||||||
(codecImage->width() > maxTextureSize || codecImage->height() > maxTextureSize)) {
|
(codecImage->width() > maxTextureSize || codecImage->height() > maxTextureSize)) {
|
||||||
SkAutoPixmapStorage pmap;
|
SkAutoPixmapStorage pmap;
|
||||||
SkImageInfo info = as_IB(codecImage)->onImageInfo();
|
SkImageInfo info = codecImage->imageInfo();
|
||||||
if (!dstColorSpace) {
|
if (!dstColorSpace) {
|
||||||
info = info.makeColorSpace(nullptr);
|
info = info.makeColorSpace(nullptr);
|
||||||
}
|
}
|
||||||
@ -504,11 +503,9 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<Sk
|
|||||||
GrGpu* gpu = context->priv().getGpu();
|
GrGpu* gpu = context->priv().getGpu();
|
||||||
sk_sp<GrSemaphore> sema = gpu->prepareTextureForCrossContextUsage(texture.get());
|
sk_sp<GrSemaphore> sema = gpu->prepareTextureForCrossContextUsage(texture.get());
|
||||||
|
|
||||||
auto gen = GrBackendTextureImageGenerator::Make(std::move(texture), proxy->origin(),
|
auto gen = GrBackendTextureImageGenerator::Make(
|
||||||
std::move(sema),
|
std::move(texture), proxy->origin(), std::move(sema), codecImage->colorType(),
|
||||||
as_IB(codecImage)->onImageInfo().colorType(),
|
codecImage->alphaType(), codecImage->refColorSpace());
|
||||||
codecImage->alphaType(),
|
|
||||||
codecImage->refColorSpace());
|
|
||||||
return SkImage::MakeFromGenerator(std::move(gen));
|
return SkImage::MakeFromGenerator(std::move(gen));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,6 @@ public:
|
|||||||
sk_sp<SkColorSpace>);
|
sk_sp<SkColorSpace>);
|
||||||
~SkImage_Gpu() override;
|
~SkImage_Gpu() override;
|
||||||
|
|
||||||
SkImageInfo onImageInfo() const override;
|
|
||||||
|
|
||||||
GrTextureProxy* peekProxy() const override {
|
GrTextureProxy* peekProxy() const override {
|
||||||
return fProxy.get();
|
return fProxy.get();
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,9 @@
|
|||||||
#include "effects/GrYUVtoRGBEffect.h"
|
#include "effects/GrYUVtoRGBEffect.h"
|
||||||
|
|
||||||
SkImage_GpuBase::SkImage_GpuBase(sk_sp<GrContext> context, int width, int height, uint32_t uniqueID,
|
SkImage_GpuBase::SkImage_GpuBase(sk_sp<GrContext> context, int width, int height, uint32_t uniqueID,
|
||||||
SkAlphaType at, sk_sp<SkColorSpace> cs)
|
SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
|
||||||
: INHERITED(width, height, uniqueID)
|
: INHERITED(SkImageInfo::Make(width, height, ct, at, std::move(cs)), uniqueID)
|
||||||
, fContext(std::move(context))
|
, fContext(std::move(context)) {}
|
||||||
, fAlphaType(at)
|
|
||||||
, fColorSpace(std::move(cs)) {}
|
|
||||||
|
|
||||||
SkImage_GpuBase::~SkImage_GpuBase() {}
|
SkImage_GpuBase::~SkImage_GpuBase() {}
|
||||||
|
|
||||||
@ -79,18 +77,18 @@ bool SkImage_GpuBase::getROPixels(SkBitmap* dst, CachingHint chint) const {
|
|||||||
SkBitmapCache::RecPtr rec = nullptr;
|
SkBitmapCache::RecPtr rec = nullptr;
|
||||||
SkPixmap pmap;
|
SkPixmap pmap;
|
||||||
if (kAllow_CachingHint == chint) {
|
if (kAllow_CachingHint == chint) {
|
||||||
rec = SkBitmapCache::Alloc(desc, this->onImageInfo(), &pmap);
|
rec = SkBitmapCache::Alloc(desc, this->imageInfo(), &pmap);
|
||||||
if (!rec) {
|
if (!rec) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!dst->tryAllocPixels(this->onImageInfo()) || !dst->peekPixels(&pmap)) {
|
if (!dst->tryAllocPixels(this->imageInfo()) || !dst->peekPixels(&pmap)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<GrSurfaceContext> sContext = direct->priv().makeWrappedSurfaceContext(
|
sk_sp<GrSurfaceContext> sContext = direct->priv().makeWrappedSurfaceContext(
|
||||||
this->asTextureProxyRef(direct), fColorSpace);
|
this->asTextureProxyRef(direct), this->refColorSpace());
|
||||||
if (!sContext) {
|
if (!sContext) {
|
||||||
return false;
|
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
|
// 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());
|
sContext->asTextureProxyRef(), this->refColorSpace());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +169,7 @@ bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SkImageInfoValidConversion(dstInfo, this->onImageInfo())) {
|
if (!SkImageInfoValidConversion(dstInfo, this->imageInfo())) {
|
||||||
return false;
|
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
|
// TODO: this seems to duplicate code in GrTextureContext::onReadPixels and
|
||||||
// GrRenderTargetContext::onReadPixels
|
// GrRenderTargetContext::onReadPixels
|
||||||
uint32_t flags = 0;
|
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
|
// let the GPU perform this transformation for us
|
||||||
flags = GrContextPriv::kUnpremul_PixelOpsFlag;
|
flags = GrContextPriv::kUnpremul_PixelOpsFlag;
|
||||||
}
|
}
|
||||||
@ -206,7 +205,8 @@ bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
|
|||||||
//
|
//
|
||||||
// Should this be handled by Ganesh? todo:?
|
// 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);
|
apply_premul(rec.fInfo, rec.fPixels, rec.fRowBytes);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -220,8 +220,8 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::asTextureProxyRef(GrRecordingContext* con
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrTextureAdjuster adjuster(fContext.get(), this->asTextureProxyRef(context), fAlphaType,
|
GrTextureAdjuster adjuster(fContext.get(), this->asTextureProxyRef(context), this->alphaType(),
|
||||||
this->uniqueID(), fColorSpace.get());
|
this->uniqueID(), this->colorSpace());
|
||||||
return adjuster.refTextureProxyForParams(params, scaleAdjust);
|
return adjuster.refTextureProxyForParams(params, scaleAdjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ class SkColorSpace;
|
|||||||
|
|
||||||
class SkImage_GpuBase : public SkImage_Base {
|
class SkImage_GpuBase : public SkImage_Base {
|
||||||
public:
|
public:
|
||||||
SkImage_GpuBase(sk_sp<GrContext>, int width, int height, uint32_t uniqueID, SkAlphaType,
|
SkImage_GpuBase(sk_sp<GrContext>, int width, int height, uint32_t uniqueID, SkColorType,
|
||||||
sk_sp<SkColorSpace>);
|
SkAlphaType, sk_sp<SkColorSpace>);
|
||||||
~SkImage_GpuBase() override;
|
~SkImage_GpuBase() override;
|
||||||
|
|
||||||
GrContext* context() const final { return fContext.get(); }
|
GrContext* context() const final { return fContext.get(); }
|
||||||
@ -94,9 +94,7 @@ protected:
|
|||||||
const sk_sp<GrTextureProxy> proxies[4],
|
const sk_sp<GrTextureProxy> proxies[4],
|
||||||
const SkYUVAIndex yuvaIndices[4]);
|
const SkYUVAIndex yuvaIndices[4]);
|
||||||
|
|
||||||
sk_sp<GrContext> fContext;
|
sk_sp<GrContext> fContext;
|
||||||
const SkAlphaType fAlphaType; // alpha type for final image
|
|
||||||
sk_sp<SkColorSpace> fColorSpace; // color space for final image
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef SkImage_Base INHERITED;
|
typedef SkImage_Base INHERITED;
|
||||||
|
@ -27,15 +27,17 @@
|
|||||||
#include "SkYUVASizeInfo.h"
|
#include "SkYUVASizeInfo.h"
|
||||||
#include "effects/GrYUVtoRGBEffect.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,
|
SkImage_GpuYUVA::SkImage_GpuYUVA(sk_sp<GrContext> context, int width, int height, uint32_t uniqueID,
|
||||||
SkYUVColorSpace colorSpace, sk_sp<GrTextureProxy> proxies[],
|
SkYUVColorSpace colorSpace, sk_sp<GrTextureProxy> proxies[],
|
||||||
int numProxies, const SkYUVAIndex yuvaIndices[4],
|
int numProxies, const SkYUVAIndex yuvaIndices[4],
|
||||||
GrSurfaceOrigin origin, sk_sp<SkColorSpace> imageColorSpace)
|
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,
|
// 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
|
// although the planar data is always un-premul, the final interleaved RGB image
|
||||||
// is/would-be premul.
|
// is/would-be premul.
|
||||||
GetAlphaTypeFromYUVAIndices(yuvaIndices), imageColorSpace)
|
GetAlphaTypeFromYUVAIndices(yuvaIndices), std::move(imageColorSpace))
|
||||||
, fNumProxies(numProxies)
|
, fNumProxies(numProxies)
|
||||||
, fYUVColorSpace(colorSpace)
|
, fYUVColorSpace(colorSpace)
|
||||||
, fOrigin(origin) {
|
, fOrigin(origin) {
|
||||||
@ -52,16 +54,19 @@ SkImage_GpuYUVA::SkImage_GpuYUVA(sk_sp<GrContext> context, int width, int height
|
|||||||
|
|
||||||
// For onMakeColorSpace()
|
// For onMakeColorSpace()
|
||||||
SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpace> targetCS)
|
SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpace> targetCS)
|
||||||
: INHERITED(image->fContext, image->width(), image->height(), kNeedNewImageUniqueID,
|
: INHERITED(image->fContext, image->width(), image->height(), kNeedNewImageUniqueID,
|
||||||
// If an alpha channel is present we always switch to kPremul. This is because,
|
kAssumedColorType,
|
||||||
// although the planar data is always un-premul, the final interleaved RGB image
|
// If an alpha channel is present we always switch to kPremul. This is because,
|
||||||
// is/would-be premul.
|
// although the planar data is always un-premul, the final interleaved RGB image
|
||||||
GetAlphaTypeFromYUVAIndices(image->fYUVAIndices), image->fColorSpace)
|
// is/would-be premul.
|
||||||
, fNumProxies(image->fNumProxies)
|
GetAlphaTypeFromYUVAIndices(image->fYUVAIndices), std::move(targetCS))
|
||||||
, fYUVColorSpace(image->fYUVColorSpace)
|
, fNumProxies(image->fNumProxies)
|
||||||
, fOrigin(image->fOrigin)
|
, fYUVColorSpace(image->fYUVColorSpace)
|
||||||
, fTargetColorSpace(targetCS) {
|
, fOrigin(image->fOrigin)
|
||||||
// The caller should have done this work, just verifying
|
// 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;)
|
SkDEBUGCODE(int textureCount;)
|
||||||
SkASSERT(SkYUVAIndex::AreValidIndices(image->fYUVAIndices, &textureCount));
|
SkASSERT(SkYUVAIndex::AreValidIndices(image->fYUVAIndices, &textureCount));
|
||||||
SkASSERT(textureCount == fNumProxies);
|
SkASSERT(textureCount == fNumProxies);
|
||||||
@ -74,12 +79,6 @@ SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpac
|
|||||||
|
|
||||||
SkImage_GpuYUVA::~SkImage_GpuYUVA() {}
|
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 {
|
bool SkImage_GpuYUVA::setupMipmapsForPlanes(GrRecordingContext* context) const {
|
||||||
if (!context || !fContext->priv().matches(context)) {
|
if (!context || !fContext->priv().matches(context)) {
|
||||||
return false;
|
return false;
|
||||||
@ -118,19 +117,22 @@ sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef(GrRecordingContext* con
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GrBackendFormat format =
|
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.
|
// Needs to create a render target in order to draw to it for the yuv->rgb conversion.
|
||||||
sk_sp<GrRenderTargetContext> renderTargetContext(
|
sk_sp<GrRenderTargetContext> renderTargetContext(
|
||||||
context->priv().makeDeferredRenderTargetContext(
|
context->priv().makeDeferredRenderTargetContext(
|
||||||
format, SkBackingFit::kExact, this->width(), this->height(),
|
format, SkBackingFit::kExact, this->width(), this->height(),
|
||||||
kRGBA_8888_GrPixelConfig, fColorSpace, 1, GrMipMapped::kNo, fOrigin));
|
kRGBA_8888_GrPixelConfig, this->refColorSpace(), 1, GrMipMapped::kNo, fOrigin));
|
||||||
if (!renderTargetContext) {
|
if (!renderTargetContext) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto colorSpaceXform = GrColorSpaceXform::Make(fColorSpace.get(), fAlphaType,
|
sk_sp<GrColorSpaceXform> colorSpaceXform;
|
||||||
fTargetColorSpace.get(), fAlphaType);
|
if (fFromColorSpace) {
|
||||||
|
colorSpaceXform = GrColorSpaceXform::Make(fFromColorSpace.get(), this->alphaType(),
|
||||||
|
this->colorSpace(), this->alphaType());
|
||||||
|
}
|
||||||
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
|
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
|
||||||
if (!RenderYUVAToRGBA(fContext.get(), renderTargetContext.get(), rect, fYUVColorSpace,
|
if (!RenderYUVAToRGBA(fContext.get(), renderTargetContext.get(), rect, fYUVColorSpace,
|
||||||
std::move(colorSpaceXform), fProxies, fYUVAIndices)) {
|
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
|
SkAlphaType at = (-1 != yuvaIndices[SkYUVAIndex::kA_Index].fIndex) ? kPremul_SkAlphaType
|
||||||
: kOpaque_SkAlphaType;
|
: kOpaque_SkAlphaType;
|
||||||
SkImageInfo info = SkImageInfo::Make(imageWidth, imageHeight, kRGBA_8888_SkColorType,
|
SkImageInfo info = SkImageInfo::Make(imageWidth, imageHeight, kAssumedColorType,
|
||||||
at, imageColorSpace);
|
at, imageColorSpace);
|
||||||
if (!SkImageInfoIsValid(info)) {
|
if (!SkImageInfoIsValid(info)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -29,8 +29,6 @@ public:
|
|||||||
GrSurfaceOrigin, sk_sp<SkColorSpace>);
|
GrSurfaceOrigin, sk_sp<SkColorSpace>);
|
||||||
~SkImage_GpuYUVA() override;
|
~SkImage_GpuYUVA() override;
|
||||||
|
|
||||||
SkImageInfo onImageInfo() const override;
|
|
||||||
|
|
||||||
// This returns the single backing proxy if the YUV channels have already been flattened but
|
// This returns the single backing proxy if the YUV channels have already been flattened but
|
||||||
// nullptr if they have not.
|
// nullptr if they have not.
|
||||||
GrTextureProxy* peekProxy() const override;
|
GrTextureProxy* peekProxy() const override;
|
||||||
@ -86,7 +84,10 @@ private:
|
|||||||
SkYUVAIndex fYUVAIndices[4];
|
SkYUVAIndex fYUVAIndices[4];
|
||||||
const SkYUVColorSpace fYUVColorSpace;
|
const SkYUVColorSpace fYUVColorSpace;
|
||||||
GrSurfaceOrigin fOrigin;
|
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
|
// 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.
|
// SkImage_GpuYUVA instances. Cache the result of the last successful onMakeColorSpace call.
|
||||||
|
@ -123,9 +123,8 @@ private:
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkImage_Lazy::SkImage_Lazy(Validator* validator)
|
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))
|
, fSharedGenerator(std::move(validator->fSharedGenerator))
|
||||||
, fInfo(validator->fInfo)
|
|
||||||
, fOrigin(validator->fOrigin) {
|
, fOrigin(validator->fOrigin) {
|
||||||
SkASSERT(fSharedGenerator);
|
SkASSERT(fSharedGenerator);
|
||||||
fUniqueID = validator->fUniqueID;
|
fUniqueID = validator->fUniqueID;
|
||||||
@ -193,7 +192,7 @@ bool SkImage_Lazy::getROPixels(SkBitmap* bitmap, SkImage::CachingHint chint) con
|
|||||||
|
|
||||||
if (SkImage::kAllow_CachingHint == chint) {
|
if (SkImage::kAllow_CachingHint == chint) {
|
||||||
SkPixmap pmap;
|
SkPixmap pmap;
|
||||||
SkBitmapCache::RecPtr cacheRec = SkBitmapCache::Alloc(desc, fInfo, &pmap);
|
SkBitmapCache::RecPtr cacheRec = SkBitmapCache::Alloc(desc, this->imageInfo(), &pmap);
|
||||||
if (!cacheRec ||
|
if (!cacheRec ||
|
||||||
!generate_pixels(ScopedGenerator(fSharedGenerator), pmap,
|
!generate_pixels(ScopedGenerator(fSharedGenerator), pmap,
|
||||||
fOrigin.x(), fOrigin.y())) {
|
fOrigin.x(), fOrigin.y())) {
|
||||||
@ -202,9 +201,9 @@ bool SkImage_Lazy::getROPixels(SkBitmap* bitmap, SkImage::CachingHint chint) con
|
|||||||
SkBitmapCache::Add(std::move(cacheRec), bitmap);
|
SkBitmapCache::Add(std::move(cacheRec), bitmap);
|
||||||
this->notifyAddedToRasterCache();
|
this->notifyAddedToRasterCache();
|
||||||
} else {
|
} else {
|
||||||
if (!bitmap->tryAllocPixels(fInfo) ||
|
if (!bitmap->tryAllocPixels(this->imageInfo()) ||
|
||||||
!generate_pixels(ScopedGenerator(fSharedGenerator), bitmap->pixmap(),
|
!generate_pixels(ScopedGenerator(fSharedGenerator), bitmap->pixmap(), fOrigin.x(),
|
||||||
fOrigin.x(), fOrigin.y())) {
|
fOrigin.y())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bitmap->setImmutable();
|
bitmap->setImmutable();
|
||||||
@ -252,12 +251,12 @@ sk_sp<GrTextureProxy> SkImage_Lazy::asTextureProxyRef(GrRecordingContext* contex
|
|||||||
|
|
||||||
sk_sp<SkImage> SkImage_Lazy::onMakeSubset(GrRecordingContext* context,
|
sk_sp<SkImage> SkImage_Lazy::onMakeSubset(GrRecordingContext* context,
|
||||||
const SkIRect& subset) const {
|
const SkIRect& subset) const {
|
||||||
SkASSERT(fInfo.bounds().contains(subset));
|
SkASSERT(this->bounds().contains(subset));
|
||||||
SkASSERT(fInfo.bounds() != subset);
|
SkASSERT(this->bounds() != subset);
|
||||||
|
|
||||||
const SkIRect generatorSubset = subset.makeOffset(fOrigin.x(), fOrigin.y());
|
const SkIRect generatorSubset = subset.makeOffset(fOrigin.x(), fOrigin.y());
|
||||||
const SkColorType colorType = fInfo.colorType();
|
const SkColorType colorType = this->colorType();
|
||||||
Validator validator(fSharedGenerator, &generatorSubset, &colorType, fInfo.refColorSpace());
|
Validator validator(fSharedGenerator, &generatorSubset, &colorType, this->refColorSpace());
|
||||||
return validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
|
return validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +270,7 @@ sk_sp<SkImage> SkImage_Lazy::onMakeColorTypeAndColorSpace(GrRecordingContext*,
|
|||||||
return fOnMakeColorTypeAndSpaceResult;
|
return fOnMakeColorTypeAndSpaceResult;
|
||||||
}
|
}
|
||||||
const SkIRect generatorSubset =
|
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);
|
Validator validator(fSharedGenerator, &generatorSubset, &targetCT, targetCS);
|
||||||
sk_sp<SkImage> result = validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
|
sk_sp<SkImage> result = validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -414,7 +413,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(
|
|||||||
SkImageGenerator::TexGenType::kCheap != generator->onCanGenerateTexture()) {
|
SkImageGenerator::TexGenType::kCheap != generator->onCanGenerateTexture()) {
|
||||||
return nullptr;
|
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,
|
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kNative_LockTexturePath,
|
||||||
kLockTexturePathCount);
|
kLockTexturePathCount);
|
||||||
set_key_on_proxy(proxyProvider, proxy.get(), nullptr, key);
|
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
|
// 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.
|
// the texture we fall through here and have the CPU generate the mip maps for us.
|
||||||
if (!proxy && !willBeMipped && !ctx->priv().options().fDisableGpuYUVConversion) {
|
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 =
|
GrBackendFormat format =
|
||||||
ctx->priv().caps()->getBackendFormatFromColorType(colorType);
|
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
|
// color space. To correct this, apply a color space conversion from the generator's color
|
||||||
// space to this image's color space.
|
// space to this image's color space.
|
||||||
SkColorSpace* generatorColorSpace = fSharedGenerator->fGenerator->getInfo().colorSpace();
|
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
|
// TODO: Update to create the mipped surface in the YUV generator and draw the base
|
||||||
// layer directly into the mipped surface.
|
// layer directly into the mipped surface.
|
||||||
|
@ -35,12 +35,8 @@ public:
|
|||||||
SkImage_Lazy(Validator* validator);
|
SkImage_Lazy(Validator* validator);
|
||||||
~SkImage_Lazy() override;
|
~SkImage_Lazy() override;
|
||||||
|
|
||||||
SkImageInfo onImageInfo() const override {
|
|
||||||
return fInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkIRect onGetSubset() const override {
|
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,
|
bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY,
|
||||||
@ -77,10 +73,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
class ScopedGenerator;
|
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;
|
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;
|
const SkIPoint fOrigin;
|
||||||
|
|
||||||
uint32_t fUniqueID;
|
uint32_t fUniqueID;
|
||||||
|
@ -72,10 +72,6 @@ public:
|
|||||||
uint32_t id = kNeedNewImageUniqueID);
|
uint32_t id = kNeedNewImageUniqueID);
|
||||||
~SkImage_Raster() override;
|
~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 onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
|
||||||
bool onPeekPixels(SkPixmap*) const override;
|
bool onPeekPixels(SkPixmap*) const override;
|
||||||
const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
|
const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
|
||||||
@ -93,11 +89,9 @@ public:
|
|||||||
bool onAsLegacyBitmap(SkBitmap*) const override;
|
bool onAsLegacyBitmap(SkBitmap*) const override;
|
||||||
|
|
||||||
SkImage_Raster(const SkBitmap& bm, bool bitmapMayBeMutable = false)
|
SkImage_Raster(const SkBitmap& bm, bool bitmapMayBeMutable = false)
|
||||||
: INHERITED(bm.width(), bm.height(),
|
: INHERITED(bm.info(),
|
||||||
is_not_subset(bm) ? bm.getGenerationID()
|
is_not_subset(bm) ? bm.getGenerationID() : (uint32_t)kNeedNewImageUniqueID)
|
||||||
: (uint32_t)kNeedNewImageUniqueID)
|
, fBitmap(bm) {
|
||||||
, fBitmap(bm)
|
|
||||||
{
|
|
||||||
SkASSERT(bitmapMayBeMutable || fBitmap.isImmutable());
|
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,
|
SkImage_Raster::SkImage_Raster(const SkImageInfo& info, sk_sp<SkData> data, size_t rowBytes,
|
||||||
uint32_t id)
|
uint32_t id)
|
||||||
: INHERITED(info.width(), info.height(), id)
|
: INHERITED(info, id) {
|
||||||
{
|
|
||||||
void* addr = const_cast<void*>(data->data());
|
void* addr = const_cast<void*>(data->data());
|
||||||
|
|
||||||
fBitmap.installPixels(info, addr, rowBytes, release_data, data.release());
|
fBitmap.installPixels(info, addr, rowBytes, release_data, data.release());
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
using namespace sk_gpu_test;
|
using namespace sk_gpu_test;
|
||||||
|
|
||||||
SkImageInfo read_pixels_info(SkImage* image) {
|
SkImageInfo read_pixels_info(SkImage* image) {
|
||||||
if (as_IB(image)->onImageInfo().colorSpace()) {
|
if (image->colorSpace()) {
|
||||||
return SkImageInfo::MakeS32(image->width(), image->height(), image->alphaType());
|
return SkImageInfo::MakeS32(image->width(), image->height(), image->alphaType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user