Flutter Engine
The Flutter Engine
nearesthalfpixelimage.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 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"
15
16/**
17 * Tests drawing images are half pixel offsets in device space with nearest filtering to show how
18 * rasterization and image sample snapping at boundary points interact. Both drawImage and drawRect
19 * with an image shader are tested. Scale factors 1 and -1 are tested. The images are all two pixels
20 * wide or tall so we either get both values once each or one value repeated twice.
21 */
22DEF_SIMPLE_GM_CAN_FAIL(nearest_half_pixel_image, canvas, errorMsg, 264, 235) {
23 // We don't run this test on the GPU because we're at the driver/hw's mercy for how this
24 // is handled.
25 if (canvas->recordingContext() || (canvas->getSurface() && canvas->getSurface()->recorder())) {
26 *errorMsg = "Test is only relevant to CPU backend";
28 }
29
30 // We make 2x1 and 1x2 images for each color type.
31 struct Images {
32 sk_sp<SkImage> imageX;
33 sk_sp<SkImage> imageY;
34 };
35
36 Images images[2];
37 uint32_t colors[] {0xFFFF0000, 0xFF0000FF};
38 SkPixmap cpmx(SkImageInfo::Make({2, 1},
41 colors,
42 sizeof(colors));
43 SkPixmap cpmy(SkImageInfo::Make({1, 2},
46 colors,
47 sizeof(colors[0]));
49
50 uint8_t alphas[] {0xFF, 0xAA};
51 SkPixmap apmx(SkImageInfo::Make({2, 1},
54 alphas,
55 sizeof(alphas));
56 SkPixmap apmy(SkImageInfo::Make({1, 2},
59 alphas,
60 sizeof(alphas[0]));
62
63 // We draw offscreen and then zoom that up to make the result clear.
64 auto surf = canvas->makeSurface(canvas->imageInfo().makeWH(80, 80));
65 if (!surf) {
66 *errorMsg = "Test only works with SkSurface backed canvases";
68 }
69 auto* c = surf->getCanvas();
70 c->clear(SK_ColorWHITE);
71
72 // We scale up in the direction not being tested, the one with image dimension of 1, to make the
73 // result more easily visible.
74 static const float kOffAxisScale = 4;
75
76 auto draw = [&](sk_sp<SkImage> image, bool shader, bool doX, bool mirror, uint8_t alpha) {
77 c->save();
79 paint.setAlpha(alpha);
80 if (shader) {
82 }
83 if (doX) {
84 c->scale(mirror ? -1 : 1, kOffAxisScale);
85 c->translate(mirror ? -2.5 : 0.5, 0);
86 } else {
87 c->scale(kOffAxisScale, mirror ? -1 : 1);
88 c->translate(0, mirror ? -2.5 : 0.5);
89 }
90
91 if (shader) {
92 c->drawRect(SkRect::Make(image->dimensions()), paint);
93 } else {
94 c->drawImage(image, 0, 0, SkFilterMode::kNearest, &paint);
95 }
96 c->restore();
97 };
98
99 for (bool shader : {false, true})
100 for (uint8_t alpha : {0xFF , 0x70}) {
101 c->save();
102 for (const auto& i : images)
103 for (auto mirror : {false, true}) {
104 draw(i.imageX, shader, /*doX=*/true, mirror, alpha);
105 c->save();
106 c->translate(4, 0);
107 draw(i.imageY, shader, /*doX=*/false, mirror, alpha);
108 c->restore();
109 c->translate(0, kOffAxisScale*2);
110 }
111 c->restore();
112 c->translate(kOffAxisScale*2, 0);
113 }
114 canvas->scale(8, 8);
115 canvas->drawImage(surf->makeImageSnapshot(), 0, 0);
116
118}
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
static unsigned mirror(SkFixed fx, int max)
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
SkISize dimensions() const
Definition: SkImage.h:297
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkImage.cpp:179
const Paint & paint
Definition: color_source.cc:38
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
SK_API sk_sp< SkImage > RasterFromPixmapCopy(const SkPixmap &pixmap)
sk_sp< const SkImage > image
Definition: SkRecords.h:269
PODArray< SkColor > colors
Definition: SkRecords.h:276
DEF_SIMPLE_GM_CAN_FAIL(nearest_half_pixel_image, canvas, errorMsg, 264, 235)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669