Flutter Engine
The Flutter Engine
matrixconvolution.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 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 "gm/gm.h"
12#include "include/core/SkFont.h"
16#include "include/core/SkRect.h"
19#include "include/core/SkSize.h"
25#include "src/gpu/BlurUtils.h"
26#include "tools/ToolUtils.h"
28
29#include <vector>
30
31namespace skiagm {
32
38};
39
40class MatrixConvolutionGM : public GM {
41public:
42 MatrixConvolutionGM(SkColor colorOne, SkColor colorTwo, KernelFixture kernelFixture, const char* nameSuffix)
43 : fNameSuffix(nameSuffix),
44 fKernelFixture(kernelFixture) {
45 this->setBGColor(0x00000000);
46 fColors[0] = colorOne;
47 fColors[1] = colorTwo;
48 }
49
50protected:
51 bool runAsBench() const override { return true; }
52
53 SkString getName() const override { return SkStringPrintf("matrixconvolution%s", fNameSuffix); }
54
55 void makeBitmap() {
56 // Draw our bitmap in N32, so legacy devices get "premul" values they understand
59 paint.setColor(0xFFFFFFFF);
60 SkPoint pts[2] = { {0, 0},
61 {0, 80.0f} };
62 SkScalar pos[2] = { 0, 80.0f };
64 pts, fColors, pos, 2, SkTileMode::kClamp));
66 surf->getCanvas()->drawString("e", -10.0f, 80.0f, font, paint);
67 fImage = surf->makeImageSnapshot();
68 }
69
70 SkISize getISize() override { return SkISize::Make(500, 300); }
71
73 SkTileMode tileMode,
74 bool convolveAlpha) {
75 // The kernelOffset is specified in a 0..2 coordinate space.
76 float normalizedXOffset = kernelOffsetIn.fX / 2.0f;
77 float normalizedYOffset = kernelOffsetIn.fY / 2.0f;
78 // Must provide a cropping geometry in order for 'tileMode' to be well defined.
79 SkIRect tileBoundary = fImage->bounds();
80 switch (fKernelFixture) {
82 SkIPoint kernelOffset {SkScalarRoundToInt(2*normalizedXOffset),
83 SkScalarRoundToInt(2*normalizedYOffset)};
84 // All 1s except center value, which is -7 (sum of 1).
85 std::vector<SkScalar> kernel(9, SkIntToScalar(1));
86 kernel[4] = SkIntToScalar(-7);
88 {3,3}, kernel.data(), /* gain= */ 0.3f, /* bias= */ 100.0f,
89 kernelOffset, tileMode, convolveAlpha, nullptr, tileBoundary);
90 }
92 SkIPoint kernelOffset {SkScalarRoundToInt(6*normalizedXOffset),
93 SkScalarRoundToInt(6*normalizedYOffset)};
94 // This ensures the texture fallback path will be taken
95 static_assert(49 > skgpu::kMaxBlurSamples);
96 // All 1s except center value, which is -47 (sum of 1).
97 std::vector<SkScalar> kernel(49, SkIntToScalar(1));
98 kernel[24] = SkIntToScalar(-47);
100 {7,7}, kernel.data(), /* gain= */ 0.3f, /* bias= */ 100.0f,
101 kernelOffset, tileMode, convolveAlpha, nullptr, tileBoundary);
102 }
104 SkIPoint kernelOffset {SkScalarRoundToInt(127*normalizedXOffset), 0};
105 // This ensures the texture fallback path will be taken
106 static_assert(128 > skgpu::kMaxBlurSamples);
107 std::vector<float> kernel(128, 0.0f);
108 kernel[64] = 0.5f;
109 kernel[65] = -0.5f;
111 {128,1}, kernel.data(), /* gain= */ 0.3f, /* bias= */ 100.0f,
112 kernelOffset, tileMode, convolveAlpha, nullptr, tileBoundary);
113 }
115 SkIPoint kernelOffset {0, SkScalarRoundToInt(254*normalizedYOffset)};
116 // This ensures the texture fallback path will be taken
117 static_assert(255 > skgpu::kMaxBlurSamples);
118 std::vector<float> kernel(255, 0.0f);
119 kernel[126] = 0.5f;
120 kernel[128] = -0.5f;
122 {1,255}, kernel.data(), /* gain= */ 0.3f, /* bias= */ 100.0f,
123 kernelOffset, tileMode, convolveAlpha, nullptr, tileBoundary);
124 }
125 default:
126 return nullptr;
127 }
128 }
129
130 void draw(SkCanvas* canvas, int x, int y, const SkIPoint& kernelOffset,
131 SkTileMode tileMode, bool convolveAlpha,
132 const SkIRect* cropRect = nullptr) {
134 auto filter = this->makeFilter(kernelOffset, tileMode, convolveAlpha);
135 if (cropRect) {
136 filter = SkImageFilters::Crop(SkRect::Make(*cropRect), std::move(filter));
137 }
138 paint.setImageFilter(std::move(filter));
139 canvas->save();
141 canvas->drawImage(fImage, 0, 0, {}, &paint);
142 canvas->restore();
143 }
144
145 void onOnceBeforeDraw() override {
146 this->makeBitmap();
147 }
148
149 void onDraw(SkCanvas* canvas) override {
150 canvas->clear(SK_ColorBLACK);
151 SkIPoint kernelOffset = SkIPoint::Make(1, 0);
152 for (int x = 10; x < 310; x += 100) {
153 this->draw(canvas, x, 10, kernelOffset, SkTileMode::kClamp, true);
154 this->draw(canvas, x, 110, kernelOffset, SkTileMode::kDecal, true);
155 this->draw(canvas, x, 210, kernelOffset, SkTileMode::kRepeat, true);
156 kernelOffset.fY++;
157 }
158 kernelOffset.fY = 1;
159 SkIRect smallRect = SkIRect::MakeXYWH(10, 5, 60, 60);
160 this->draw(canvas, 310, 10, kernelOffset, SkTileMode::kClamp, true, &smallRect);
161 this->draw(canvas, 310, 110, kernelOffset, SkTileMode::kDecal, true, &smallRect);
162 this->draw(canvas, 310, 210, kernelOffset, SkTileMode::kRepeat, true, &smallRect);
163
164 this->draw(canvas, 410, 10, kernelOffset, SkTileMode::kClamp, false);
165 this->draw(canvas, 410, 110, kernelOffset, SkTileMode::kDecal, false);
166 this->draw(canvas, 410, 210, kernelOffset, SkTileMode::kRepeat, false);
167 }
168
169private:
170 sk_sp<SkImage> fImage;
171 SkColor fColors[2];
172 const char* fNameSuffix;
173 KernelFixture fKernelFixture;
174
175 using INHERITED = GM;
176};
177
178//////////////////////////////////////////////////////////////////////////////
179
180DEF_GM(return new MatrixConvolutionGM(0xFFFFFFFF, 0x40404040, KernelFixture::kBasic_KernelFixture, "");)
181DEF_GM(return new MatrixConvolutionGM(0xFFFF0000, 0xFF00FF00, KernelFixture::kBasic_KernelFixture, "_color");)
182DEF_GM(return new MatrixConvolutionGM(0xFFFFFFFF, 0x40404040, KernelFixture::kLarge_KernelFixture, "_big");)
183DEF_GM(return new MatrixConvolutionGM(0xFFFF0000, 0xFF00FF00, KernelFixture::kLarge_KernelFixture, "_big_color");)
184DEF_GM(return new MatrixConvolutionGM(0xFFFFFFFF, 0x40404040, KernelFixture::kLarger_KernelFixture, "_bigger");)
185DEF_GM(return new MatrixConvolutionGM(0xFFFFFFFF, 0x40404040, KernelFixture::kLargest_KernelFixture, "_biggest");)
186
187} // namespace skiagm
SkPoint pos
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
#define SkIntToScalar(x)
Definition: SkScalar.h:57
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
SkTileMode
Definition: SkTileMode.h:13
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void clear(SkColor color)
Definition: SkCanvas.h:1199
int save()
Definition: SkCanvas.cpp:447
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
Definition: SkFont.h:35
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static sk_sp< SkImageFilter > MatrixConvolution(const SkISize &kernelSize, const SkScalar kernel[], SkScalar gain, SkScalar bias, const SkIPoint &kernelOffset, SkTileMode tileMode, bool convolveAlpha, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Crop(const SkRect &rect, SkTileMode tileMode, sk_sp< SkImageFilter > input)
SkIRect bounds() const
Definition: SkImage.h:303
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
void setBGColor(SkColor)
Definition: gm.cpp:159
void draw(SkCanvas *canvas, int x, int y, const SkIPoint &kernelOffset, SkTileMode tileMode, bool convolveAlpha, const SkIRect *cropRect=nullptr)
void onDraw(SkCanvas *canvas) override
SkString getName() const override
bool runAsBench() const override
MatrixConvolutionGM(SkColor colorOne, SkColor colorTwo, KernelFixture kernelFixture, const char *nameSuffix)
sk_sp< SkImageFilter > makeFilter(const SkIPoint &kernelOffsetIn, SkTileMode tileMode, bool convolveAlpha)
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
double y
double x
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
sk_sp< SkTypeface > DefaultPortableTypeface()
font
Font Metadata and Metrics.
static constexpr int kMaxBlurSamples
Definition: BlurUtils.h:35
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
@ kLargest_KernelFixture
int32_t fX
x-axis value
Definition: SkPoint_impl.h:29
int32_t fY
y-axis value
Definition: SkPoint_impl.h:30
static constexpr SkIPoint Make(int32_t x, int32_t y)
Definition: SkPoint_impl.h:38
Definition: SkRect.h:32
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkImageInfo MakeN32Premul(int width, int height)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669