diff options
author | Mike Klein <mtklein@chromium.org> | 2016-11-14 16:02:41 -0500 |
---|---|---|
committer | Mike Klein <mtklein@chromium.org> | 2016-11-14 22:05:47 +0000 |
commit | 662c2aed38c1917c05883095a8013f51931aafa4 (patch) | |
tree | 406b473cd8f3333aa2087e9bc2769145098fe047 /src/core | |
parent | 0fdde549825bcf6931aadbc292a91403ea15bb63 (diff) |
Fill in gamut-transformation TODOs for software pipeline.
This adds support for paint colors, color shaders, and mode color filters (everything that the software pipeline supports today).
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4781
Change-Id: I6e5da6d0dba03fbc82ecaa233ce8c727e7ce17b3
Reviewed-on: https://skia-review.googlesource.com/4781
Reviewed-by: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkColorShader.cpp | 9 | ||||
-rw-r--r-- | src/core/SkPM4fPriv.h | 51 |
2 files changed, 57 insertions, 3 deletions
diff --git a/src/core/SkColorShader.cpp b/src/core/SkColorShader.cpp index a761d605fa..69d9e46b27 100644 --- a/src/core/SkColorShader.cpp +++ b/src/core/SkColorShader.cpp @@ -320,7 +320,10 @@ bool SkColorShader::onAppendStages(SkRasterPipeline* p, auto color = scratch->make<SkPM4f>(SkPM4f_from_SkColor(fColor, dst)); p->append(SkRasterPipeline::move_src_dst); p->append(SkRasterPipeline::constant_color, color); - // TODO: sRGB -> dst gamut correction if needed + if (!append_gamut_transform(p, scratch, + SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).get(), dst)) { + return false; + } p->append(SkRasterPipeline::srcin); return true; } @@ -331,7 +334,9 @@ bool SkColor4Shader::onAppendStages(SkRasterPipeline* p, auto color = scratch->make<SkPM4f>(fColor4.premul()); p->append(SkRasterPipeline::move_src_dst); p->append(SkRasterPipeline::constant_color, color); - // TODO: fColorSpace -> dst gamut correction if needed + if (!append_gamut_transform(p, scratch, fColorSpace.get(), dst)) { + return false; + } p->append(SkRasterPipeline::srcin); return true; } diff --git a/src/core/SkPM4fPriv.h b/src/core/SkPM4fPriv.h index f70c5c5a53..304a49ffdd 100644 --- a/src/core/SkPM4fPriv.h +++ b/src/core/SkPM4fPriv.h @@ -10,7 +10,10 @@ #include "SkColorPriv.h" #include "SkColorSpace.h" +#include "SkColorSpace_Base.h" +#include "SkFixedAlloc.h" #include "SkPM4f.h" +#include "SkRasterPipeline.h" #include "SkSRGB.h" static inline Sk4f set_alpha(const Sk4f& px, float alpha) { @@ -72,12 +75,58 @@ static inline float exact_srgb_to_linear(float srgb) { return linear; } + +// N.B. scratch_matrix_3x4 must live at least as long as p. +static inline bool append_gamut_transform(SkRasterPipeline* p, float scratch_matrix_3x4[12], + SkColorSpace* src, SkColorSpace* dst) { + if (src == dst) { return true; } + if (!dst) { return true; } // Legacy modes intentionally ignore color gamut. + if (!src) { return true; } // A null src color space means linear gamma, dst gamut. + + auto toXYZ = as_CSB(src)-> toXYZD50(), + fromXYZ = as_CSB(dst)->fromXYZD50(); + if (!toXYZ || !fromXYZ) { return false; } // Unsupported color space type. + + if (as_CSB(src)->toXYZD50Hash() == as_CSB(dst)->toXYZD50Hash()) { return true; } + + SkMatrix44 m44(*fromXYZ, *toXYZ); + + // Convert from 4x4 to (column-major) 3x4. + auto ptr = scratch_matrix_3x4; + *ptr++ = m44.get(0,0); *ptr++ = m44.get(1,0); *ptr++ = m44.get(2,0); + *ptr++ = m44.get(0,1); *ptr++ = m44.get(1,1); *ptr++ = m44.get(2,1); + *ptr++ = m44.get(0,2); *ptr++ = m44.get(1,2); *ptr++ = m44.get(2,2); + *ptr++ = m44.get(0,3); *ptr++ = m44.get(1,3); *ptr++ = m44.get(2,3); + + p->append(SkRasterPipeline::matrix_3x4, scratch_matrix_3x4); + // TODO: detect whether we can skip the clamps? + p->append(SkRasterPipeline::clamp_0); + p->append(SkRasterPipeline::clamp_a); + return true; +} + +static inline bool append_gamut_transform(SkRasterPipeline* p, SkFallbackAlloc* scratch, + SkColorSpace* src, SkColorSpace* dst) { + struct matrix_3x4 { float arr[12]; }; + return append_gamut_transform(p, scratch->make<matrix_3x4>()->arr, src, dst); +} + static inline SkPM4f SkPM4f_from_SkColor(SkColor color, SkColorSpace* dst) { SkColor4f color4f; if (dst) { // sRGB gamma, sRGB gamut. color4f = SkColor4f::FromColor(color); - // TODO: gamut transform if needed + void* color4f_ptr = &color4f; + + float scratch_matrix_3x4[12]; + + SkRasterPipeline p; + p.append(SkRasterPipeline::constant_color, color4f_ptr); + append_gamut_transform(&p, scratch_matrix_3x4, + SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).get(), dst); + p.append(SkRasterPipeline::store_f32, &color4f_ptr); + + p.compile()(0,1); } else { // Linear gamma, dst gamut. swizzle_rb(SkNx_cast<float>(Sk4b::Load(&color)) * (1/255.0f)).store(&color4f); |