1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "../src/jumper/SkJumper.h" 9 #include "SkColorSpace_New.h" 10 #include "SkRasterPipeline.h" 11 #include "Test.h" 12 #include <initializer_list> 13 14 DEF_TEST(SkColorSpace_New_TransferFnBasics, r) { 15 auto gamut = SkMatrix44::I(); 16 auto blending = SkColorSpace_New::Blending::AsEncoded; 17 18 SkColorSpace_New linearA{SkColorSpace_New::TransferFn::MakeLinear(), gamut, blending}, 19 linearB{SkColorSpace_New::TransferFn::MakeGamma(1), gamut, blending}, 20 srgb{SkColorSpace_New::TransferFn::MakeSRGB(), gamut, blending}, 21 gamma{SkColorSpace_New::TransferFn::MakeGamma(2.2f), gamut, blending}; 22 23 REPORTER_ASSERT(r, linearA.gammaIsLinear()); 24 REPORTER_ASSERT(r, linearB.gammaIsLinear()); 25 REPORTER_ASSERT(r, ! srgb.gammaIsLinear()); 26 REPORTER_ASSERT(r, ! gamma.gammaIsLinear()); 27 28 REPORTER_ASSERT(r, !linearA.gammaCloseToSRGB()); 29 REPORTER_ASSERT(r, !linearB.gammaCloseToSRGB()); 30 REPORTER_ASSERT(r, srgb.gammaCloseToSRGB()); 31 REPORTER_ASSERT(r, ! gamma.gammaCloseToSRGB()); 32 33 REPORTER_ASSERT(r, linearA.transferFn().equals(linearB.transferFn())); 34 REPORTER_ASSERT(r, !linearA.transferFn().equals( srgb.transferFn())); 35 REPORTER_ASSERT(r, !linearA.transferFn().equals( gamma.transferFn())); 36 REPORTER_ASSERT(r, !linearB.transferFn().equals( srgb.transferFn())); 37 REPORTER_ASSERT(r, !linearB.transferFn().equals( gamma.transferFn())); 38 REPORTER_ASSERT(r, ! srgb.transferFn().equals( gamma.transferFn())); 39 } 40 41 DEF_TEST(SkColorSpace_New_TransferFnStages, r) { 42 // We'll create a little SkRasterPipelineBlitter-like scenario, 43 // blending the same src color over the same dst color, but with 44 // three different transfer functions, for simplicity the same for src and dst. 45 SkColor src = 0x7f7f0000; 46 47 SkColor dsts[3]; 48 for (SkColor& dst : dsts) { 49 dst = 0xff007f00; 50 } 51 52 auto gamut = SkMatrix44::I(); 53 auto blending = SkColorSpace_New::Blending::Linear; 54 SkColorSpace_New linear{SkColorSpace_New::TransferFn::MakeLinear(), gamut, blending}, 55 srgb{SkColorSpace_New::TransferFn::MakeSRGB(), gamut, blending}, 56 gamma{SkColorSpace_New::TransferFn::MakeGamma(3), gamut, blending}; 57 SkColor* dst = dsts; 58 for (const SkColorSpace_New* cs : {&linear, &srgb, &gamma}) { 59 SkJumper_MemoryCtx src_ctx = { &src, 0 }, 60 dst_ctx = { dst++, 0 }; 61 62 SkRasterPipeline_<256> p; 63 64 p.append(SkRasterPipeline::load_8888, &src_ctx); 65 cs->transferFn().linearizeSrc(&p); 66 p.append(SkRasterPipeline::premul); 67 68 p.append(SkRasterPipeline::load_8888_dst, &dst_ctx); 69 cs->transferFn().linearizeDst(&p); 70 p.append(SkRasterPipeline::premul_dst); 71 72 p.append(SkRasterPipeline::srcover); 73 p.append(SkRasterPipeline::unpremul); 74 cs->transferFn().encodeSrc(&p); 75 p.append(SkRasterPipeline::store_8888, &dst_ctx); 76 p.run(0,0,1,1); 77 } 78 79 // Double check the uninteresting channels: alpha's opaque, no blue. 80 REPORTER_ASSERT(r, SkColorGetA(dsts[0]) == 0xff && SkColorGetB(dsts[0]) == 0x00); 81 REPORTER_ASSERT(r, SkColorGetA(dsts[1]) == 0xff && SkColorGetB(dsts[1]) == 0x00); 82 REPORTER_ASSERT(r, SkColorGetA(dsts[2]) == 0xff && SkColorGetB(dsts[2]) == 0x00); 83 84 // Because we're doing linear blending, a more-exponential transfer function will 85 // brighten the encoded values more when linearizing. So we expect to see that 86 // linear is darker than sRGB, and sRGB in turn is darker than gamma 3. 87 REPORTER_ASSERT(r, SkColorGetR(dsts[0]) < SkColorGetR(dsts[1])); 88 REPORTER_ASSERT(r, SkColorGetR(dsts[1]) < SkColorGetR(dsts[2])); 89 90 REPORTER_ASSERT(r, SkColorGetG(dsts[0]) < SkColorGetG(dsts[1])); 91 REPORTER_ASSERT(r, SkColorGetG(dsts[1]) < SkColorGetG(dsts[2])); 92 93 } 94