remove to_2dot2 and from_2dot2
The parametric_{r,g,b} stages are just as good now; under the hood it's all going through approx_powf. Change-Id: If7f3ae1e24fcee2ddb201c1d66ce1dd64820c89a Reviewed-on: https://skia-review.googlesource.com/14320 Reviewed-by: Matt Sarett <msarett@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
parent
21c131395f
commit
c7be00366b
@ -91,6 +91,13 @@ public:
|
||||
};
|
||||
DEF_BENCH( return (new SkRasterPipelineLegacyBench); )
|
||||
|
||||
static SkColorSpaceTransferFn gamma(float g) {
|
||||
SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0};
|
||||
fn.fG = g;
|
||||
fn.fA = 1;
|
||||
return fn;
|
||||
}
|
||||
|
||||
class SkRasterPipeline_2dot2 : public Benchmark {
|
||||
public:
|
||||
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
|
||||
@ -100,10 +107,17 @@ public:
|
||||
|
||||
void onDraw(int loops, SkCanvas*) override {
|
||||
SkColor4f c = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
SkColorSpaceTransferFn from_2dot2 = gamma( 2.2f),
|
||||
to_2dot2 = gamma(1/2.2f);
|
||||
SkRasterPipeline p;
|
||||
p.append(SkRasterPipeline::constant_color, &c);
|
||||
p.append(SkRasterPipeline::from_2dot2);
|
||||
p.append(SkRasterPipeline::to_2dot2);
|
||||
p.append(SkRasterPipeline::parametric_r, &from_2dot2);
|
||||
p.append(SkRasterPipeline::parametric_g, &from_2dot2);
|
||||
p.append(SkRasterPipeline::parametric_b, &from_2dot2);
|
||||
p.append(SkRasterPipeline::parametric_r, & to_2dot2);
|
||||
p.append(SkRasterPipeline::parametric_g, & to_2dot2);
|
||||
p.append(SkRasterPipeline::parametric_b, & to_2dot2);
|
||||
|
||||
while (loops --> 0) {
|
||||
p.run(0,N);
|
||||
|
@ -1244,12 +1244,17 @@ bool SkColorSpaceXform_XYZ<kCSM>
|
||||
}
|
||||
|
||||
TablesContext tables;
|
||||
SkColorSpaceTransferFn to_2dot2 = {0,0,0,0,0,0,0};
|
||||
to_2dot2.fG = 1/2.2f;
|
||||
to_2dot2.fA = 1;
|
||||
switch (fDstGamma) {
|
||||
case kSRGB_DstGamma:
|
||||
pipeline.append(SkRasterPipeline::to_srgb);
|
||||
break;
|
||||
case k2Dot2_DstGamma:
|
||||
pipeline.append(SkRasterPipeline::to_2dot2);
|
||||
pipeline.append(SkRasterPipeline::parametric_r, &to_2dot2);
|
||||
pipeline.append(SkRasterPipeline::parametric_g, &to_2dot2);
|
||||
pipeline.append(SkRasterPipeline::parametric_b, &to_2dot2);
|
||||
break;
|
||||
case kTable_DstGamma:
|
||||
tables.fR = fDstGammaTables[0];
|
||||
|
@ -112,13 +112,22 @@ SkColorSpaceXform_A2B::SkColorSpaceXform_A2B(SkColorSpace_A2B* srcSpace,
|
||||
case SkColorSpace_Base::kRGB_ICCTypeFlag:
|
||||
currentChannels = 3;
|
||||
break;
|
||||
case SkColorSpace_Base::kCMYK_ICCTypeFlag:
|
||||
case SkColorSpace_Base::kCMYK_ICCTypeFlag: {
|
||||
currentChannels = 4;
|
||||
// CMYK images from JPEGs (the only format that supports it) are actually
|
||||
// inverted CMYK, so we need to invert every channel.
|
||||
// TransferFn is y = -x + 1 for x < 1.f, otherwise 0x + 0, ie y = 1 - x for x in [0,1]
|
||||
this->addTransferFns({1.f, 0.f, 0.f, -1.f, 1.f, 0.f, 1.f}, 4);
|
||||
SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0};
|
||||
fn.fG = 1;
|
||||
fn.fA = 0;
|
||||
fn.fB = 0;
|
||||
fn.fC = -1;
|
||||
fn.fD = 1;
|
||||
fn.fE = 0;
|
||||
fn.fF = 1;
|
||||
this->addTransferFns(fn,4);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
currentChannels = 0;
|
||||
SkASSERT(false);
|
||||
@ -134,18 +143,12 @@ SkColorSpaceXform_A2B::SkColorSpaceXform_A2B(SkColorSpace_A2B* srcSpace,
|
||||
break;
|
||||
}
|
||||
|
||||
// take the fast path for 3-channel named gammas
|
||||
if (3 == currentChannels) {
|
||||
if (k2Dot2Curve_SkGammaNamed == e.gammaNamed()) {
|
||||
SkCSXformPrintf("fast path from 2.2\n");
|
||||
fElementsPipeline.append(SkRasterPipeline::from_2dot2);
|
||||
break;
|
||||
} else if (kSRGB_SkGammaNamed == e.gammaNamed()) {
|
||||
SkCSXformPrintf("fast path from sRGB\n");
|
||||
// Images should always start the pipeline as unpremul
|
||||
fElementsPipeline.append_from_srgb(kUnpremul_SkAlphaType);
|
||||
break;
|
||||
}
|
||||
// Take the fast path for ordinary sRGB.
|
||||
if (3 == currentChannels && kSRGB_SkGammaNamed == e.gammaNamed()) {
|
||||
SkCSXformPrintf("fast path from sRGB\n");
|
||||
// Images should always start the pipeline as unpremul
|
||||
fElementsPipeline.append_from_srgb(kUnpremul_SkAlphaType);
|
||||
break;
|
||||
}
|
||||
|
||||
SkCSXformPrintf("Gamma stage added: %s\n", debugGammaNamed[(int)e.gammaNamed()]);
|
||||
@ -234,9 +237,16 @@ SkColorSpaceXform_A2B::SkColorSpaceXform_A2B(SkColorSpace_A2B* srcSpace,
|
||||
case kLinear_SkGammaNamed:
|
||||
// do nothing
|
||||
break;
|
||||
case k2Dot2Curve_SkGammaNamed:
|
||||
fElementsPipeline.append(SkRasterPipeline::to_2dot2);
|
||||
case k2Dot2Curve_SkGammaNamed: {
|
||||
SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0};
|
||||
fn.fG = 1/2.2f;
|
||||
fn.fA = 1;
|
||||
auto to_2dot2 = this->copy(fn);
|
||||
fElementsPipeline.append(SkRasterPipeline::parametric_r, to_2dot2);
|
||||
fElementsPipeline.append(SkRasterPipeline::parametric_g, to_2dot2);
|
||||
fElementsPipeline.append(SkRasterPipeline::parametric_b, to_2dot2);
|
||||
break;
|
||||
}
|
||||
case kSRGB_SkGammaNamed:
|
||||
fElementsPipeline.append(SkRasterPipeline::to_srgb);
|
||||
break;
|
||||
|
@ -62,7 +62,6 @@
|
||||
M(unpremul) M(premul) \
|
||||
M(set_rgb) M(swap_rb) \
|
||||
M(from_srgb) M(to_srgb) \
|
||||
M(from_2dot2) M(to_2dot2) \
|
||||
M(constant_color) M(seed_shader) \
|
||||
M(load_a8) M(store_a8) \
|
||||
M(load_g8) \
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -479,17 +479,6 @@ STAGE(to_srgb) {
|
||||
b = fn(b);
|
||||
}
|
||||
|
||||
STAGE(from_2dot2) {
|
||||
r = approx_powf(r, C(2.2f));
|
||||
g = approx_powf(g, C(2.2f));
|
||||
b = approx_powf(b, C(2.2f));
|
||||
}
|
||||
STAGE(to_2dot2) {
|
||||
r = approx_powf(r, C(1/2.2f));
|
||||
g = approx_powf(g, C(1/2.2f));
|
||||
b = approx_powf(b, C(1/2.2f));
|
||||
}
|
||||
|
||||
STAGE(rgb_to_hsl) {
|
||||
F mx = max(max(r,g), b),
|
||||
mn = min(min(r,g), b),
|
||||
|
@ -41,7 +41,10 @@ static void check_error(skiatest::Reporter* r, float limit, SkColorSpaceTransfer
|
||||
}
|
||||
|
||||
static void check_error(skiatest::Reporter* r, float limit, float gamma) {
|
||||
check_error(r, limit, { gamma, 1.0f,0,0,0,0,0 });
|
||||
SkColorSpaceTransferFn fn = {0,0,0,0,0,0,0};
|
||||
fn.fG = gamma;
|
||||
fn.fA = 1;
|
||||
check_error(r, limit, fn);
|
||||
}
|
||||
|
||||
DEF_TEST(Parametric_sRGB, r) {
|
||||
@ -73,36 +76,3 @@ DEF_TEST(Parametric_inv_1dot8, r) { check_error(r, 1/510.0f, 1/1.8f); }
|
||||
DEF_TEST(Parametric_inv_2dot0, r) { check_error(r, 1/510.0f, 1/2.0f); }
|
||||
DEF_TEST(Parametric_inv_2dot2, r) { check_error(r, 1/510.0f, 1/2.2f); }
|
||||
DEF_TEST(Parametric_inv_2dot4, r) { check_error(r, 1/510.0f, 1/2.4f); }
|
||||
|
||||
// As above, checking that the stage implements gamma within limit.
|
||||
static void check_error(skiatest::Reporter* r, float limit,
|
||||
float gamma, SkRasterPipeline::StockStage stage) {
|
||||
|
||||
// We expect the gamma will only be applied to R,G,B, leaving A alone.
|
||||
// So this isn't quite exhaustive, but it's pretty good.
|
||||
float in[256], out[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
in [i] = i / 255.0f;
|
||||
out[i] = 0.0f; // Not likely important. Just being tidy.
|
||||
}
|
||||
|
||||
const float* ip = in;
|
||||
float* op = out;
|
||||
|
||||
SkRasterPipeline p;
|
||||
p.append(SkRasterPipeline::load_f32, &ip);
|
||||
p.append(stage);
|
||||
p.append(SkRasterPipeline::store_f32, &op);
|
||||
p.run(0, 256/4);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
float want = powf(i/255.0f, (i%4) == 3 ? 1.0f
|
||||
: gamma);
|
||||
float err = fabsf(out[i] - want);
|
||||
if (err > limit) {
|
||||
ERRORF(r, "At %d, error was %g (got %g, want %g)", i, err, out[i], want);
|
||||
}
|
||||
}
|
||||
}
|
||||
DEF_TEST(from_2dot2, r) { check_error(r, 1/510.f, 2.2f, SkRasterPipeline::from_2dot2); }
|
||||
DEF_TEST( to_2dot2, r) { check_error(r, 1/510.f, 1/2.2f,SkRasterPipeline:: to_2dot2); }
|
||||
|
Loading…
Reference in New Issue
Block a user