Use SkTransferFunctionBehavior in SkImageGenerator
This fixes SkColorSpaceXformCanvas gms that expect non-linear premuls from the codec. BUG=skia: Change-Id: I5dc236d0cd760c23605a26e9c33ddb18955f9231 Reviewed-on: https://skia-review.googlesource.com/10164 Reviewed-by: Mike Klein <mtklein@chromium.org> Commit-Queue: Matt Sarett <msarett@google.com>
This commit is contained in:
parent
8576014d8a
commit
d531ca038f
@ -177,6 +177,23 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Options {
|
||||
Options()
|
||||
: fColorTable(nullptr)
|
||||
, fColorTableCount(nullptr)
|
||||
, fBehavior(SkTransferFunctionBehavior::kRespect)
|
||||
{}
|
||||
|
||||
SkPMColor* fColorTable;
|
||||
int* fColorTableCount;
|
||||
SkTransferFunctionBehavior fBehavior;
|
||||
};
|
||||
bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* opts);
|
||||
virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
const Options& opts) {
|
||||
return this->onGetPixels(info, pixels, rowBytes, opts.fColorTable, opts.fColorTableCount);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
|
||||
const SkIPoint&);
|
||||
@ -186,6 +203,8 @@ private:
|
||||
const SkImageInfo fInfo;
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
friend class SkImageCacherator;
|
||||
|
||||
// This is our default impl, which may be different on different platforms.
|
||||
// It is called from NewFromEncoded() after it has checked for any runtime factory.
|
||||
// The SkData will never be NULL, as that will have been checked by NewFromEncoded.
|
||||
|
@ -37,8 +37,19 @@ SkData* SkCodecImageGenerator::onRefEncodedData(GrContext* ctx) {
|
||||
|
||||
bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
SkPMColor ctable[], int* ctableCount) {
|
||||
SkCodec::Result result = fCodec->getPixels(info, pixels, rowBytes, nullptr, ctable,
|
||||
ctableCount);
|
||||
Options opts;
|
||||
opts.fColorTable = ctable;
|
||||
opts.fColorTableCount = ctableCount;
|
||||
opts.fBehavior = SkTransferFunctionBehavior::kRespect;
|
||||
return this->onGetPixels(info, pixels, rowBytes, opts);
|
||||
}
|
||||
|
||||
bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
const Options& opts) {
|
||||
SkCodec::Options codecOpts;
|
||||
codecOpts.fPremulBehavior = opts.fBehavior;
|
||||
SkCodec::Result result = fCodec->getPixels(info, pixels, rowBytes, &codecOpts, opts.fColorTable,
|
||||
opts.fColorTableCount);
|
||||
switch (result) {
|
||||
case SkCodec::kSuccess:
|
||||
case SkCodec::kIncompleteInput:
|
||||
|
@ -24,7 +24,9 @@ protected:
|
||||
SkData* onRefEncodedData(GrContext* ctx) override;
|
||||
|
||||
bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[],
|
||||
int* ctableCount) override;
|
||||
int* ctableCount) override;
|
||||
bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options& opts)
|
||||
override;
|
||||
|
||||
bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const override;
|
||||
|
||||
|
@ -166,14 +166,18 @@ bool SkImageCacherator::generateBitmap(SkBitmap* bitmap, const SkImageInfo& deco
|
||||
}
|
||||
|
||||
bool SkImageCacherator::directGeneratePixels(const SkImageInfo& info, void* pixels, size_t rb,
|
||||
int srcX, int srcY) {
|
||||
int srcX, int srcY,
|
||||
SkTransferFunctionBehavior behavior) {
|
||||
ScopedGenerator generator(fSharedGenerator);
|
||||
const SkImageInfo& genInfo = generator->getInfo();
|
||||
// Currently generators do not natively handle subsets, so check that first.
|
||||
if (srcX || srcY || genInfo.width() != info.width() || genInfo.height() != info.height()) {
|
||||
return false;
|
||||
}
|
||||
return generator->getPixels(info, pixels, rb);
|
||||
|
||||
SkImageGenerator::Options opts;
|
||||
opts.fBehavior = behavior;
|
||||
return generator->getPixels(info, pixels, rb, &opts);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
bool lockAsBitmapOnlyIfAlreadyCached(SkBitmap*, CachedFormat);
|
||||
// Call the underlying generator directly
|
||||
bool directGeneratePixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
|
||||
int srcX, int srcY);
|
||||
int srcX, int srcY, SkTransferFunctionBehavior behavior);
|
||||
|
||||
private:
|
||||
// Ref-counted tuple(SkImageGenerator, SkMutex) which allows sharing of one generator
|
||||
|
@ -45,6 +45,15 @@ bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t r
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
const Options* opts) {
|
||||
Options defaultOpts;
|
||||
if (!opts) {
|
||||
opts = &defaultOpts;
|
||||
}
|
||||
return this->onGetPixels(info, pixels, rowBytes, *opts);
|
||||
}
|
||||
|
||||
bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
||||
SkASSERT(kIndex_8_SkColorType != info.colorType());
|
||||
if (kIndex_8_SkColorType == info.colorType()) {
|
||||
|
@ -60,7 +60,8 @@ bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels
|
||||
// Try passing the caller's buffer directly down to the generator. If this fails we
|
||||
// may still succeed in the general case, as the generator may prefer some other
|
||||
// config, which we could then convert via SkBitmap::readPixels.
|
||||
if (fCache.directGeneratePixels(dstInfo, dstPixels, dstRB, srcX, srcY)) {
|
||||
if (fCache.directGeneratePixels(dstInfo, dstPixels, dstRB, srcX, srcY,
|
||||
SkTransferFunctionBehavior::kRespect)) {
|
||||
return true;
|
||||
}
|
||||
// else fall through
|
||||
@ -112,7 +113,10 @@ sk_sp<SkImage> SkImage_Generator::onMakeColorSpace(sk_sp<SkColorSpace> target) c
|
||||
}
|
||||
dst.allocPixels(dstInfo);
|
||||
|
||||
if (!fCache.directGeneratePixels(dstInfo, dst.getPixels(), dst.rowBytes(), 0, 0)) {
|
||||
// Use kIgnore for transfer function behavior. This is used by the SkColorSpaceXformCanvas,
|
||||
// which wants to pre-xform the inputs but ignore the transfer function on blends.
|
||||
if (!fCache.directGeneratePixels(dstInfo, dst.getPixels(), dst.rowBytes(), 0, 0,
|
||||
SkTransferFunctionBehavior::kIgnore)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user