blob: 13357b3aeb9935aa633509d2f1ca216ffe8144c3 [file] [log] [blame]
junov@chromium.orgb6e16192011-12-09 15:48:03 +00001/*
2 * Copyright 2011 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 */
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkBitmap.h"
Mike Reed9290d012020-06-11 16:56:06 -04009#include "include/core/SkCanvas.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkShader.h"
Mike Reed9290d012020-06-11 16:56:06 -040011#include "include/core/SkSurface.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/effects/SkGradientShader.h"
13#include "src/shaders/SkColorShader.h"
14#include "tests/Test.h"
Mike Reed9290d012020-06-11 16:56:06 -040015#include "tools/ToolUtils.h"
junov@chromium.orgb6e16192011-12-09 15:48:03 +000016
17static void test_bitmap(skiatest::Reporter* reporter) {
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000018 SkImageInfo info = SkImageInfo::MakeN32Premul(2, 2);
19
junov@chromium.orgb6e16192011-12-09 15:48:03 +000020 SkBitmap bmp;
commit-bot@chromium.orga3264e52014-05-30 13:26:10 +000021 bmp.setInfo(info);
rmistry@google.comd6176b02012-08-23 18:14:13 +000022
junov@chromium.orgb6e16192011-12-09 15:48:03 +000023 // test 1: bitmap without pixel data
Mike Reed50acf8f2019-04-08 13:20:23 -040024 auto shader = bmp.makeShader(SkTileMode::kClamp, SkTileMode::kClamp);
junov@chromium.orgb6e16192011-12-09 15:48:03 +000025 REPORTER_ASSERT(reporter, shader);
26 REPORTER_ASSERT(reporter, !shader->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000027
28 // From this point on, we have pixels
mike@reedtribe.orgdeee4962014-02-13 14:41:43 +000029 bmp.allocPixels(info);
junov@chromium.orgb6e16192011-12-09 15:48:03 +000030
31 // test 2: not opaque by default
Mike Reed50acf8f2019-04-08 13:20:23 -040032 shader = bmp.makeShader();
junov@chromium.orgb6e16192011-12-09 15:48:03 +000033 REPORTER_ASSERT(reporter, shader);
34 REPORTER_ASSERT(reporter, !shader->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000035
36 // test 3: explicitly opaque
reed@google.com383a6972013-10-21 14:00:07 +000037 bmp.setAlphaType(kOpaque_SkAlphaType);
Mike Reed50acf8f2019-04-08 13:20:23 -040038 shader = bmp.makeShader();
junov@chromium.orgb6e16192011-12-09 15:48:03 +000039 REPORTER_ASSERT(reporter, shader);
40 REPORTER_ASSERT(reporter, shader->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000041
42 // test 4: explicitly not opaque
reed@google.com383a6972013-10-21 14:00:07 +000043 bmp.setAlphaType(kPremul_SkAlphaType);
Mike Reed50acf8f2019-04-08 13:20:23 -040044 shader = bmp.makeShader();
junov@chromium.orgb6e16192011-12-09 15:48:03 +000045 REPORTER_ASSERT(reporter, shader);
46 REPORTER_ASSERT(reporter, !shader->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000047}
48
reed1a9b9642016-03-13 14:13:58 -070049static void test_gradient(skiatest::Reporter* reporter) {
junov@chromium.orgb6e16192011-12-09 15:48:03 +000050 SkPoint pts[2];
51 pts[0].iset(0, 0);
52 pts[1].iset(1, 0);
53 SkColor colors[2];
54 SkScalar pos[2] = {SkIntToScalar(0), SkIntToScalar(1)};
55 int count = 2;
Mike Reedfae8fce2019-04-03 10:27:45 -040056 SkTileMode mode = SkTileMode::kClamp;
junov@chromium.orgb6e16192011-12-09 15:48:03 +000057
58 // test 1: all opaque
59 colors[0] = SkColorSetARGB(0xFF, 0, 0, 0);
60 colors[1] = SkColorSetARGB(0xFF, 0, 0, 0);
reed1a9b9642016-03-13 14:13:58 -070061 auto grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode);
junov@chromium.orgb6e16192011-12-09 15:48:03 +000062 REPORTER_ASSERT(reporter, grad);
63 REPORTER_ASSERT(reporter, grad->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000064
65 // test 2: all 0 alpha
66 colors[0] = SkColorSetARGB(0, 0, 0, 0);
67 colors[1] = SkColorSetARGB(0, 0, 0, 0);
reed1a9b9642016-03-13 14:13:58 -070068 grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode);
junov@chromium.orgb6e16192011-12-09 15:48:03 +000069 REPORTER_ASSERT(reporter, grad);
70 REPORTER_ASSERT(reporter, !grad->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000071
72 // test 3: one opaque, one transparent
73 colors[0] = SkColorSetARGB(0xFF, 0, 0, 0);
74 colors[1] = SkColorSetARGB(0x40, 0, 0, 0);
reed1a9b9642016-03-13 14:13:58 -070075 grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode);
junov@chromium.orgb6e16192011-12-09 15:48:03 +000076 REPORTER_ASSERT(reporter, grad);
77 REPORTER_ASSERT(reporter, !grad->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000078
79 // test 4: test 3, swapped
80 colors[0] = SkColorSetARGB(0x40, 0, 0, 0);
81 colors[1] = SkColorSetARGB(0xFF, 0, 0, 0);
reed1a9b9642016-03-13 14:13:58 -070082 grad = SkGradientShader::MakeLinear(pts, colors, pos, count, mode);
junov@chromium.orgb6e16192011-12-09 15:48:03 +000083 REPORTER_ASSERT(reporter, grad);
84 REPORTER_ASSERT(reporter, !grad->isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000085}
86
reed1a9b9642016-03-13 14:13:58 -070087static void test_color(skiatest::Reporter* reporter) {
junov@chromium.orgb6e16192011-12-09 15:48:03 +000088 SkColorShader colorShader1(SkColorSetARGB(0,0,0,0));
89 REPORTER_ASSERT(reporter, !colorShader1.isOpaque());
90 SkColorShader colorShader2(SkColorSetARGB(0xFF,0,0,0));
91 REPORTER_ASSERT(reporter, colorShader2.isOpaque());
92 SkColorShader colorShader3(SkColorSetARGB(0x7F,0,0,0));
93 REPORTER_ASSERT(reporter, !colorShader3.isOpaque());
junov@chromium.orgb6e16192011-12-09 15:48:03 +000094}
95
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000096DEF_TEST(ShaderOpacity, reporter) {
junov@chromium.orgb6e16192011-12-09 15:48:03 +000097 test_gradient(reporter);
98 test_color(reporter);
99 test_bitmap(reporter);
100}
Mike Reed9290d012020-06-11 16:56:06 -0400101
102DEF_TEST(image_shader_filtering, reporter) {
103 auto make_checker_img = [](int w, int h) {
104 auto info = SkImageInfo::Make(w, h, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
105 auto surf = SkSurface::MakeRaster(info);
106 ToolUtils::draw_checkerboard(surf->getCanvas(), SK_ColorRED, SK_ColorBLUE, 2);
107 return surf->makeImageSnapshot();
108 };
109
110 auto img = make_checker_img(4, 4);
111
112 const SkFilterQuality quals[] = {
113 kNone_SkFilterQuality,
114 kLow_SkFilterQuality,
115 kMedium_SkFilterQuality,
116 kHigh_SkFilterQuality,
117 };
118 const SkScalar scales[] = { 3.0f, 1.0f, 0.5f, 0.25f, 0.125f };
119
120 auto make_img = [&](const SkPaint& paint) {
121 auto info = SkImageInfo::Make(70, 70, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
122 auto surf = SkSurface::MakeRaster(info);
123 auto canvas = surf->getCanvas();
124 canvas->scale(1.06f, 1.06f); // nicely exaggerates noise when not filtering
125 canvas->drawRect({0, 0, 64, 64}, paint);
126 return surf->makeImageSnapshot();
127 };
128
129 SkPaint paint;
130 for (auto q : quals) {
131 for (auto scale : scales) {
132 SkMatrix m = SkMatrix::Scale(scale, scale);
133 paint.setFilterQuality(kNone_SkFilterQuality); // this setting should be ignored
134 paint.setShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m, q));
135 auto img0 = make_img(paint);
136
137 paint.setFilterQuality(q); // this should (still) be ignored
138 auto img1 = make_img(paint);
139
140 // make legacy form of shader, relying on the paint's filter-quality (q)
141 paint.setShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m));
142 auto img2 = make_img(paint);
143
144 REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img0.get(), img1.get()));
145 REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img0.get(), img2.get()));
146 }
147 }
148}