Adding an SkColorSpace to SkImage_Gpu
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2165703003
Review-Url: https://codereview.chromium.org/2165703003
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index fb3e5c6..e8cd5e0 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -332,6 +332,7 @@
// No API to draw a GrTexture directly, so we cheat and create a private image subclass
SkAutoTUnref<SkImage> image(new SkImage_Gpu(cache->info().width(), cache->info().height(),
cache->uniqueID(), kPremul_SkAlphaType, texture,
+ sk_ref_sp(cache->info().colorSpace()),
SkBudgeted::kNo));
canvas->drawImage(image, x, y);
#endif
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index 6021590..fd20e5e 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -73,7 +73,7 @@
*
* If a subset is specified, it must be contained within the generator's bounds.
*/
- static sk_sp<SkImage> MakeFromGenerator(SkImageGenerator*, const SkIRect* subset = NULL);
+ static sk_sp<SkImage> MakeFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
/**
* Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
@@ -81,7 +81,7 @@
*
* If a subset is specified, it must be contained within the encoded data's bounds.
*/
- static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = NULL);
+ static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr);
/**
* Create a new image from the specified descriptor. Note - the caller is responsible for
@@ -90,12 +90,12 @@
* Will return NULL if the specified descriptor is unsupported.
*/
static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
- return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, NULL, NULL);
+ return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr, nullptr);
}
static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& de,
SkAlphaType at) {
- return MakeFromTexture(ctx, de, at, NULL, NULL);
+ return MakeFromTexture(ctx, de, at, nullptr, nullptr, nullptr);
}
typedef void (*TextureReleaseProc)(ReleaseContext);
@@ -107,8 +107,21 @@
*
* Will return NULL if the specified descriptor is unsupported.
*/
+ static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
+ SkAlphaType at, TextureReleaseProc trp,
+ ReleaseContext rc) {
+ return MakeFromTexture(ctx, desc, at, nullptr, trp, rc);
+ }
+
+ /**
+ * Create a new image from the specified descriptor. The underlying platform texture must stay
+ * valid and unaltered until the specified release-proc is invoked, indicating that Skia
+ * no longer is holding a reference to it.
+ *
+ * Will return NULL if the specified descriptor is unsupported.
+ */
static sk_sp<SkImage> MakeFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
- TextureReleaseProc, ReleaseContext);
+ sk_sp<SkColorSpace>, TextureReleaseProc, ReleaseContext);
/**
* Create a new image from the specified descriptor. Note - Skia will delete or recycle the
@@ -117,7 +130,8 @@
* Will return NULL if the specified descriptor is unsupported.
*/
static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
- SkAlphaType = kPremul_SkAlphaType);
+ SkAlphaType = kPremul_SkAlphaType,
+ sk_sp<SkColorSpace> = nullptr);
/**
* Create a new image by copying the pixels from the specified y, u, v textures. The data
@@ -127,7 +141,8 @@
static sk_sp<SkImage> MakeFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
const GrBackendObject yuvTextureHandles[3],
const SkISize yuvSizes[3],
- GrSurfaceOrigin);
+ GrSurfaceOrigin,
+ sk_sp<SkColorSpace> = nullptr);
/**
* Create a new image by copying the pixels from the specified y and uv textures. The data
@@ -136,7 +151,8 @@
*/
static sk_sp<SkImage> MakeFromNV12TexturesCopy(GrContext*, SkYUVColorSpace,
const GrBackendObject nv12TextureHandles[2],
- const SkISize nv12Sizes[2], GrSurfaceOrigin);
+ const SkISize nv12Sizes[2], GrSurfaceOrigin,
+ sk_sp<SkColorSpace> = nullptr);
static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture>, const SkISize& dimensions,
const SkMatrix*, const SkPaint*);
@@ -421,14 +437,14 @@
static SkImage* NewFromRaster(const Info&, const void* pixels, size_t rowBytes,
RasterReleaseProc, ReleaseContext);
static SkImage* NewFromBitmap(const SkBitmap&);
- static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = NULL);
- static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = NULL);
+ static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
+ static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = nullptr);
static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
- return NewFromTexture(ctx, desc, kPremul_SkAlphaType, NULL, NULL);
+ return NewFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr);
}
static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& de, SkAlphaType at) {
- return NewFromTexture(ctx, de, at, NULL, NULL);
+ return NewFromTexture(ctx, de, at, nullptr, nullptr);
}
static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
TextureReleaseProc, ReleaseContext);
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 881c015..31d53a7 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -86,6 +86,7 @@
////////////////////////////////////////////////////////////////////////////////
-SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque);
+SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque,
+ sk_sp<SkColorSpace> colorSpace = nullptr);
#endif
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index a4ffa19..4a3e46e 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -449,9 +449,10 @@
SkRect dst = SkRect::MakeXYWH(x, y,
this->subset().width(), this->subset().height());
+ // TODO: Supply correct color space after we're storing it here
auto img = sk_sp<SkImage>(new SkImage_Gpu(fTexture->width(), fTexture->height(),
this->uniqueID(), fAlphaType, fTexture.get(),
- SkBudgeted::kNo));
+ nullptr, SkBudgeted::kNo));
canvas->drawImageRect(img, this->subset(),
dst, paint, SkCanvas::kStrict_SrcRectConstraint);
@@ -528,9 +529,10 @@
fTexture->width() == subset.width() &&
fTexture->height() == subset.height()) {
// The existing GrTexture is already tight so reuse it in the SkImage
+ // TODO: Supply correct color space after we're storing it here
return sk_make_sp<SkImage_Gpu>(fTexture->width(), fTexture->height(),
kNeedNewImageUniqueID,
- fAlphaType, fTexture.get(), SkBudgeted::kYes);
+ fAlphaType, fTexture.get(), nullptr, SkBudgeted::kYes);
}
GrContext* ctx = fTexture->getContext();
@@ -543,8 +545,9 @@
return nullptr;
}
ctx->copySurface(subTx.get(), fTexture.get(), subset, SkIPoint::Make(0, 0));
+ // TODO: Supply correct color space after we're storing it here
return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
- fAlphaType, subTx.get(), SkBudgeted::kYes);
+ fAlphaType, subTx.get(), nullptr, SkBudgeted::kYes);
}
sk_sp<SkSurface> onMakeTightSurface(const SkImageInfo& info) const override {
diff --git a/src/gpu/GrTextureParamsAdjuster.h b/src/gpu/GrTextureParamsAdjuster.h
index 7513eb4..eee761f 100644
--- a/src/gpu/GrTextureParamsAdjuster.h
+++ b/src/gpu/GrTextureParamsAdjuster.h
@@ -72,6 +72,7 @@
int width() const { return fWidth; }
int height() const { return fHeight; }
bool isAlphaOnly() const { return fIsAlphaOnly; }
+ virtual SkColorSpace* getColorSpace() = 0;
protected:
GrTextureProducer(int width, int height, bool isAlphaOnly)
@@ -108,8 +109,6 @@
*/
virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
- virtual SkColorSpace* getColorSpace() = 0;
-
private:
const int fWidth;
const int fHeight;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 2694718..3b3783a 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -742,7 +742,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////
-SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) {
+SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque,
+ sk_sp<SkColorSpace> colorSpace) {
#ifdef SK_DEBUG
const GrSurfaceDesc& desc = tex->desc();
SkASSERT(w <= desc.fWidth);
@@ -754,7 +755,7 @@
if (!GrPixelConfigToColorAndColorSpace(config, &ct, nullptr)) {
ct = kUnknown_SkColorType;
}
- return SkImageInfo::Make(w, h, ct, at);
+ return SkImageInfo::Make(w, h, ct, at, std::move(colorSpace));
}
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index e6d66a1..8e46407 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -304,7 +304,8 @@
}
const SkImageInfo info = bm.info();
return sk_make_sp<SkImage_Gpu>(info.width(), info.height(), bm.getGenerationID(),
- info.alphaType(), tex, SkBudgeted::kNo);
+ info.alphaType(), tex, sk_ref_sp(info.colorSpace()),
+ SkBudgeted::kNo);
}
#endif
@@ -396,7 +397,7 @@
}
sk_sp<SkImage> SkImage::MakeFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
- TextureReleaseProc, ReleaseContext) {
+ sk_sp<SkColorSpace>, TextureReleaseProc, ReleaseContext) {
return nullptr;
}
@@ -412,14 +413,15 @@
}
sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
- SkAlphaType) {
+ SkAlphaType, sk_sp<SkColorSpace>) {
return nullptr;
}
sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace space,
const GrBackendObject yuvTextureHandles[3],
const SkISize yuvSizes[3],
- GrSurfaceOrigin origin) {
+ GrSurfaceOrigin origin,
+ sk_sp<SkColorSpace> imageColorSpace) {
return nullptr;
}
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index de67d6c..b3604b9 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -20,11 +20,12 @@
#include "SkPixelRef.h"
SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrTexture* tex,
- SkBudgeted budgeted)
+ sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted)
: INHERITED(w, h, uniqueID)
, fTexture(SkRef(tex))
, fAlphaType(at)
, fBudgeted(budgeted)
+ , fColorSpace(std::move(colorSpace))
, fAddedRasterVersionToCache(false)
{
SkASSERT(tex->width() == w);
@@ -43,8 +44,9 @@
}
}
-static SkImageInfo make_info(int w, int h, bool isOpaque) {
- return SkImageInfo::MakeN32(w, h, isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
+static SkImageInfo make_info(int w, int h, bool isOpaque, sk_sp<SkColorSpace> colorSpace) {
+ return SkImageInfo::MakeN32(w, h, isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType,
+ std::move(colorSpace));
}
bool SkImage_Gpu::getROPixels(SkBitmap* dst, CachingHint chint) const {
@@ -55,7 +57,8 @@
return true;
}
- if (!dst->tryAllocPixels(make_info(this->width(), this->height(), this->isOpaque()))) {
+ if (!dst->tryAllocPixels(make_info(this->width(), this->height(), this->isOpaque(),
+ this->fColorSpace))) {
return false;
}
if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_GrPixelConfig,
@@ -72,7 +75,7 @@
}
bool SkImage_Gpu::asBitmapForImageFilters(SkBitmap* bitmap) const {
- bitmap->setInfo(make_info(this->width(), this->height(), this->isOpaque()));
+ bitmap->setInfo(make_info(this->width(), this->height(), this->isOpaque(), fColorSpace));
bitmap->setPixelRef(new SkGrPixelRef(bitmap->info(), fTexture))->unref();
bitmap->pixelRef()->setImmutableWithID(this->uniqueID());
return true;
@@ -147,13 +150,14 @@
}
ctx->copySurface(subTx.get(), fTexture, subset, SkIPoint::Make(0, 0));
return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
- fAlphaType, subTx.get(), fBudgeted);
+ fAlphaType, subTx.get(), fColorSpace, fBudgeted);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx, const GrBackendTextureDesc& desc,
- SkAlphaType at, GrWrapOwnership ownership,
+ SkAlphaType at, sk_sp<SkColorSpace> colorSpace,
+ GrWrapOwnership ownership,
SkImage::TextureReleaseProc releaseProc,
SkImage::ReleaseContext releaseCtx) {
if (desc.fWidth <= 0 || desc.fHeight <= 0) {
@@ -169,25 +173,28 @@
const SkBudgeted budgeted = SkBudgeted::kNo;
return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
- at, tex, budgeted);
+ at, tex, colorSpace, budgeted);
}
sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
- SkAlphaType at, TextureReleaseProc releaseP,
- ReleaseContext releaseC) {
- return new_wrapped_texture_common(ctx, desc, at, kBorrow_GrWrapOwnership, releaseP, releaseC);
+ SkAlphaType at, sk_sp<SkColorSpace> cs,
+ TextureReleaseProc releaseP, ReleaseContext releaseC) {
+ return new_wrapped_texture_common(ctx, desc, at, std::move(cs), kBorrow_GrWrapOwnership,
+ releaseP, releaseC);
}
sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
- SkAlphaType at) {
- return new_wrapped_texture_common(ctx, desc, at, kAdopt_GrWrapOwnership, nullptr, nullptr);
+ SkAlphaType at, sk_sp<SkColorSpace> cs) {
+ return new_wrapped_texture_common(ctx, desc, at, std::move(cs), kAdopt_GrWrapOwnership,
+ nullptr, nullptr);
}
static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpace colorSpace,
bool nv12,
const GrBackendObject yuvTextureHandles[],
const SkISize yuvSizes[],
- GrSurfaceOrigin origin) {
+ GrSurfaceOrigin origin,
+ sk_sp<SkColorSpace> imageColorSpace) {
const SkBudgeted budgeted = SkBudgeted::kYes;
if (yuvSizes[0].fWidth <= 0 || yuvSizes[0].fHeight <= 0 || yuvSizes[1].fWidth <= 0 ||
@@ -262,21 +269,25 @@
drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), rect);
ctx->flushSurfaceWrites(drawContext->accessRenderTarget());
return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID,
- kOpaque_SkAlphaType,
- drawContext->asTexture().get(), budgeted);
+ kOpaque_SkAlphaType, drawContext->asTexture().get(),
+ std::move(imageColorSpace), budgeted);
}
sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace colorSpace,
const GrBackendObject yuvTextureHandles[3],
- const SkISize yuvSizes[3], GrSurfaceOrigin origin) {
- return make_from_yuv_textures_copy(ctx, colorSpace, false, yuvTextureHandles, yuvSizes, origin);
+ const SkISize yuvSizes[3], GrSurfaceOrigin origin,
+ sk_sp<SkColorSpace> imageColorSpace) {
+ return make_from_yuv_textures_copy(ctx, colorSpace, false, yuvTextureHandles, yuvSizes, origin,
+ std::move(imageColorSpace));
}
sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace colorSpace,
const GrBackendObject yuvTextureHandles[2],
const SkISize yuvSizes[2],
- GrSurfaceOrigin origin) {
- return make_from_yuv_textures_copy(ctx, colorSpace, true, yuvTextureHandles, yuvSizes, origin);
+ GrSurfaceOrigin origin,
+ sk_sp<SkColorSpace> imageColorSpace) {
+ return make_from_yuv_textures_copy(ctx, colorSpace, true, yuvTextureHandles, yuvSizes, origin,
+ std::move(imageColorSpace));
}
static sk_sp<SkImage> create_image_from_maker(GrTextureMaker* maker, SkAlphaType at, uint32_t id) {
@@ -286,7 +297,7 @@
return nullptr;
}
return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), id, at, texture,
- SkBudgeted::kNo);
+ sk_ref_sp(maker->getColorSpace()), SkBudgeted::kNo);
}
sk_sp<SkImage> SkImage::makeTextureImage(GrContext *context) const {
@@ -346,7 +357,8 @@
return nullptr;
}
return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNewImageUniqueID,
- pixmap.alphaType(), texture, budgeted);
+ pixmap.alphaType(), texture,
+ sk_ref_sp(pixmap.info().colorSpace()), budgeted);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -544,5 +556,6 @@
return nullptr;
}
return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNewImageUniqueID,
- info.alphaType(), texture, budgeted);
+ info.alphaType(), texture, sk_ref_sp(info.colorSpace()),
+ budgeted);
}
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 3cef934..6206416 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -23,11 +23,13 @@
* An "image" can be a subset/window into a larger texture, so we explicit take the
* width and height.
*/
- SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType, GrTexture*, SkBudgeted);
+ SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType, GrTexture*, sk_sp<SkColorSpace>,
+ SkBudgeted);
~SkImage_Gpu() override;
SkImageInfo onImageInfo() const override {
- return GrMakeInfoFromTexture(fTexture, fTexture->width(), fTexture->height(), isOpaque());
+ return GrMakeInfoFromTexture(fTexture, fTexture->width(), fTexture->height(), isOpaque(),
+ fColorSpace);
}
void applyBudgetDecision() const {
@@ -58,6 +60,7 @@
SkAutoTUnref<GrTexture> fTexture;
const SkAlphaType fAlphaType;
const SkBudgeted fBudgeted;
+ sk_sp<SkColorSpace> fColorSpace;
mutable SkAtomic<bool> fAddedRasterVersionToCache;
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 5d1555f..fa37814 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -100,7 +100,8 @@
sk_sp<SkImage> image;
if (tex) {
image = sk_make_sp<SkImage_Gpu>(info.width(), info.height(), kNeedNewImageUniqueID,
- info.alphaType(), tex, budgeted);
+ info.alphaType(), tex, sk_ref_sp(info.colorSpace()),
+ budgeted);
}
return image;
}