blob: fdc97a4fd8ba7a08c7e2857b24bcb79d96223c97 [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>
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -050026#include <SkRuntimeEffect.h>
John Reck013127b2020-10-29 20:53:51 -040027
John Reck064650b2021-01-19 21:29:24 -050028#include <log/log.h>
29
30#include "hwui/Bitmap.h"
31#include "CanvasProperty.h"
John Reck013127b2020-10-29 20:53:51 -040032#include "CanvasOpTypes.h"
Nader Jawad55f19762020-11-25 15:30:20 -080033#include "Layer.h"
John Reck064650b2021-01-19 21:29:24 -050034#include "Points.h"
35#include "RenderNode.h"
John Reck013127b2020-10-29 20:53:51 -040036
37#include <experimental/type_traits>
Nader Jawadda9248c2020-11-09 17:27:36 -080038#include <utility>
John Reck013127b2020-10-29 20:53:51 -040039
40namespace android::uirenderer {
41
42template <CanvasOpType T>
43struct CanvasOp;
44
45struct CanvasOpTraits {
46 CanvasOpTraits() = delete;
47
48 template<class T>
49 using draw_t = decltype(std::integral_constant<void (T::*)(SkCanvas*) const, &T::draw>{});
50
51 template <class T>
52 static constexpr bool can_draw = std::experimental::is_detected_v<draw_t, T>;
53};
54
55#define ASSERT_DRAWABLE() private: constexpr void _check_drawable() \
56 { static_assert(CanvasOpTraits::can_draw<std::decay_t<decltype(*this)>>); }
57
58// ----------------------------------------------
59// State Ops
60// ---------------------------------------------
61
62template <>
63struct CanvasOp<CanvasOpType::Save> {
64 void draw(SkCanvas* canvas) const { canvas->save(); }
65 ASSERT_DRAWABLE()
66};
67
68template <>
69struct CanvasOp<CanvasOpType::SaveLayer> {
70 SkCanvas::SaveLayerRec saveLayerRec;
71 void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
72 ASSERT_DRAWABLE()
73};
74
75template <>
76struct CanvasOp<CanvasOpType::SaveBehind> {
77 SkRect bounds;
78 void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
79 ASSERT_DRAWABLE()
80};
81
82template <>
83struct CanvasOp<CanvasOpType::Restore> {
84 void draw(SkCanvas* canvas) const { canvas->restore(); }
85 ASSERT_DRAWABLE()
86};
87
88template <>
89struct CanvasOp<CanvasOpType::BeginZ> {
90};
91template <>
92struct CanvasOp<CanvasOpType::EndZ> {};
93
94// ----------------------------------------------
95// Clip Ops
96// ---------------------------------------------
97
98template <>
99struct CanvasOp<CanvasOpType::ClipRect> {
100 SkRect rect;
101 SkClipOp clipOp;
102 void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
103 ASSERT_DRAWABLE()
104};
105
106template <>
107struct CanvasOp<CanvasOpType::ClipPath> {
108 SkPath path;
109 SkClipOp op;
110 void draw(SkCanvas* canvas) const { canvas->clipPath(path, op, true); }
111 ASSERT_DRAWABLE()
112};
113
114// ----------------------------------------------
115// Drawing Ops
116// ---------------------------------------------
117
Nader Jawadde3ce842020-11-06 16:54:48 -0800118template<>
119struct CanvasOp<CanvasOpType::DrawRoundRectProperty> {
120 sp<uirenderer::CanvasPropertyPrimitive> left;
121 sp<uirenderer::CanvasPropertyPrimitive> top;
122 sp<uirenderer::CanvasPropertyPrimitive> right;
123 sp<uirenderer::CanvasPropertyPrimitive> bottom;
124 sp<uirenderer::CanvasPropertyPrimitive> rx;
125 sp<uirenderer::CanvasPropertyPrimitive> ry;
126 sp<uirenderer::CanvasPropertyPaint> paint;
127
128 void draw(SkCanvas* canvas) const {
129 SkRect rect = SkRect::MakeLTRB(left->value, top->value, right->value, bottom->value);
130 canvas->drawRoundRect(rect, rx->value, ry->value, paint->value);
131 }
132 ASSERT_DRAWABLE()
133};
134
135template<>
136struct CanvasOp<CanvasOpType::DrawCircleProperty> {
137 sp<uirenderer::CanvasPropertyPrimitive> x;
138 sp<uirenderer::CanvasPropertyPrimitive> y;
139 sp<uirenderer::CanvasPropertyPrimitive> radius;
140 sp<uirenderer::CanvasPropertyPaint> paint;
141
142 void draw(SkCanvas* canvas) const {
143 canvas->drawCircle(x->value, y->value, radius->value, paint->value);
144 }
145 ASSERT_DRAWABLE()
146};
147
Lucas Dupin00af5272021-04-29 20:30:01 -0700148template <>
149struct CanvasOp<CanvasOpType::DrawRippleDrawable> {
150 skiapipeline::RippleDrawableParams params;
Lucas Dupin6d1601a2021-04-15 08:39:50 -0700151
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -0500152 void draw(SkCanvas* canvas) const {
Lucas Dupin00af5272021-04-29 20:30:01 -0700153 skiapipeline::AnimatedRippleDrawable::draw(canvas, params);
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -0500154 }
155 ASSERT_DRAWABLE()
156};
157
John Reck013127b2020-10-29 20:53:51 -0400158template <>
159struct CanvasOp<CanvasOpType::DrawColor> {
160 SkColor4f color;
161 SkBlendMode mode;
162 void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
163 ASSERT_DRAWABLE()
164};
165
166template <>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800167struct CanvasOp<CanvasOpType::DrawPaint> {
168 SkPaint paint;
169 void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
170 ASSERT_DRAWABLE()
171};
172
173template <>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800174struct CanvasOp<CanvasOpType::DrawPoint> {
175 float x;
176 float y;
177 SkPaint paint;
178 void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); }
179 ASSERT_DRAWABLE()
180};
181
182template <>
Nader Jawad4285c8a2020-11-06 22:49:42 -0800183struct CanvasOp<CanvasOpType::DrawPoints> {
184 size_t count;
185 SkPaint paint;
186 sk_sp<Points> points;
187 void draw(SkCanvas* canvas) const {
188 canvas->drawPoints(
189 SkCanvas::kPoints_PointMode,
190 count,
191 points->data(),
192 paint
193 );
194 }
195 ASSERT_DRAWABLE()
196};
197
198template <>
John Reck013127b2020-10-29 20:53:51 -0400199struct CanvasOp<CanvasOpType::DrawRect> {
200 SkRect rect;
201 SkPaint paint;
202 void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
203 ASSERT_DRAWABLE()
204};
205
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800206template <>
207struct CanvasOp<CanvasOpType::DrawRegion> {
208 SkRegion region;
209 SkPaint paint;
210 void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
211 ASSERT_DRAWABLE()
212};
213
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800214template<>
215struct CanvasOp<CanvasOpType::DrawRoundRect> {
216 SkRect rect;
217 SkScalar rx;
218 SkScalar ry;
219 SkPaint paint;
220 void draw(SkCanvas* canvas) const {
221 canvas->drawRoundRect(rect, rx, ry, paint);
222 }
223 ASSERT_DRAWABLE()
224};
225
226template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800227struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> {
228 SkRRect outer;
229 SkRRect inner;
230 SkPaint paint;
231 void draw(SkCanvas* canvas) const {
232 canvas->drawDRRect(outer, inner, paint);
233 }
234 ASSERT_DRAWABLE()
235};
236
237template<>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800238struct CanvasOp<CanvasOpType::DrawCircle> {
239 SkScalar cx;
240 SkScalar cy;
241 SkScalar radius;
242 SkPaint paint;
243 void draw(SkCanvas* canvas) const {
244 canvas->drawCircle(cx, cy, radius, paint);
245 }
246 ASSERT_DRAWABLE()
247};
248
249template<>
250struct CanvasOp<CanvasOpType::DrawOval> {
251 SkRect oval;
252 SkPaint paint;
253 void draw(SkCanvas* canvas) const {
254 canvas->drawOval(oval, paint);
255 }
256 ASSERT_DRAWABLE()
257};
258
259template<>
260struct CanvasOp<CanvasOpType::DrawArc> {
261 SkRect oval;
262 SkScalar startAngle;
263 SkScalar sweepAngle;
264 bool useCenter;
265 SkPaint paint;
266
267 void draw(SkCanvas* canvas) const {
268 canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
269 }
270 ASSERT_DRAWABLE()
271};
John Reck013127b2020-10-29 20:53:51 -0400272
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800273template<>
274struct CanvasOp<CanvasOpType::DrawPath> {
275 SkPath path;
276 SkPaint paint;
277
278 void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); }
279 ASSERT_DRAWABLE()
280};
281
282template<>
283struct CanvasOp<CanvasOpType::DrawLine> {
284 float startX;
285 float startY;
286 float endX;
287 float endY;
288 SkPaint paint;
289
290 void draw(SkCanvas* canvas) const {
291 canvas->drawLine(startX, startY, endX, endY, paint);
292 }
293 ASSERT_DRAWABLE()
294};
295
296template<>
Nader Jawad4285c8a2020-11-06 22:49:42 -0800297struct CanvasOp<CanvasOpType::DrawLines> {
298 size_t count;
299 SkPaint paint;
300 sk_sp<Points> points;
301 void draw(SkCanvas* canvas) const {
302 canvas->drawPoints(
303 SkCanvas::kLines_PointMode,
304 count,
305 points->data(),
306 paint
307 );
308 }
309 ASSERT_DRAWABLE()
310};
311
312template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800313struct CanvasOp<CanvasOpType::DrawVertices> {
314 sk_sp<SkVertices> vertices;
315 SkBlendMode mode;
316 SkPaint paint;
317 void draw(SkCanvas* canvas) const {
318 canvas->drawVertices(vertices, mode, paint);
319 }
320 ASSERT_DRAWABLE()
321};
322
Nader Jawadda9248c2020-11-09 17:27:36 -0800323template<>
324struct CanvasOp<CanvasOpType::DrawImage> {
325
John Reckb5eeb182020-12-09 13:45:39 -0500326 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800327 const sk_sp<Bitmap>& bitmap,
328 float left,
329 float top,
Mike Reed7994a312021-01-28 18:06:26 -0500330 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800331 SkPaint paint
332 ) : left(left),
333 top(top),
Mike Reed7994a312021-01-28 18:06:26 -0500334 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800335 paint(std::move(paint)),
336 bitmap(bitmap),
337 image(bitmap->makeImage()) { }
338
339 float left;
340 float top;
Mike Reed7994a312021-01-28 18:06:26 -0500341 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800342 SkPaint paint;
343 sk_sp<Bitmap> bitmap;
344 sk_sp<SkImage> image;
345
346 void draw(SkCanvas* canvas) const {
Mike Reed7994a312021-01-28 18:06:26 -0500347 canvas->drawImage(image, left, top, SkSamplingOptions(filter), &paint);
Nader Jawadda9248c2020-11-09 17:27:36 -0800348 }
349 ASSERT_DRAWABLE()
350};
351
352template<>
353struct CanvasOp<CanvasOpType::DrawImageRect> {
354
John Reckb5eeb182020-12-09 13:45:39 -0500355 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800356 const sk_sp<Bitmap>& bitmap,
357 SkRect src,
358 SkRect dst,
Mike Reed7994a312021-01-28 18:06:26 -0500359 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800360 SkPaint paint
361 ) : src(src),
362 dst(dst),
Mike Reed7994a312021-01-28 18:06:26 -0500363 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800364 paint(std::move(paint)),
365 bitmap(bitmap),
366 image(bitmap->makeImage()) { }
367
368 SkRect src;
369 SkRect dst;
Mike Reed7994a312021-01-28 18:06:26 -0500370 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800371 SkPaint paint;
372 sk_sp<Bitmap> bitmap;
373 sk_sp<SkImage> image;
374
375 void draw(SkCanvas* canvas) const {
376 canvas->drawImageRect(image,
377 src,
378 dst,
Mike Reed7994a312021-01-28 18:06:26 -0500379 SkSamplingOptions(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800380 &paint,
381 SkCanvas::kFast_SrcRectConstraint
382 );
383 }
384 ASSERT_DRAWABLE()
385};
386
387template<>
388struct CanvasOp<CanvasOpType::DrawImageLattice> {
389
John Reckb5eeb182020-12-09 13:45:39 -0500390 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800391 const sk_sp<Bitmap>& bitmap,
392 SkRect dst,
393 SkCanvas::Lattice lattice,
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500394 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800395 SkPaint paint
396 ): dst(dst),
397 lattice(lattice),
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500398 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800399 bitmap(bitmap),
400 image(bitmap->makeImage()),
401 paint(std::move(paint)) {}
402
403 SkRect dst;
404 SkCanvas::Lattice lattice;
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500405 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800406 const sk_sp<Bitmap> bitmap;
407 const sk_sp<SkImage> image;
408
409 SkPaint paint;
410 void draw(SkCanvas* canvas) const {
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500411 canvas->drawImageLattice(image.get(), lattice, dst, filter, &paint);
Nader Jawadda9248c2020-11-09 17:27:36 -0800412 }
413 ASSERT_DRAWABLE()
414};
415
416template<>
417struct CanvasOp<CanvasOpType::DrawPicture> {
418 sk_sp<SkPicture> picture;
419 void draw(SkCanvas* canvas) const {
420 picture->playback(canvas);
421 }
422};
423
Nader Jawad55f19762020-11-25 15:30:20 -0800424template<>
425struct CanvasOp<CanvasOpType::DrawLayer> {
426 sp<Layer> layer;
427};
428
John Reck064650b2021-01-19 21:29:24 -0500429template<>
430struct CanvasOp<CanvasOpType::DrawRenderNode> {
431 sp<RenderNode> renderNode;
432};
433
John Reck013127b2020-10-29 20:53:51 -0400434// cleanup our macros
435#undef ASSERT_DRAWABLE
436
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800437} // namespace android::uirenderer