SkColorInfo: It's SkImageInfo minus the dimensions.

Change-Id: Idea9530028428c1a9d42e08a655457938b284b84
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/245261
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2019-10-01 09:59:02 -04:00 committed by Skia Commit-Bot
parent a7914a8726
commit 65f533af95
9 changed files with 170 additions and 76 deletions

View File

@ -10,6 +10,7 @@ This file includes a list of high level updates for each milestone release.
* Remove isRectContour and ksNestedFillRects from public
* Start to move nested SkPath types (e.g. Direction, Verb) up to root level in SkPathTypes.h
* Remove Vulkan/Metal float32 RGBA texture support
* Add SkColorInfo. It's dimensionless SkImageInfo.
Milestone 79

View File

@ -186,6 +186,102 @@ enum SkYUVColorSpace {
kLastEnum_SkYUVColorSpace = kIdentity_SkYUVColorSpace, //!< last valid value
};
/** \struct SkColorInfo
Describes pixel and encoding. SkImageInfo can be created from SkColorInfo by
providing dimensions.
It encodes how pixel bits describe alpha, transparency; color components red, blue,
and green; and SkColorSpace, the range and linearity of colors.
*/
class SK_API SkColorInfo {
public:
/** Creates an SkColorInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
and no SkColorSpace.
@return empty SkImageInfo
*/
SkColorInfo() = default;
/** Creates SkColorInfo from SkColorType ct, SkAlphaType at, and optionally SkColorSpace cs.
If SkColorSpace cs is nullptr and SkColorInfo is part of drawing source: SkColorSpace
defaults to sRGB, mapping into SkSurface SkColorSpace.
Parameters are not validated to see if their values are legal, or that the
combination is supported.
@return created SkColorInfo
*/
SkColorInfo(SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
: fColorSpace(std::move(cs)), fColorType(ct), fAlphaType(at) {}
SkColorInfo(const SkColorInfo&) = default;
SkColorInfo(SkColorInfo&&) = default;
SkColorInfo& operator=(const SkColorInfo&) = default;
SkColorInfo& operator=(SkColorInfo&&) = default;
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
SkColorType colorType() const { return fColorType; }
SkAlphaType alphaType() const { return fAlphaType; }
bool isOpaque() const { return SkAlphaTypeIsOpaque(fAlphaType); }
bool gammaCloseToSRGB() const { return fColorSpace && fColorSpace->gammaCloseToSRGB(); }
/** Does other represent the same color type, alpha type, and color space? */
bool operator==(const SkColorInfo& other) const {
return fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
}
/** Does other represent a different color type, alpha type, or color space? */
bool operator!=(const SkColorInfo& other) const { return !(*this == other); }
/** Creates SkColorInfo with same SkColorType, SkColorSpace, with SkAlphaType set
to newAlphaType.
Created SkColorInfo contains newAlphaType even if it is incompatible with
SkColorType, in which case SkAlphaType in SkColorInfo is ignored.
*/
SkColorInfo makeAlphaType(SkAlphaType newAlphaType) const {
return SkColorInfo(this->colorType(), newAlphaType, this->refColorSpace());
}
/** Creates new SkColorInfo with same SkAlphaType, SkColorSpace, with SkColorType
set to newColorType.
*/
SkColorInfo makeColorType(SkColorType newColorType) const {
return SkColorInfo(newColorType, this->alphaType(), this->refColorSpace());
}
/** Creates SkColorInfo with same SkAlphaType, SkColorType, with SkColorSpace
set to cs. cs may be nullptr.
*/
SkColorInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
return SkColorInfo(this->colorType(), this->alphaType(), std::move(cs));
}
/** Returns number of bytes per pixel required by SkColorType.
Returns zero if colorType() is kUnknown_SkColorType.
@return bytes in pixel
*/
int bytesPerPixel() const;
/** Returns bit shift converting row bytes to row pixels.
Returns zero for kUnknown_SkColorType.
@return one of: 0, 1, 2, 3, 4; left shift to convert pixels to bytes
*/
int shiftPerPixel() const;
private:
sk_sp<SkColorSpace> fColorSpace;
SkColorType fColorType = kUnknown_SkColorType;
SkAlphaType fAlphaType = kUnknown_SkAlphaType;
};
/** \struct SkImageInfo
Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
@ -204,12 +300,7 @@ public:
@return empty SkImageInfo
*/
SkImageInfo()
: fColorSpace(nullptr)
, fDimensions{0, 0}
, fColorType(kUnknown_SkColorType)
, fAlphaType(kUnknown_SkAlphaType)
{}
SkImageInfo() = default;
/** Creates SkImageInfo from integral dimensions width and height, SkColorType ct,
SkAlphaType at, and optionally SkColorSpace cs.
@ -235,11 +326,28 @@ public:
*/
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
sk_sp<SkColorSpace> cs = nullptr) {
return SkImageInfo({width, height}, ct, at, std::move(cs));
return SkImageInfo({width, height}, {ct, at, std::move(cs)});
}
static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at,
sk_sp<SkColorSpace> cs = nullptr) {
return SkImageInfo(dimensions, ct, at, std::move(cs));
return SkImageInfo(dimensions, {ct, at, std::move(cs)});
}
/** Creates SkImageInfo from integral dimensions and SkColorInfo colorInfo,
Parameters are not validated to see if their values are legal, or that the
combination is supported.
@param dimensions pixel column and row count; must be zeros or greater
@param SkColorInfo the pixel encoding consisting of SkColorType, SkAlphaType, and
SkColorSpace (which may be nullptr)
@return created SkImageInfo
*/
static SkImageInfo Make(SkISize dimensions, const SkColorInfo& colorInfo) {
return SkImageInfo(dimensions, colorInfo);
}
static SkImageInfo Make(SkISize dimensions, SkColorInfo&& colorInfo) {
return SkImageInfo(dimensions, std::move(colorInfo));
}
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
@ -371,7 +479,7 @@ public:
@return SkColorType
*/
SkColorType colorType() const { return fColorType; }
SkColorType colorType() const { return fColorInfo.colorType(); }
/** Returns SkAlphaType, one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
@ -379,14 +487,14 @@ public:
@return SkAlphaType
*/
SkAlphaType alphaType() const { return fAlphaType; }
SkAlphaType alphaType() const { return fColorInfo.alphaType(); }
/** Returns SkColorSpace, the range of colors. The reference count of
SkColorSpace is unchanged. The returned SkColorSpace is immutable.
@return SkColorSpace, or nullptr
*/
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
SkColorSpace* colorSpace() const { return fColorInfo.colorSpace(); }
/** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer
tracks the number of objects sharing this SkColorSpace reference so the memory
@ -396,7 +504,7 @@ public:
@return SkColorSpace wrapped in a smart pointer
*/
sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
sk_sp<SkColorSpace> refColorSpace() const { return fColorInfo.refColorSpace(); }
/** Returns if SkImageInfo describes an empty area of pixels by checking if either
width or height is zero or smaller.
@ -405,6 +513,11 @@ public:
*/
bool isEmpty() const { return fDimensions.isEmpty(); }
/** Returns the dimensionless SkColorInfo that represents the same color type,
alpha type, and color space as this SkImageInfo.
*/
const SkColorInfo& colorInfo() const { return fColorInfo; }
/** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
alpha value is implicitly or explicitly 1.0. If true, and all pixels are
not opaque, Skia may draw incorrectly.
@ -414,9 +527,7 @@ public:
@return true if SkAlphaType is kOpaque_SkAlphaType
*/
bool isOpaque() const {
return SkAlphaTypeIsOpaque(fAlphaType);
}
bool isOpaque() const { return fColorInfo.isOpaque(); }
/** Returns SkISize { width(), height() }.
@ -436,9 +547,7 @@ public:
@return true if SkColorSpace gamma is approximately the same as sRGB
*/
bool gammaCloseToSRGB() const {
return fColorSpace && fColorSpace->gammaCloseToSRGB();
}
bool gammaCloseToSRGB() const { return fColorInfo.gammaCloseToSRGB(); }
/** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
with dimensions set to width and height.
@ -448,7 +557,7 @@ public:
@return created SkImageInfo
*/
SkImageInfo makeWH(int newWidth, int newHeight) const {
return Make(newWidth, newHeight, fColorType, fAlphaType, fColorSpace);
return Make({newWidth, newHeight}, fColorInfo);
}
/** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height,
@ -463,7 +572,7 @@ public:
@return created SkImageInfo
*/
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
return Make(this->width(), this->height(), fColorType, newAlphaType, fColorSpace);
return Make(fDimensions, fColorInfo.makeAlphaType(newAlphaType));
}
/** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height,
@ -477,7 +586,7 @@ public:
@return created SkImageInfo
*/
SkImageInfo makeColorType(SkColorType newColorType) const {
return Make(this->width(), this->height(), newColorType, fAlphaType, fColorSpace);
return Make(fDimensions, fColorInfo.makeColorType(newColorType));
}
/** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height,
@ -487,7 +596,7 @@ public:
@return created SkImageInfo
*/
SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
return Make(this->width(), this->height(), fColorType, fAlphaType, std::move(cs));
return Make(fDimensions, fColorInfo.makeColorSpace(std::move(cs)));
}
/** Returns number of bytes per pixel required by SkColorType.
@ -495,14 +604,14 @@ public:
@return bytes in pixel
*/
int bytesPerPixel() const;
int bytesPerPixel() const { return fColorInfo.bytesPerPixel(); }
/** Returns bit shift converting row bytes to row pixels.
Returns zero for kUnknown_SkColorType.
@return one of: 0, 1, 2, 3; left shift to convert pixels to bytes
*/
int shiftPerPixel() const;
int shiftPerPixel() const { return fColorInfo.shiftPerPixel(); }
/** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
@ -545,9 +654,7 @@ public:
@return true if SkImageInfo equals other
*/
bool operator==(const SkImageInfo& other) const {
return fDimensions == other.fDimensions &&
fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
return fDimensions == other.fDimensions && fColorInfo == other.fColorInfo;
}
/** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
@ -605,12 +712,7 @@ public:
/** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
a width and height of zero, and no SkColorSpace.
*/
void reset() {
fColorSpace = nullptr;
fDimensions = {0, 0};
fColorType = kUnknown_SkColorType;
fAlphaType = kUnknown_SkAlphaType;
}
void reset() { *this = {}; }
/** Asserts if internal values are illegal or inconsistent. Only available if
SK_DEBUG is defined at compile time.
@ -618,17 +720,14 @@ public:
SkDEBUGCODE(void validate() const;)
private:
sk_sp<SkColorSpace> fColorSpace;
SkISize fDimensions;
SkColorType fColorType;
SkAlphaType fAlphaType;
SkColorInfo fColorInfo;
SkISize fDimensions = {0, 0};
SkImageInfo(SkISize dimensions, SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
: fColorSpace(std::move(cs))
, fDimensions(dimensions)
, fColorType(ct)
, fAlphaType(at)
{}
SkImageInfo(SkISize dimensions, const SkColorInfo& colorInfo)
: fColorInfo(colorInfo), fDimensions(dimensions) {}
SkImageInfo(SkISize dimensions, SkColorInfo&& colorInfo)
: fColorInfo(std::move(colorInfo)), fDimensions(dimensions) {}
};
#endif

View File

@ -628,14 +628,3 @@ bool SkBitmap::peekPixels(SkPixmap* pmap) const {
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
void SkImageInfo::validate() const {
SkASSERT(fDimensions.width() >= 0);
SkASSERT(fDimensions.height() >= 0);
SkASSERT(SkColorTypeIsValid(fColorType));
SkASSERT(SkAlphaTypeIsValid(fAlphaType));
}
#endif

View File

@ -41,9 +41,11 @@ bool SkColorTypeIsAlwaysOpaque(SkColorType ct) {
///////////////////////////////////////////////////////////////////////////////////////////////////
int SkImageInfo::bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); }
int SkColorInfo::bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); }
int SkImageInfo::shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); }
int SkColorInfo::shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); }
///////////////////////////////////////////////////////////////////////////////////////////////////
size_t SkImageInfo::computeOffset(int x, int y, size_t rowBytes) const {
SkASSERT((unsigned)x < (unsigned)this->width());
@ -62,9 +64,18 @@ size_t SkImageInfo::computeByteSize(size_t rowBytes) const {
}
SkImageInfo SkImageInfo::MakeS32(int width, int height, SkAlphaType at) {
return SkImageInfo({width, height}, kN32_SkColorType, at, SkColorSpace::MakeSRGB());
return SkImageInfo({width, height}, {kN32_SkColorType, at, SkColorSpace::MakeSRGB()});
}
#ifdef SK_DEBUG
void SkImageInfo::validate() const {
SkASSERT(fDimensions.width() >= 0);
SkASSERT(fDimensions.height() >= 0);
SkASSERT(SkColorTypeIsValid(this->colorType()));
SkASSERT(SkAlphaTypeIsValid(this->alphaType()));
}
#endif
bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
SkAlphaType* canonical) {
switch (colorType) {

View File

@ -17,14 +17,9 @@
#include "src/gpu/GrSurfaceContext.h"
#include "src/gpu/SkGr.h"
static GrColorInfo make_info(const SkBitmap& bm) {
return GrColorInfo(SkColorTypeToGrColorType(bm.colorType()), bm.alphaType(),
bm.refColorSpace());
}
GrBitmapTextureMaker::GrBitmapTextureMaker(GrRecordingContext* context, const SkBitmap& bitmap,
bool useDecal)
: INHERITED(context, bitmap.width(), bitmap.height(), make_info(bitmap), useDecal)
: INHERITED(context, bitmap.width(), bitmap.height(), bitmap.info().colorInfo(), useDecal)
, fBitmap(bitmap) {
if (!bitmap.isVolatile()) {
SkIPoint origin = bitmap.pixelRefOrigin();

View File

@ -13,6 +13,11 @@ GrColorInfo::GrColorInfo(
GrColorType colorType, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace)
: fColorSpace(std::move(colorSpace)), fColorType(colorType), fAlphaType(alphaType) {}
GrColorInfo::GrColorInfo(const SkColorInfo& ci)
: GrColorInfo(SkColorTypeToGrColorType(ci.colorType()),
ci.alphaType(),
ci.refColorSpace()) {}
GrColorSpaceXform* GrColorInfo::colorSpaceXformFromSRGB() const {
// TODO: Make this atomic if we start accessing this on multiple threads.
if (!fInitializedColorSpaceXformFromSRGB) {

View File

@ -20,6 +20,7 @@ class GrColorInfo {
public:
GrColorInfo() = default;
GrColorInfo(GrColorType, SkAlphaType, sk_sp<SkColorSpace>);
/* implicit */ GrColorInfo(const SkColorInfo&);
bool isLinearlyBlended() const { return fColorSpace && fColorSpace->gammaIsLinear(); }

