aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkPM4fPriv.h66
-rw-r--r--src/effects/SkToSRGBColorFilter.cpp46
2 files changed, 75 insertions, 37 deletions
diff --git a/src/core/SkPM4fPriv.h b/src/core/SkPM4fPriv.h
index 2789d3763e..0ded5e5116 100644
--- a/src/core/SkPM4fPriv.h
+++ b/src/core/SkPM4fPriv.h
@@ -99,51 +99,65 @@ static inline void analyze_3x4_matrix(const float matrix[12],
*can_overflow = overflow;
}
-
// N.B. scratch_matrix_3x4 must live at least as long as p.
-static inline void append_gamut_transform(SkRasterPipeline* p, float scratch_matrix_3x4[12],
- SkColorSpace* src, SkColorSpace* dst,
- SkAlphaType alphaType) {
- if (src == dst) { return; } // That was easy.
- if (!dst) { return; } // Legacy modes intentionally ignore color gamut.
- if (!src) { return; } // A null src color space means linear gamma, dst gamut.
-
- auto toXYZ = as_CSB(src)-> toXYZD50(),
- fromXYZ = as_CSB(dst)->fromXYZD50();
- if (!toXYZ || !fromXYZ) {
- SkASSERT(false); // We really don't want to get here with a weird colorspace.
- return;
+// Returns false if no gamut tranformation was necessary.
+static inline bool append_gamut_transform_noclamp(SkRasterPipeline* p,
+ float scratch_matrix_3x4[12],
+ SkColorSpace* src,
+ SkColorSpace* dst) {
+ if (src == dst || !dst || !src) {
+ return false;
+ }
+
+ const SkMatrix44 *fromSrc = as_CSB(src)-> toXYZD50(),
+ *toDst = as_CSB(dst)->fromXYZD50();
+ if (!fromSrc || !toDst) {
+ SkDEBUGFAIL("We can't handle non-XYZ color spaces in append_gamut_transform().");
+ return false;
}
// Slightly more sophisticated version of if (src == dst)
if (as_CSB(src)->toXYZD50Hash() == as_CSB(dst)->toXYZD50Hash()) {
- return;
+ return false;
}
- SkMatrix44 m44(*fromXYZ, *toXYZ);
-
// Convert from 4x4 to (column-major) 3x4.
+ SkMatrix44 m44(*toDst, *fromSrc);
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);
- bool needs_clamp_0, needs_clamp_1;
- analyze_3x4_matrix(scratch_matrix_3x4, &needs_clamp_0, &needs_clamp_1);
-
p->append(SkRasterPipeline::matrix_3x4, scratch_matrix_3x4);
- if (needs_clamp_0) { p->append(SkRasterPipeline::clamp_0); }
- if (needs_clamp_1) {
- (kPremul_SkAlphaType == alphaType) ? p->append(SkRasterPipeline::clamp_a)
- : p->append(SkRasterPipeline::clamp_1);
+ return true;
+}
+
+
+// N.B. scratch_matrix_3x4 must live at least as long as p.
+static inline void append_gamut_transform(SkRasterPipeline* p,
+ float scratch_matrix_3x4[12],
+ SkColorSpace* src,
+ SkColorSpace* dst,
+ SkAlphaType alphaType) {
+ if (append_gamut_transform_noclamp(p, scratch_matrix_3x4, src, dst)) {
+ bool needs_clamp_0, needs_clamp_1;
+ analyze_3x4_matrix(scratch_matrix_3x4, &needs_clamp_0, &needs_clamp_1);
+
+ if (needs_clamp_0) { p->append(SkRasterPipeline::clamp_0); }
+ if (needs_clamp_1) {
+ (kPremul_SkAlphaType == alphaType) ? p->append(SkRasterPipeline::clamp_a)
+ : p->append(SkRasterPipeline::clamp_1);
+ }
}
}
-static inline void append_gamut_transform(SkRasterPipeline* p, SkArenaAlloc* scratch,
- SkColorSpace* src, SkColorSpace* dst,
+static inline void append_gamut_transform(SkRasterPipeline* p,
+ SkArenaAlloc* alloc,
+ SkColorSpace* src,
+ SkColorSpace* dst,
SkAlphaType alphaType) {
- append_gamut_transform(p, scratch->makeArrayDefault<float>(12), src, dst, alphaType);
+ append_gamut_transform(p, alloc->makeArrayDefault<float>(12), src, dst, alphaType);
}
static inline SkColor4f to_colorspace(const SkColor4f& c, SkColorSpace* src, SkColorSpace* dst) {
diff --git a/src/effects/SkToSRGBColorFilter.cpp b/src/effects/SkToSRGBColorFilter.cpp
index 7b6b3e6b84..253fea1427 100644
--- a/src/effects/SkToSRGBColorFilter.cpp
+++ b/src/effects/SkToSRGBColorFilter.cpp
@@ -5,26 +5,50 @@
* found in the LICENSE file.
*/
-#include "SkToSRGBColorFilter.h"
-#include "SkPM4f.h"
-#include "SkColorPriv.h"
-#include "SkColorSpace.h"
#include "SkColorSpace_Base.h"
+#include "SkPM4fPriv.h"
#include "SkRasterPipeline.h"
#include "SkString.h"
+#include "SkToSRGBColorFilter.h"
#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#include "effects/GrNonlinearColorSpaceXformEffect.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
+ #include "effects/GrNonlinearColorSpaceXformEffect.h"
#endif
void SkToSRGBColorFilter::onAppendStages(SkRasterPipeline* p,
- SkColorSpace* dst,
- SkArenaAlloc* scratch,
+ SkColorSpace* /*dst color space*/,
+ SkArenaAlloc* alloc,
bool shaderIsOpaque) const {
- // TODO
+ if (fSrcColorSpace->isSRGB()) {
+ // That was easy.
+ return;
+ }
+
+ // Step 1: Linearize by undoing the src transfer function.
+ // Linear and sRGB will return true to isNumericalTransferFn(), so we check them first.
+ SkColorSpaceTransferFn srcFn;
+ if (fSrcColorSpace->gammaIsLinear()) {
+ // Nothing to do.
+ } else if (fSrcColorSpace->gammaCloseToSRGB()) {
+ p->append_from_srgb(shaderIsOpaque ? kOpaque_SkAlphaType
+ : kPremul_SkAlphaType);
+ } else if (fSrcColorSpace->isNumericalTransferFn(&srcFn)) {
+ p->append(SkRasterPipeline::parametric_r, &srcFn);
+ p->append(SkRasterPipeline::parametric_g, &srcFn);
+ p->append(SkRasterPipeline::parametric_b, &srcFn);
+ } else {
+ SkDEBUGFAIL("Looks like we got a table transfer function here, quite unexpectedly.");
+ // TODO: If we really need to handle this, we can, but I don't think Ganesh does.
+ }
+
+ // Step 2: Transform to sRGB gamut, without clamping.
+ (void)append_gamut_transform_noclamp(p,
+ alloc->makeArrayDefault<float>(12),
+ fSrcColorSpace.get(),
+ SkColorSpace::MakeSRGB().get());
+
+ // Step 3: Back to sRGB encoding.
+ p->append(SkRasterPipeline::to_srgb);
}
sk_sp<SkColorFilter> SkToSRGBColorFilter::Make(sk_sp<SkColorSpace> srcColorSpace) {