blob: e6813748522640a03164c4a89fa19061c062fbcf [file] [log] [blame]
herbcc49e592016-05-17 09:57:34 -07001/*
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"
herb2edf0c62016-07-12 15:00:46 -070016#include "SkPM4fPriv.h"
herbcc49e592016-05-17 09:57:34 -070017#include "SkNx.h"
18#include "Test.h"
herbcc49e592016-05-17 09:57:34 -070019
20typedef void (*Blender)(uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
21
mtklein0c902472016-07-20 18:10:07 -070022static 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
herb2edf0c62016-07-12 15:00:46 -070028static 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++) {
mtklein0c902472016-07-20 18:10:07 -070034 srcover_srgb_srgb_1(dst++, src[i]);
herb2edf0c62016-07-12 15:00:46 -070035 }
36 ndst -= n;
37 }
herbcc49e592016-05-17 09:57:34 -070038}
39
mtklein0358a6a2016-07-13 08:02:20 -070040static SkString mismatch_message(std::string resourceName, int x, int y,
herbcc49e592016-05-17 09:57:34 -070041 uint32_t src, uint32_t good, uint32_t bad) {
42 return SkStringPrintf(
mtklein0358a6a2016-07-13 08:02:20 -070043 "%s - missmatch at %d, %d src: %08x good: %08x bad: %08x",
44 resourceName.c_str(), x, y, src, good, bad);
herbcc49e592016-05-17 09:57:34 -070045}
46
mtklein0358a6a2016-07-13 08:02:20 -070047static void test_blender(std::string resourceName, skiatest::Reporter* reporter) {
herbcc49e592016-05-17 09:57:34 -070048 std::string fileName = resourceName + ".png";
49 sk_sp<SkImage> image = GetResourceAsImage(fileName.c_str());
herbcc49e592016-05-17 09:57:34 -070050 if (image == nullptr) {
bsalomon037655f2016-05-17 18:36:23 -070051 ERRORF(reporter, "image is NULL");
52 return;
herbcc49e592016-05-17 09:57:34 -070053 }
54 SkBitmap bm;
55 if (!as_IB(image)->getROPixels(&bm)) {
bsalomon037655f2016-05-17 18:36:23 -070056 ERRORF(reporter, "Could not read resource");
57 return;
herbcc49e592016-05-17 09:57:34 -070058 }
59
60 SkPixmap pixmap;
61 bm.peekPixels(&pixmap);
62 SkASSERTF(pixmap.colorType() == kN32_SkColorType, "colorType: %d", pixmap.colorType());
63 SkASSERT(pixmap.alphaType() != kUnpremul_SkAlphaType);
64 const uint32_t* src = pixmap.addr32();
65 const int width = pixmap.rowBytesAsPixels();
66 SkASSERT(width > 0);
67 SkASSERT(width < 4000);
68 SkAutoTArray<uint32_t> correctDst(width);
69 SkAutoTArray<uint32_t> testDst(width);
70
71 for (int y = 0; y < pixmap.height(); y++) {
mtklein0c902472016-07-20 18:10:07 -070072 // TODO: zero is not the most interesting dst to test srcover...
herb2edf0c62016-07-12 15:00:46 -070073 sk_bzero(correctDst.get(), width * sizeof(uint32_t));
74 sk_bzero(testDst.get(), width * sizeof(uint32_t));
75 brute_force_srcover_srgb_srgb(correctDst.get(), src, width, width);
mtklein0358a6a2016-07-13 08:02:20 -070076 SkOpts:: srcover_srgb_srgb( testDst.get(), src, width, width);
herbcc49e592016-05-17 09:57:34 -070077 for (int x = 0; x < width; x++) {
78 REPORTER_ASSERT_MESSAGE(
79 reporter, correctDst[x] == testDst[x],
mtklein0358a6a2016-07-13 08:02:20 -070080 mismatch_message(resourceName, x, y, src[x], correctDst[x], testDst[x]));
herbcc49e592016-05-17 09:57:34 -070081 if (correctDst[x] != testDst[x]) break;
82 }
83 src += width;
84 }
85}
86
87DEF_TEST(SkBlend_optsCheck, reporter) {
herbcc49e592016-05-17 09:57:34 -070088 std::vector<std::string> testResources = {
89 "yellow_rose", "baby_tux", "plane", "mandrill_512", "iconstrip"
90 };
91
mtklein0358a6a2016-07-13 08:02:20 -070092 for (auto& resourceName : testResources) {
93 test_blender(resourceName, reporter);
herbcc49e592016-05-17 09:57:34 -070094 }
95}
96
herbcc49e592016-05-17 09:57:34 -070097DEF_TEST(SkBlend_optsSqrtCheck, reporter) {
98 for (int c = 0; c < 256; c++) {
99 Sk4f i{(float)c};
100 Sk4f ii = i * i;
101 Sk4f s = ii.sqrt() + 0.5f;
102 Sk4f sf = s.floor();
103 REPORTER_ASSERT_MESSAGE(
104 reporter, i[0] == sf[0], SkStringPrintf("i: %f, s: %f", i[0], sf[0]));
105 }
106}