View File

@ -16,11 +16,8 @@ class GrImageInfo {
public:
GrImageInfo() = default;
// not explicit
GrImageInfo(const SkImageInfo& info)
: fColorInfo(SkColorTypeToGrColorType(info.colorType()), info.alphaType(),
info.refColorSpace())
, fDimensions(info.dimensions()) {}
/* implicit */ GrImageInfo(const SkImageInfo& info)
: fColorInfo(info.colorInfo()), fDimensions(info.dimensions()) {}
GrImageInfo(GrColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs, int w, int h)
: fColorInfo(ct, at, std::move(cs)), fDimensions{w,h} {}

View File

@ -13,15 +13,10 @@
#include "src/image/SkImage_GpuYUVA.h"
#include "src/image/SkImage_Lazy.h"
static GrColorInfo make_info(const SkImage*& image) {
return GrColorInfo(SkColorTypeToGrColorType(image->colorType()),
image->alphaType(),
image->refColorSpace());
}
GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context, const SkImage* client,
SkImage::CachingHint chint, bool useDecal)
: INHERITED(context, client->width(), client->height(), make_info(client), useDecal)
: INHERITED(context, client->width(), client->height(), client->imageInfo().colorInfo(),
useDecal)
, fImage(static_cast<const SkImage_Lazy*>(client))
, fCachingHint(chint) {
SkASSERT(client->isLazyGenerated());
@ -48,7 +43,8 @@ void GrImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* pa
GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client,
bool useDecal)
: INHERITED(context, client->width(), client->height(), make_info(client), useDecal)
: INHERITED(context, client->width(), client->height(), client->imageInfo().colorInfo(),
useDecal)
, fImage(static_cast<const SkImage_GpuYUVA*>(client)) {
SkASSERT(as_IB(client)->isYUVA());
GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(),