update mode color filter color management
Change-Id: I2f371e279f45086ae8885c7206fefff3fbc8c941 Reviewed-on: https://skia-review.googlesource.com/140985 Auto-Submit: Mike Klein <mtklein@chromium.org> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
parent
d9c2e522dd
commit
b774bbba2f
@ -67,7 +67,7 @@ void SkModeColorFilter::onAppendStages(SkRasterPipeline* p,
|
|||||||
SkArenaAlloc* scratch,
|
SkArenaAlloc* scratch,
|
||||||
bool shaderIsOpaque) const {
|
bool shaderIsOpaque) const {
|
||||||
p->append(SkRasterPipeline::move_src_dst);
|
p->append(SkRasterPipeline::move_src_dst);
|
||||||
p->append_constant_color(scratch, SkPM4f_from_SkColor(fColor, dst));
|
p->append_constant_color(scratch, premul_in_dst_colorspace(fColor, dst));
|
||||||
SkBlendMode_AppendStages(fMode, p);
|
SkBlendMode_AppendStages(fMode, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,29 +10,61 @@
|
|||||||
|
|
||||||
#include "SkColorData.h"
|
#include "SkColorData.h"
|
||||||
#include "SkColorSpace.h"
|
#include "SkColorSpace.h"
|
||||||
|
#include "SkColorSpaceXformSteps.h"
|
||||||
#include "SkArenaAlloc.h"
|
#include "SkArenaAlloc.h"
|
||||||
#include "SkPM4f.h"
|
#include "SkPM4f.h"
|
||||||
#include "SkRasterPipeline.h"
|
#include "SkRasterPipeline.h"
|
||||||
#include "SkSRGB.h"
|
#include "SkSRGB.h"
|
||||||
#include "../jumper/SkJumper.h"
|
#include "../jumper/SkJumper.h"
|
||||||
|
|
||||||
|
// This file is mostly helper routines for doing color space management.
|
||||||
|
// It probably wants a new name, and they likely don't need to be inline.
|
||||||
|
//
|
||||||
|
// There are two generations of routines in here, the old ones that assumed linear blending,
|
||||||
|
// and the new ones assuming as-encoded blending. We're trying to move to the new as-encoded
|
||||||
|
// ones and will hopefully eventually remove all the linear routines.
|
||||||
|
//
|
||||||
|
// We'll start with the new as-encoded routines first,
|
||||||
|
// and shove all the old broken routines towards the bottom.
|
||||||
|
|
||||||
static inline Sk4f Sk4f_fromL32(uint32_t px) {
|
static inline Sk4f Sk4f_fromL32(uint32_t px) {
|
||||||
return SkNx_cast<float>(Sk4b::Load(&px)) * (1/255.0f);
|
return SkNx_cast<float>(Sk4b::Load(&px)) * (1/255.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Sk4f Sk4f_fromS32(uint32_t px) {
|
|
||||||
return { sk_linear_from_srgb[(px >> 0) & 0xff],
|
|
||||||
sk_linear_from_srgb[(px >> 8) & 0xff],
|
|
||||||
sk_linear_from_srgb[(px >> 16) & 0xff],
|
|
||||||
(1/255.0f) * (px >> 24) };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t Sk4f_toL32(const Sk4f& px) {
|
static inline uint32_t Sk4f_toL32(const Sk4f& px) {
|
||||||
uint32_t l32;
|
uint32_t l32;
|
||||||
SkNx_cast<uint8_t>(Sk4f_round(px * 255.0f)).store(&l32);
|
SkNx_cast<uint8_t>(Sk4f_round(px * 255.0f)).store(&l32);
|
||||||
return l32;
|
return l32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline SkPM4f premul_in_dst_colorspace(SkColor color, SkColorSpace* dstCS) {
|
||||||
|
float rgba[4];
|
||||||
|
swizzle_rb(Sk4f_fromL32(color)).store(rgba);
|
||||||
|
|
||||||
|
// SkColors are always sRGB.
|
||||||
|
auto srcCS = SkColorSpace::MakeSRGB().get();
|
||||||
|
|
||||||
|
// If dstCS is null, no color space transformation is needed (and apply() will just premul).
|
||||||
|
if (!dstCS) { dstCS = srcCS; }
|
||||||
|
|
||||||
|
// TODO: Can we use a precomputed sRGB -> dstCS SkColorSpaceXformSteps for each device?
|
||||||
|
SkColorSpaceXformSteps(srcCS, kUnpremul_SkAlphaType, dstCS)
|
||||||
|
.apply(rgba);
|
||||||
|
|
||||||
|
return {{rgba[0], rgba[1], rgba[2], rgba[3]}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
// Functions below this line are probably totally broken as far as color space management goes.
|
||||||
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
static inline Sk4f Sk4f_fromS32(uint32_t px) {
|
||||||
|
return { sk_linear_from_srgb[(px >> 0) & 0xff],
|
||||||
|
sk_linear_from_srgb[(px >> 8) & 0xff],
|
||||||
|
sk_linear_from_srgb[(px >> 16) & 0xff],
|
||||||
|
(1/255.0f) * (px >> 24) };
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t Sk4f_toS32(const Sk4f& px) {
|
static inline uint32_t Sk4f_toS32(const Sk4f& px) {
|
||||||
Sk4i rgb = sk_linear_to_srgb(px),
|
Sk4i rgb = sk_linear_to_srgb(px),
|
||||||
srgb = { rgb[0], rgb[1], rgb[2], (int)(255.0f * px[3] + 0.5f) };
|
srgb = { rgb[0], rgb[1], rgb[2], (int)(255.0f * px[3] + 0.5f) };
|
||||||
@ -106,4 +138,5 @@ static inline SkPM4f SkPM4f_from_SkColor(SkColor color, SkColorSpace* dst) {
|
|||||||
return SkColor4f_from_SkColor(color, dst).premul();
|
return SkColor4f_from_SkColor(color, dst).premul();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,22 +86,6 @@ private:
|
|||||||
typedef SkBlitter INHERITED;
|
typedef SkBlitter INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SkPM4f premul_in_dst_colorspace(SkColor color, SkColorSpace* dstCS) {
|
|
||||||
float rgba[4];
|
|
||||||
swizzle_rb(SkNx_cast<float>(Sk4b::Load(&color)) * (1/255.0f)).store(rgba);
|
|
||||||
|
|
||||||
// SkColors are always sRGB.
|
|
||||||
auto srcCS = SkColorSpace::MakeSRGB().get();
|
|
||||||
|
|
||||||
// If dstCS is null, no color space transformation is needed (and apply() will just premul).
|
|
||||||
if (!dstCS) { dstCS = srcCS; }
|
|
||||||
|
|
||||||
SkColorSpaceXformSteps(srcCS, kUnpremul_SkAlphaType, dstCS)
|
|
||||||
.apply(rgba);
|
|
||||||
|
|
||||||
return {{rgba[0], rgba[1], rgba[2], rgba[3]}};
|
|
||||||
}
|
|
||||||
|
|
||||||
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
|
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
|
||||||
const SkPaint& paint,
|
const SkPaint& paint,
|
||||||
const SkMatrix& ctm,
|
const SkMatrix& ctm,
|
||||||
|
Loading…
Reference in New Issue
Block a user