Plumb dst color space in many places, rather than "mode"
[platform/upstream/libSkiaSharp.git] / tests / SkBlend_optsTest.cpp
1 /*
2  * Copyright 2016 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 <string>
9 #include <tuple>
10 #include <vector>
11 #include "Resources.h"
12 #include "SkCpu.h"
13 #include "SkImage.h"
14 #include "SkImage_Base.h"
15 #include "SkOpts.h"
16 #include "SkPM4fPriv.h"
17 #include "SkNx.h"
18 #include "Test.h"
19
20 typedef void (*Blender)(uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
21
22 static inline void srcover_srgb_srgb_1(uint32_t* dst, uint32_t src) {
23     auto d = Sk4f_fromS32(*dst),
24          s = Sk4f_fromS32( src);
25     *dst = Sk4f_toS32(s + d * (1.0f - s[3]));
26 }
27
28 static void brute_force_srcover_srgb_srgb(
29     uint32_t* dst, const uint32_t* const src, int ndst, const int nsrc) {
30     while (ndst > 0) {
31         int n = SkTMin(ndst, nsrc);
32
33         for (int i = 0; i < n; i++) {
34             srcover_srgb_srgb_1(dst++, src[i]);
35         }
36         ndst -= n;
37     }
38 }
39
40 static SkString mismatch_message(std::string resourceName, int x, int y,
41                                   uint32_t src, uint32_t good, uint32_t bad) {
42     return SkStringPrintf(
43         "%s - missmatch at %d, %d src: %08x good: %08x bad: %08x",
44         resourceName.c_str(), x, y, src, good, bad);
45 }
46
47 static void test_blender(std::string resourceName, skiatest::Reporter* reporter) {
48     std::string fileName = resourceName + ".png";
49     sk_sp<SkImage> image = GetResourceAsImage(fileName.c_str());
50     if (image == nullptr) {
51         ERRORF(reporter, "image is NULL");
52         return;
53     }
54     SkBitmap bm;
55     sk_sp<SkColorSpace> srgbColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
56     if (!as_IB(image)->getROPixels(&bm, srgbColorSpace.get())) {
57         ERRORF(reporter, "Could not read resource");
58         return;
59     }
60
61     SkPixmap pixmap;
62     bm.peekPixels(&pixmap);
63     SkASSERTF(pixmap.colorType() == kN32_SkColorType, "colorType: %d", pixmap.colorType());
64     SkASSERT(pixmap.alphaType() != kUnpremul_SkAlphaType);
65     const uint32_t* src = pixmap.addr32();
66     const int width = pixmap.rowBytesAsPixels();
67     SkASSERT(width > 0);
68     SkASSERT(width < 4000);
69     SkAutoTArray<uint32_t> correctDst(width);
70     SkAutoTArray<uint32_t> testDst(width);
71
72     for (int y = 0; y < pixmap.height(); y++) {
73         // TODO: zero is not the most interesting dst to test srcover...
74         sk_bzero(correctDst.get(), width * sizeof(uint32_t));
75         sk_bzero(testDst.get(), width * sizeof(uint32_t));
76         brute_force_srcover_srgb_srgb(correctDst.get(), src, width, width);
77         SkOpts::    srcover_srgb_srgb(   testDst.get(), src, width, width);
78         for (int x = 0; x < width; x++) {
79             REPORTER_ASSERT_MESSAGE(
80                 reporter, correctDst[x] == testDst[x],
81                 mismatch_message(resourceName, x, y, src[x], correctDst[x], testDst[x]));
82             if (correctDst[x] != testDst[x]) break;
83         }
84         src += width;
85     }
86 }
87
88 DEF_TEST(SkBlend_optsCheck, reporter) {
89     std::vector<std::string> testResources = {
90         "yellow_rose", "baby_tux", "plane", "mandrill_512", "iconstrip"
91     };
92
93     for (auto& resourceName : testResources) {
94         test_blender(resourceName, reporter);
95     }
96 }
97
98 DEF_TEST(SkBlend_optsSqrtCheck, reporter) {
99     for (int c = 0; c < 256; c++) {
100         Sk4f i{(float)c};
101         Sk4f ii = i * i;
102         Sk4f s = ii.sqrt() + 0.5f;
103         Sk4f sf = s.floor();
104         REPORTER_ASSERT_MESSAGE(
105             reporter, i[0] == sf[0], SkStringPrintf("i: %f, s: %f", i[0], sf[0]));
106     }
107 }