blob: 8c7113d5d07550945d5cc17a6c376757a3e86442 [file] [log] [blame]
John Reck013127b2020-10-29 20:53:51 -04001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <SkAndroidFrameworkUtils.h>
20#include <SkCanvas.h>
21#include <SkPath.h>
Nader Jawadfb1e7f12020-11-06 22:49:42 -080022#include <SkRegion.h>
23#include <SkVertices.h>
Nader Jawadda9248c2020-11-09 17:27:36 -080024#include <SkImage.h>
25#include <SkPicture.h>
26#include <hwui/Bitmap.h>
John Reck013127b2020-10-29 20:53:51 -040027#include <log/log.h>
Nader Jawadde3ce842020-11-06 16:54:48 -080028#include "CanvasProperty.h"
John Reck013127b2020-10-29 20:53:51 -040029
30#include "CanvasOpTypes.h"
31
32#include <experimental/type_traits>
Nader Jawadda9248c2020-11-09 17:27:36 -080033#include <utility>
John Reck013127b2020-10-29 20:53:51 -040034
35namespace android::uirenderer {
36
37template <CanvasOpType T>
38struct CanvasOp;
39
40struct CanvasOpTraits {
41 CanvasOpTraits() = delete;
42
43 template<class T>
44 using draw_t = decltype(std::integral_constant<void (T::*)(SkCanvas*) const, &T::draw>{});
45
46 template <class T>
47 static constexpr bool can_draw = std::experimental::is_detected_v<draw_t, T>;
48};
49
50#define ASSERT_DRAWABLE() private: constexpr void _check_drawable() \
51 { static_assert(CanvasOpTraits::can_draw<std::decay_t<decltype(*this)>>); }
52
53// ----------------------------------------------
54// State Ops
55// ---------------------------------------------
56
57template <>
58struct CanvasOp<CanvasOpType::Save> {
59 void draw(SkCanvas* canvas) const { canvas->save(); }
60 ASSERT_DRAWABLE()
61};
62
63template <>
64struct CanvasOp<CanvasOpType::SaveLayer> {
65 SkCanvas::SaveLayerRec saveLayerRec;
66 void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
67 ASSERT_DRAWABLE()
68};
69
70template <>
71struct CanvasOp<CanvasOpType::SaveBehind> {
72 SkRect bounds;
73 void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
74 ASSERT_DRAWABLE()
75};
76
77template <>
78struct CanvasOp<CanvasOpType::Restore> {
79 void draw(SkCanvas* canvas) const { canvas->restore(); }
80 ASSERT_DRAWABLE()
81};
82
83template <>
84struct CanvasOp<CanvasOpType::BeginZ> {
85};
86template <>
87struct CanvasOp<CanvasOpType::EndZ> {};
88
89// ----------------------------------------------
90// Clip Ops
91// ---------------------------------------------
92
93template <>
94struct CanvasOp<CanvasOpType::ClipRect> {
95 SkRect rect;
96 SkClipOp clipOp;
97 void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
98 ASSERT_DRAWABLE()
99};
100
101template <>
102struct CanvasOp<CanvasOpType::ClipPath> {
103 SkPath path;
104 SkClipOp op;
105 void draw(SkCanvas* canvas) const { canvas->clipPath(path, op, true); }
106 ASSERT_DRAWABLE()
107};
108
109// ----------------------------------------------
110// Drawing Ops
111// ---------------------------------------------
112
Nader Jawadde3ce842020-11-06 16:54:48 -0800113template<>
114struct CanvasOp<CanvasOpType::DrawRoundRectProperty> {
115 sp<uirenderer::CanvasPropertyPrimitive> left;
116 sp<uirenderer::CanvasPropertyPrimitive> top;
117 sp<uirenderer::CanvasPropertyPrimitive> right;
118 sp<uirenderer::CanvasPropertyPrimitive> bottom;
119 sp<uirenderer::CanvasPropertyPrimitive> rx;
120 sp<uirenderer::CanvasPropertyPrimitive> ry;
121 sp<uirenderer::CanvasPropertyPaint> paint;
122
123 void draw(SkCanvas* canvas) const {
124 SkRect rect = SkRect::MakeLTRB(left->value, top->value, right->value, bottom->value);
125 canvas->drawRoundRect(rect, rx->value, ry->value, paint->value);
126 }
127 ASSERT_DRAWABLE()
128};
129
130template<>
131struct CanvasOp<CanvasOpType::DrawCircleProperty> {
132 sp<uirenderer::CanvasPropertyPrimitive> x;
133 sp<uirenderer::CanvasPropertyPrimitive> y;
134 sp<uirenderer::CanvasPropertyPrimitive> radius;
135 sp<uirenderer::CanvasPropertyPaint> paint;
136
137 void draw(SkCanvas* canvas) const {
138 canvas->drawCircle(x->value, y->value, radius->value, paint->value);
139 }
140 ASSERT_DRAWABLE()
141};
142
John Reck013127b2020-10-29 20:53:51 -0400143template <>
144struct CanvasOp<CanvasOpType::DrawColor> {
145 SkColor4f color;
146 SkBlendMode mode;
147 void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
148 ASSERT_DRAWABLE()
149};
150
151template <>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800152struct CanvasOp<CanvasOpType::DrawPaint> {
153 SkPaint paint;
154 void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
155 ASSERT_DRAWABLE()
156};
157
158template <>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800159struct CanvasOp<CanvasOpType::DrawPoint> {
160 float x;
161 float y;
162 SkPaint paint;
163 void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); }
164 ASSERT_DRAWABLE()
165};
166
167template <>
John Reck013127b2020-10-29 20:53:51 -0400168struct CanvasOp<CanvasOpType::DrawRect> {
169 SkRect rect;
170 SkPaint paint;
171 void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
172 ASSERT_DRAWABLE()
173};
174
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800175template <>
176struct CanvasOp<CanvasOpType::DrawRegion> {
177 SkRegion region;
178 SkPaint paint;
179 void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
180 ASSERT_DRAWABLE()
181};
182
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800183template<>
184struct CanvasOp<CanvasOpType::DrawRoundRect> {
185 SkRect rect;
186 SkScalar rx;
187 SkScalar ry;
188 SkPaint paint;
189 void draw(SkCanvas* canvas) const {
190 canvas->drawRoundRect(rect, rx, ry, paint);
191 }
192 ASSERT_DRAWABLE()
193};
194
195template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800196struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> {
197 SkRRect outer;
198 SkRRect inner;
199 SkPaint paint;
200 void draw(SkCanvas* canvas) const {
201 canvas->drawDRRect(outer, inner, paint);
202 }
203 ASSERT_DRAWABLE()
204};
205
206template<>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800207struct CanvasOp<CanvasOpType::DrawCircle> {
208 SkScalar cx;
209 SkScalar cy;
210 SkScalar radius;
211 SkPaint paint;
212 void draw(SkCanvas* canvas) const {
213 canvas->drawCircle(cx, cy, radius, paint);
214 }
215 ASSERT_DRAWABLE()
216};
217
218template<>
219struct CanvasOp<CanvasOpType::DrawOval> {
220 SkRect oval;
221 SkPaint paint;
222 void draw(SkCanvas* canvas) const {
223 canvas->drawOval(oval, paint);
224 }
225 ASSERT_DRAWABLE()
226};
227
228template<>
229struct CanvasOp<CanvasOpType::DrawArc> {
230 SkRect oval;
231 SkScalar startAngle;
232 SkScalar sweepAngle;
233 bool useCenter;
234 SkPaint paint;
235
236 void draw(SkCanvas* canvas) const {
237 canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
238 }
239 ASSERT_DRAWABLE()
240};
John Reck013127b2020-10-29 20:53:51 -0400241
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800242template<>
243struct CanvasOp<CanvasOpType::DrawPath> {
244 SkPath path;
245 SkPaint paint;
246
247 void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); }
248 ASSERT_DRAWABLE()
249};
250
251template<>
252struct CanvasOp<CanvasOpType::DrawLine> {
253 float startX;
254 float startY;
255 float endX;
256 float endY;
257 SkPaint paint;
258
259 void draw(SkCanvas* canvas) const {
260 canvas->drawLine(startX, startY, endX, endY, paint);
261 }
262 ASSERT_DRAWABLE()
263};
264
265template<>
266struct CanvasOp<CanvasOpType::DrawVertices> {
267 sk_sp<SkVertices> vertices;
268 SkBlendMode mode;
269 SkPaint paint;
270 void draw(SkCanvas* canvas) const {
271 canvas->drawVertices(vertices, mode, paint);
272 }
273 ASSERT_DRAWABLE()
274};
275
Nader Jawadda9248c2020-11-09 17:27:36 -0800276template<>
277struct CanvasOp<CanvasOpType::DrawImage> {
278
279 CanvasOp<CanvasOpType::DrawImageRect>(
280 const sk_sp<Bitmap>& bitmap,
281 float left,
282 float top,
283 SkPaint paint
284 ) : left(left),
285 top(top),
286 paint(std::move(paint)),
287 bitmap(bitmap),
288 image(bitmap->makeImage()) { }
289
290 float left;
291 float top;
292 SkPaint paint;
293 sk_sp<Bitmap> bitmap;
294 sk_sp<SkImage> image;
295
296 void draw(SkCanvas* canvas) const {
297 canvas->drawImage(image, left, top, &paint);
298 }
299 ASSERT_DRAWABLE()
300};
301
302template<>
303struct CanvasOp<CanvasOpType::DrawImageRect> {
304
305 CanvasOp<CanvasOpType::DrawImageRect>(
306 const sk_sp<Bitmap>& bitmap,
307 SkRect src,
308 SkRect dst,
309 SkPaint paint
310 ) : src(src),
311 dst(dst),
312 paint(std::move(paint)),
313 bitmap(bitmap),
314 image(bitmap->makeImage()) { }
315
316 SkRect src;
317 SkRect dst;
318 SkPaint paint;
319 sk_sp<Bitmap> bitmap;
320 sk_sp<SkImage> image;
321
322 void draw(SkCanvas* canvas) const {
323 canvas->drawImageRect(image,
324 src,
325 dst,
326 &paint,
327 SkCanvas::kFast_SrcRectConstraint
328 );
329 }
330 ASSERT_DRAWABLE()
331};
332
333template<>
334struct CanvasOp<CanvasOpType::DrawImageLattice> {
335
336 CanvasOp<CanvasOpType::DrawImageLattice>(
337 const sk_sp<Bitmap>& bitmap,
338 SkRect dst,
339 SkCanvas::Lattice lattice,
340 SkPaint paint
341 ): dst(dst),
342 lattice(lattice),
343 bitmap(bitmap),
344 image(bitmap->makeImage()),
345 paint(std::move(paint)) {}
346
347 SkRect dst;
348 SkCanvas::Lattice lattice;
349 const sk_sp<Bitmap> bitmap;
350 const sk_sp<SkImage> image;
351
352 SkPaint paint;
353 void draw(SkCanvas* canvas) const {
354 canvas->drawImageLattice(image.get(), lattice, dst, &paint);
355 }
356 ASSERT_DRAWABLE()
357};
358
359template<>
360struct CanvasOp<CanvasOpType::DrawPicture> {
361 sk_sp<SkPicture> picture;
362 void draw(SkCanvas* canvas) const {
363 picture->playback(canvas);
364 }
365};
366
John Reck013127b2020-10-29 20:53:51 -0400367// cleanup our macros
368#undef ASSERT_DRAWABLE
369
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800370} // namespace android::uirenderer