Flutter Engine
The Flutter Engine
rasterhandleallocator.cpp
Go to the documentation of this file.
1/*
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 */
7
8#include "gm/gm.h"
15
17protected:
19
20public:
21 GraphicsPort(SkCanvas* canvas) : fCanvas(canvas) {}
22 virtual ~GraphicsPort() {}
23
24 void save() { fCanvas->save(); }
25 void saveLayer(const SkRect& bounds, SkAlpha alpha) {
27 }
28 void restore() { fCanvas->restore(); }
29
30 void translate(float x, float y) { fCanvas->translate(x, y); }
31 void scale(float s) { fCanvas->scale(s, s); }
32 void clip(const SkRect& r) { fCanvas->clipRect(r); }
33
34 void drawOval(const SkRect& r, SkColor c) {
35 SkPaint p;
36 p.setColor(c);
37 fCanvas->drawOval(r, p);
38 }
39
40 virtual void drawRect(const SkRect& r, SkColor c) {
41 SkPaint p;
42 p.setColor(c);
43 fCanvas->drawRect(r, p);
44 }
45
46 SkCanvas* peekCanvas() const { return fCanvas; }
47};
48
50public:
52
53 void drawRect(const SkRect& r, SkColor c) override {
55 canvas->drawRect(r, SkPaint(SkColor4f::FromColor(c)));
56 }
57};
58
60public:
62
63 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
65 if (!surface) {
66 return false;
67 }
68 SkCanvas* canvas = surface->getCanvas();
69 SkPixmap pixmap;
70 canvas->peekPixels(&pixmap);
71
72 rec->fReleaseProc = [](void* pixels, void* ctx){ SkSafeUnref((SkSurface*)ctx); };
73 rec->fReleaseCtx = surface.release();
74 rec->fPixels = pixmap.writable_addr();
75 rec->fRowBytes = pixmap.rowBytes();
76 rec->fHandle = canvas;
77 canvas->save(); // balanced each time updateHandle is called
78 return true;
79 }
80
81 void updateHandle(Handle hndl, const SkMatrix& ctm, const SkIRect& clip) override {
82 SkCanvas* canvas = (SkCanvas*)hndl;
83 canvas->restore();
84 canvas->save();
85 canvas->clipRect(SkRect::Make(clip));
86 canvas->concat(ctm);
87 }
88};
89
90#ifdef SK_BUILD_FOR_MAC
91
93class CGGraphicsPort : public GraphicsPort {
94public:
95 CGGraphicsPort(SkCanvas* canvas) : GraphicsPort(canvas) {}
96
97 void drawRect(const SkRect& r, SkColor c) override {
98 CGContextRef cg = (CGContextRef)fCanvas->accessTopRasterHandle();
99
100 CGColorRef color = CGColorCreateGenericRGB(SkColorGetR(c)/255.f,
101 SkColorGetG(c)/255.f,
102 SkColorGetB(c)/255.f,
103 SkColorGetA(c)/255.f);
104
105 CGContextSetFillColorWithColor(cg, color);
106 CGContextFillRect(cg, CGRectMake(r.x(), r.y(), r.width(), r.height()));
107 }
108};
109
110static CGAffineTransform matrix_to_transform(CGContextRef cg, const SkMatrix& ctm) {
112 matrix.setScale(1, -1);
113 matrix.postTranslate(0, SkIntToScalar(CGBitmapContextGetHeight(cg)));
114 matrix.preConcat(ctm);
115
116 return CGAffineTransformMake(matrix[SkMatrix::kMScaleX],
122}
123
124class CGAllocator : public SkRasterHandleAllocator {
125public:
126 CGAllocator() {}
127
128 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
129 // let CG allocate the pixels
130 CGContextRef cg = SkCreateCGContext(SkPixmap(info, nullptr, 0));
131 if (!cg) {
132 return false;
133 }
134 rec->fReleaseProc = [](void* pixels, void* ctx){ CGContextRelease((CGContextRef)ctx); };
135 rec->fReleaseCtx = cg;
136 rec->fPixels = CGBitmapContextGetData(cg);
137 rec->fRowBytes = CGBitmapContextGetBytesPerRow(cg);
138 rec->fHandle = cg;
139 CGContextSaveGState(cg); // balanced each time updateHandle is called
140 return true;
141 }
142
143 void updateHandle(Handle hndl, const SkMatrix& ctm, const SkIRect& clip) override {
144 CGContextRef cg = (CGContextRef)hndl;
145
146 CGContextRestoreGState(cg);
147 CGContextSaveGState(cg);
148 CGContextClipToRect(cg, CGRectMake(clip.x(), clip.y(), clip.width(), clip.height()));
149 CGContextConcatCTM(cg, matrix_to_transform(cg, ctm));
150 }
151};
152
153using MyPort = CGGraphicsPort;
154using MyAllocator = CGAllocator;
155
156#elif defined(SK_BUILD_FOR_WIN)
157
159
160static RECT toRECT(const SkIRect& r) {
161 return { r.left(), r.top(), r.right(), r.bottom() };
162}
163
164class GDIGraphicsPort : public GraphicsPort {
165public:
166 GDIGraphicsPort(SkCanvas* canvas) : GraphicsPort(canvas) {}
167
168 void drawRect(const SkRect& r, SkColor c) override {
169 HDC hdc = (HDC)fCanvas->accessTopRasterHandle();
170
171 COLORREF cr = RGB(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));// SkEndian_Swap32(c) >> 8;
172 RECT rounded = toRECT(r.round());
173 FillRect(hdc, &rounded, CreateSolidBrush(cr));
174
175 // Assuming GDI wrote zeros for alpha, this will or-in 0xFF for alpha
177 paint.setBlendMode(SkBlendMode::kDstATop);
178 fCanvas->drawRect(r, paint);
179 }
180};
181
182// We use this static factory function instead of the regular constructor so
183// that we can create the pixel data before calling the constructor. This is
184// required so that we can call the base class' constructor with the pixel
185// data.
186static bool Create(int width, int height, bool is_opaque, SkRasterHandleAllocator::Rec* rec) {
187 BITMAPINFOHEADER hdr;
188 memset(&hdr, 0, sizeof(hdr));
189 hdr.biSize = sizeof(BITMAPINFOHEADER);
190 hdr.biWidth = width;
191 hdr.biHeight = -height; // Minus means top-down bitmap.
192 hdr.biPlanes = 1;
193 hdr.biBitCount = 32;
194 hdr.biCompression = BI_RGB; // No compression.
195 hdr.biSizeImage = 0;
196 hdr.biXPelsPerMeter = 1;
197 hdr.biYPelsPerMeter = 1;
198 void* pixels;
199 HBITMAP hbitmap = CreateDIBSection(nullptr, (const BITMAPINFO*)&hdr, 0, &pixels, 0, 0);
200 if (!hbitmap) {
201 return false;
202 }
203
204 size_t row_bytes = width * sizeof(SkPMColor);
205 sk_bzero(pixels, row_bytes * height);
206
207 HDC hdc = CreateCompatibleDC(nullptr);
208 if (!hdc) {
209 DeleteObject(hbitmap);
210 return false;
211 }
212 SetGraphicsMode(hdc, GM_ADVANCED);
213 HGDIOBJ origBitmap = SelectObject(hdc, hbitmap);
214
215 struct ReleaseContext {
216 HDC hdc;
217 HGDIOBJ hbitmap;
218 };
219 rec->fReleaseProc = [](void*, void* context) {
220 ReleaseContext* ctx = static_cast<ReleaseContext*>(context);
221 HBITMAP hbitmap = static_cast<HBITMAP>(SelectObject(ctx->hdc, ctx->hbitmap));
222 DeleteObject(hbitmap);
223 DeleteDC(ctx->hdc);
224 delete ctx;
225 };
226 rec->fReleaseCtx = new ReleaseContext{hdc, origBitmap};
227 rec->fPixels = pixels;
228 rec->fRowBytes = row_bytes;
229 rec->fHandle = hdc;
230 return true;
231}
232
233/**
234* Subclass of SkRasterHandleAllocator that returns an HDC as its "handle".
235*/
236class GDIAllocator : public SkRasterHandleAllocator {
237public:
238 GDIAllocator() {}
239
240 bool allocHandle(const SkImageInfo& info, Rec* rec) override {
241 SkASSERT(info.colorType() == kN32_SkColorType);
242 return Create(info.width(), info.height(), info.isOpaque(), rec);
243 }
244
245 void updateHandle(Handle handle, const SkMatrix& ctm, const SkIRect& clip_bounds) override {
246 HDC hdc = static_cast<HDC>(handle);
247
248 XFORM xf;
249 xf.eM11 = ctm[SkMatrix::kMScaleX];
250 xf.eM21 = ctm[SkMatrix::kMSkewX];
251 xf.eDx = ctm[SkMatrix::kMTransX];
252 xf.eM12 = ctm[SkMatrix::kMSkewY];
253 xf.eM22 = ctm[SkMatrix::kMScaleY];
254 xf.eDy = ctm[SkMatrix::kMTransY];
255 SetWorldTransform(hdc, &xf);
256
257 RECT clip_bounds_RECT = toRECT(clip_bounds);
258 HRGN hrgn = CreateRectRgnIndirect(&clip_bounds_RECT);
259 [[maybe_unused]] int result = SelectClipRgn(hdc, hrgn);
261 result = DeleteObject(hrgn);
262 SkASSERT(result != 0);
263 }
264};
265
266using MyPort = GDIGraphicsPort;
267using MyAllocator = GDIAllocator;
268
269#else
270
273
274#endif
275
276DEF_SIMPLE_GM(rasterallocator, canvas, 600, 300) {
277 auto doDraw = [](GraphicsPort* port) {
278 SkAutoCanvasRestore acr(port->peekCanvas(), true);
279
280 port->drawRect({0, 0, 256, 256}, SK_ColorRED);
281 port->save();
282 port->translate(30, 30);
283 port->drawRect({0, 0, 30, 30}, SK_ColorBLUE);
284 port->drawOval({10, 10, 20, 20}, SK_ColorWHITE);
285 port->restore();
286
287 port->saveLayer({50, 50, 100, 100}, 0x80);
288 port->drawRect({55, 55, 95, 95}, SK_ColorGREEN);
289 port->restore();
290
291 port->clip({150, 50, 200, 200});
292 port->drawRect({0, 0, 256, 256}, 0xFFCCCCCC);
293 };
294
295 // TODO: this common code fails pic-8888 and serialize-8888
296 //GraphicsPort skiaPort(canvas);
297 //doDraw(&skiaPort);
298
300 std::unique_ptr<SkCanvas> nativeCanvas =
301 SkRasterHandleAllocator::MakeCanvas(std::make_unique<MyAllocator>(), info);
302 MyPort nativePort(nativeCanvas.get());
303 doDraw(&nativePort);
304
305 SkPixmap pm;
306 nativeCanvas->peekPixels(&pm);
307 canvas->drawImage(SkImages::RasterFromPixmapCopy(pm), 280, 0);
308}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
sk_bzero(glyphs, sizeof(glyphs))
static sk_sp< Effect > Create()
Definition: RefCntTest.cpp:117
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kDstATop
r = d*sa + s*(1-da)
#define SkColorGetR(color)
Definition: SkColor.h:65
#define SkColorGetG(color)
Definition: SkColor.h:69
uint32_t SkColor
Definition: SkColor.h:37
uint8_t SkAlpha
Definition: SkColor.h:26
uint32_t SkPMColor
Definition: SkColor.h:205
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
#define SkColorGetA(color)
Definition: SkColor.h:61
#define SkColorGetB(color)
Definition: SkColor.h:73
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
static void SkSafeUnref(T *obj)
Definition: SkRefCnt.h:149
#define SkIntToScalar(x)
Definition: SkScalar.h:57
void drawOval(const SkRect &r, SkColor c)
void translate(float x, float y)
void saveLayer(const SkRect &bounds, SkAlpha alpha)
SkCanvas * peekCanvas() const
virtual void drawRect(const SkRect &r, SkColor c)
void clip(const SkRect &r)
GraphicsPort(SkCanvas *canvas)
SkRasterHandleAllocator::Handle accessTopRasterHandle() const
Definition: SkCanvas.cpp:2841
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void drawOval(const SkRect &oval, const SkPaint &paint)
Definition: SkCanvas.cpp:1698
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
bool peekPixels(SkPixmap *pixmap)
Definition: SkCanvas.cpp:1237
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int saveLayerAlpha(const SkRect *bounds, U8CPU alpha)
Definition: SkCanvas.h:661
int save()
Definition: SkCanvas.cpp:447
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
static constexpr int kMScaleX
horizontal scale factor
Definition: SkMatrix.h:353
static constexpr int kMTransY
vertical translation
Definition: SkMatrix.h:358
static constexpr int kMTransX
horizontal translation
Definition: SkMatrix.h:355
static constexpr int kMSkewY
vertical skew factor
Definition: SkMatrix.h:356
static constexpr int kMScaleY
vertical scale factor
Definition: SkMatrix.h:357
static constexpr int kMSkewX
horizontal skew factor
Definition: SkMatrix.h:354
size_t rowBytes() const
Definition: SkPixmap.h:145
void * writable_addr() const
Definition: SkPixmap.h:483
static std::unique_ptr< SkCanvas > MakeCanvas(std::unique_ptr< SkRasterHandleAllocator >, const SkImageInfo &, const Rec *rec=nullptr, const SkSurfaceProps *props=nullptr)
Definition: SkCanvas.cpp:2871
virtual void updateHandle(Handle, const SkMatrix &, const SkIRect &)=0
virtual bool allocHandle(const SkImageInfo &, Rec *)=0
void updateHandle(Handle hndl, const SkMatrix &ctm, const SkIRect &clip) override
bool allocHandle(const SkImageInfo &info, Rec *rec) override
SkiaGraphicsPort(SkCanvas *canvas)
void drawRect(const SkRect &r, SkColor c) override
const Paint & paint
Definition: color_source.cc:38
DlColor color
VkSurfaceKHR surface
Definition: main.cc:49
struct MyStruct s
GAsyncResult * result
double y
double x
SK_API sk_sp< SkImage > RasterFromPixmapCopy(const SkPixmap &pixmap)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
void * ReleaseContext
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
DEF_SIMPLE_GM(rasterallocator, canvas, 600, 300)
int32_t height
int32_t width
Definition: SkRect.h:32
constexpr int32_t top() const
Definition: SkRect.h:120
constexpr int32_t bottom() const
Definition: SkRect.h:134
constexpr int32_t right() const
Definition: SkRect.h:127
constexpr int32_t left() const
Definition: SkRect.h:113
static SkImageInfo MakeN32Premul(int width, int height)
void(* fReleaseProc)(void *pixels, void *ctx)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
constexpr float x() const
Definition: SkRect.h:720
constexpr float y() const
Definition: SkRect.h:727
void round(SkIRect *dst) const
Definition: SkRect.h:1228
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
#define ERROR(message)
Definition: elf_loader.cc:260