be6e575ee7
- opaque and unpremul are never the same... there's no reason to ever premul opaque sources. - under optimization, they won't always be a deterministic tweak the the premul steps (though right now they still are). Change-Id: I5669b3dba83774326c07d5a8f16b1d2ce2b22aae Reviewed-on: https://skia-review.googlesource.com/130061 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Auto-Submit: Mike Klein <mtklein@chromium.org>
195 lines
11 KiB
C++
195 lines
11 KiB
C++
/*
|
|
* Copyright 2018 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "SkColorSpacePriv.h"
|
|
#include "SkColorSpaceXformSteps.h"
|
|
#include "Test.h"
|
|
|
|
template <typename T>
|
|
static void check_eq(skiatest::Reporter* r, SkColorSpaceXformSteps steps, T baseline) {
|
|
REPORTER_ASSERT(r, steps.early_unpremul == baseline.early_unpremul);
|
|
REPORTER_ASSERT(r, steps.linearize_src == baseline.linearize_src);
|
|
REPORTER_ASSERT(r, steps.late_unpremul == baseline.late_unpremul);
|
|
REPORTER_ASSERT(r, steps.gamut_transform == baseline.gamut_transform);
|
|
REPORTER_ASSERT(r, steps.early_encode == baseline.early_encode);
|
|
REPORTER_ASSERT(r, steps.premul == baseline.premul);
|
|
REPORTER_ASSERT(r, steps.linearize_dst == baseline.linearize_dst);
|
|
REPORTER_ASSERT(r, steps.late_encode == baseline.late_encode);
|
|
|
|
// A couple (redundant) sanity checks that cover impossible states.
|
|
// At most one of the early/late options should happen, possibly neither.
|
|
REPORTER_ASSERT(r, !(steps.early_unpremul && steps.late_unpremul));
|
|
REPORTER_ASSERT(r, !(steps.early_encode && steps.late_encode));
|
|
}
|
|
|
|
DEF_TEST(SkColorSpaceXformSteps, r) {
|
|
auto srgb_L = SkColorSpace::MakeSRGB(),
|
|
adobe_L = SkColorSpace::MakeRGB(g2Dot2_TransferFn, SkColorSpace::kAdobeRGB_Gamut),
|
|
srgb22_L = SkColorSpace::MakeRGB(g2Dot2_TransferFn, SkColorSpace:: kSRGB_Gamut),
|
|
srgb_N = srgb_L->makeNonlinearBlending(),
|
|
adobe_N = adobe_L->makeNonlinearBlending(),
|
|
srgb22_N = srgb22_L->makeNonlinearBlending();
|
|
|
|
struct {
|
|
sk_sp<SkColorSpace> src, dst;
|
|
SkAlphaType srcAT;
|
|
|
|
bool early_unpremul;
|
|
bool linearize_src;
|
|
bool late_unpremul;
|
|
|
|
bool gamut_transform;
|
|
bool early_encode;
|
|
bool premul;
|
|
|
|
bool linearize_dst;
|
|
bool late_encode;
|
|
} tests[] = {
|
|
// The first eight cases we test are back and forth between two color spaces with
|
|
// different gamuts and transfer functions. There's not much optimization possible here.
|
|
|
|
{ adobe_N, srgb_N, kPremul_SkAlphaType,
|
|
true, // src is encoded as f(s)*a,a, so we unpremul to f(s),a before linearizing.
|
|
true, // Linearize to s,a.
|
|
false,
|
|
|
|
true, // Gamut transform.
|
|
true, // Non-linear blending, so we encode to sRGB g(s),a early.
|
|
true, // Premul to g(s)*a,a
|
|
|
|
false, // Non-linear blending, so no need to linearize dst.
|
|
false, // Non-linear blending, so the output of our blend function is what we want.
|
|
},
|
|
{ srgb_N, adobe_N, kPremul_SkAlphaType, true,true,false, true,true,true, false,false },
|
|
|
|
{ adobe_L, srgb_L, kPremul_SkAlphaType,
|
|
false, // src is encoded as f(s*a),a, so we linearize before unpremul.
|
|
true, // Linearize,
|
|
true, // then unpremul.
|
|
|
|
true, // Gamut transform.
|
|
false, // We're doing linear blending, so we don't encode to sRGB yet.
|
|
true, // Premul so we can blend.
|
|
|
|
true, // We're doing linear blending, so we need to linearize dst.
|
|
true, // Once blending is done, finally encode to sRGB.
|
|
},
|
|
{ srgb_L, adobe_L, kPremul_SkAlphaType, false,true,true, true,false,true, true,true },
|
|
|
|
{ adobe_L, srgb_N, kPremul_SkAlphaType,
|
|
false, // src is encoded as f(s*a),a, so we linearize before unpremul.
|
|
true, // Linearize,
|
|
true, // then unpremul.
|
|
|
|
true, // Gamut transform
|
|
true, // We're doing non-linear blending, so encode to sRGB now.
|
|
true, // (non-linear) premul
|
|
|
|
false, // We're doing non-linear blending, so dst is already ready to blend.
|
|
false, // The output of the blend is just what we want.
|
|
},
|
|
{ srgb_L, adobe_N, kPremul_SkAlphaType, false,true,true, true,true,true, false,false },
|
|
|
|
{ adobe_N, srgb_L, kPremul_SkAlphaType,
|
|
true, // src is encoded as f(s)*a,a, so we unpremul to f(s),a before linearizing.
|
|
true, // Linearize to s,a.
|
|
false,
|
|
|
|
true, // Gamut transform
|
|
false, // We're doing linear blending, so we don't encode to sRGB yet.
|
|
true, // (linear) premul
|
|
|
|
true, // We're doing linear blending, so we need to linearize dst.
|
|
true, // Once blending is done, finally encode to sRGB.
|
|
},
|
|
{ srgb_N, adobe_L, kPremul_SkAlphaType, true,true,false, true,false,true, true,true },
|
|
|
|
// These next 16 are the previous 8 with opaque and unpremul srcs.
|
|
// Generally, the steps that change are the early_unpremul, late_unpremul, and premul steps,
|
|
// but optimizations can sometimes make more steps drop out.
|
|
{ adobe_N, srgb_N, kOpaque_SkAlphaType, false,true,false, true,true,false, false,false },
|
|
{ adobe_N, srgb_N, kUnpremul_SkAlphaType, false,true,false, true,true,true, false,false },
|
|
{ srgb_N, adobe_N, kOpaque_SkAlphaType, false,true,false, true,true,false, false,false },
|
|
{ srgb_N, adobe_N, kUnpremul_SkAlphaType, false,true,false, true,true,true, false,false },
|
|
|
|
{ adobe_L, srgb_L, kOpaque_SkAlphaType, false,true,false, true,false,false, true,true },
|
|
{ adobe_L, srgb_L, kUnpremul_SkAlphaType, false,true,false, true,false,true, true,true },
|
|
{ srgb_L, adobe_L, kOpaque_SkAlphaType, false,true,false, true,false,false, true,true },
|
|
{ srgb_L, adobe_L, kUnpremul_SkAlphaType, false,true,false, true,false,true, true,true },
|
|
|
|
{ adobe_L, srgb_N, kOpaque_SkAlphaType, false,true,false, true,true,false, false,false },
|
|
{ adobe_L, srgb_N, kUnpremul_SkAlphaType, false,true,false, true,true,true, false,false },
|
|
{ srgb_L, adobe_N, kOpaque_SkAlphaType, false,true,false, true,true,false, false,false },
|
|
{ srgb_L, adobe_N, kUnpremul_SkAlphaType, false,true,false, true,true,true, false,false },
|
|
|
|
{ adobe_N, srgb_L, kOpaque_SkAlphaType, false,true,false, true,false,false, true,true },
|
|
{ adobe_N, srgb_L, kUnpremul_SkAlphaType, false,true,false, true,false,true, true,true },
|
|
{ srgb_N, adobe_L, kOpaque_SkAlphaType, false,true,false, true,false,false, true,true },
|
|
{ srgb_N, adobe_L, kUnpremul_SkAlphaType, false,true,false, true,false,true, true,true },
|
|
|
|
// These eight cases transform between color spaces with different
|
|
// transfer functions and the same gamut. Optimization here is limited
|
|
// to skipping the gamut_transform step: |
|
|
// This column v has all become false.
|
|
{ srgb_N, srgb22_N, kPremul_SkAlphaType, true,true,false, false,true,true, false,false },
|
|
{ srgb22_N, srgb_N, kPremul_SkAlphaType, true,true,false, false,true,true, false,false },
|
|
|
|
{ srgb_L, srgb22_L, kPremul_SkAlphaType, false,true,true, false,false,true, true,true },
|
|
{ srgb22_L, srgb_L, kPremul_SkAlphaType, false,true,true, false,false,true, true,true },
|
|
|
|
{ srgb_L, srgb22_N, kPremul_SkAlphaType, false,true,true, false,true,true, false,false },
|
|
{ srgb22_L, srgb_N, kPremul_SkAlphaType, false,true,true, false,true,true, false,false },
|
|
|
|
{ srgb_N, srgb22_L, kPremul_SkAlphaType, true,true,false, false,false,true, true,true },
|
|
{ srgb22_N, srgb_L, kPremul_SkAlphaType, true,true,false, false,false,true, true,true },
|
|
|
|
// Same deal, the next 16 are the previous 8 in opaque and unpremul.
|
|
{ srgb_N, srgb22_N, kOpaque_SkAlphaType, false,true,false, false,true,false, false,false},
|
|
{ srgb_N, srgb22_N, kUnpremul_SkAlphaType, false,true,false, false,true,true, false,false},
|
|
{ srgb22_N, srgb_N, kOpaque_SkAlphaType, false,true,false, false,true,false, false,false},
|
|
{ srgb22_N, srgb_N, kUnpremul_SkAlphaType, false,true,false, false,true,true, false,false},
|
|
|
|
{ srgb_L, srgb22_L, kOpaque_SkAlphaType, false,true,false, false,false,false, true,true },
|
|
{ srgb_L, srgb22_L, kUnpremul_SkAlphaType, false,true,false, false,false,true, true,true },
|
|
{ srgb22_L, srgb_L, kOpaque_SkAlphaType, false,true,false, false,false,false, true,true },
|
|
{ srgb22_L, srgb_L, kUnpremul_SkAlphaType, false,true,false, false,false,true, true,true },
|
|
|
|
{ srgb_L, srgb22_N, kOpaque_SkAlphaType, false,true,false, false,true,false, false,false},
|
|
{ srgb_L, srgb22_N, kUnpremul_SkAlphaType, false,true,false, false,true,true, false,false},
|
|
{ srgb22_L, srgb_N, kOpaque_SkAlphaType, false,true,false, false,true,false, false,false},
|
|
{ srgb22_L, srgb_N, kUnpremul_SkAlphaType, false,true,false, false,true,true, false,false},
|
|
|
|
{ srgb_N, srgb22_L, kOpaque_SkAlphaType, false,true,false, false,false,false, true,true },
|
|
{ srgb_N, srgb22_L, kUnpremul_SkAlphaType, false,true,false, false,false,true, true,true },
|
|
{ srgb22_N, srgb_L, kOpaque_SkAlphaType, false,true,false, false,false,false, true,true },
|
|
{ srgb22_N, srgb_L, kUnpremul_SkAlphaType, false,true,false, false,false,true, true,true },
|
|
|
|
// These four test cases test drawing in the same color space.
|
|
// There is lots of room for optimization here.
|
|
{ srgb_N, srgb_N, kPremul_SkAlphaType, true,true,false, false,true,true, false,false },
|
|
{ srgb_L, srgb_L, kPremul_SkAlphaType, false,true,true, false,false,true, true,true },
|
|
{ srgb_L, srgb_N, kPremul_SkAlphaType, false,true,true, false,true,true, false,false },
|
|
{ srgb_N, srgb_L, kPremul_SkAlphaType, true,true,false, false,false,true, true,true },
|
|
|
|
// And the usual variants for opaque + unpremul sources.
|
|
{ srgb_N, srgb_N, kOpaque_SkAlphaType, false,true,false, false,true,false, false,false },
|
|
{ srgb_N, srgb_N, kUnpremul_SkAlphaType, false,true,false, false,true,true, false,false },
|
|
{ srgb_L, srgb_L, kOpaque_SkAlphaType, false,true,false, false,false,false, true,true },
|
|
{ srgb_L, srgb_L, kUnpremul_SkAlphaType, false,true,false, false,false,true, true,true },
|
|
{ srgb_L, srgb_N, kOpaque_SkAlphaType, false,true,false, false,true,false, false,false },
|
|
{ srgb_L, srgb_N, kUnpremul_SkAlphaType, false,true,false, false,true,true, false,false },
|
|
{ srgb_N, srgb_L, kOpaque_SkAlphaType, false,true,false, false,false,false, true,true },
|
|
{ srgb_N, srgb_L, kUnpremul_SkAlphaType, false,true,false, false,false,true, true,true },
|
|
|
|
// TODO: versions of above crossing in linear transfer functions
|
|
};
|
|
|
|
for (auto t : tests) {
|
|
check_eq(r, SkColorSpaceXformSteps(t.src.get(), t.srcAT, t.dst.get()), t);
|
|
}
|
|
}
|