blob: 855cd0d6436bfd0ce27171570159ba29ed0e5216 [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
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -0500148template<>
149struct CanvasOp<CanvasOpType::DrawRippleProperty> {
150 sp<uirenderer::CanvasPropertyPrimitive> x;
151 sp<uirenderer::CanvasPropertyPrimitive> y;
152 sp<uirenderer::CanvasPropertyPrimitive> radius;
153 sp<uirenderer::CanvasPropertyPaint> paint;
154 sp<uirenderer::CanvasPropertyPrimitive> progress;
155 sk_sp<SkRuntimeEffect> effect;
156
157 void draw(SkCanvas* canvas) const {
158 SkRuntimeShaderBuilder runtimeEffectBuilder(effect);
159
160 SkRuntimeShaderBuilder::BuilderUniform center = runtimeEffectBuilder.uniform("in_origin");
161 if (center.fVar != nullptr) {
162 center = SkV2{x->value, y->value};
163 }
164
165 SkRuntimeShaderBuilder::BuilderUniform radiusU =
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500166 runtimeEffectBuilder.uniform("in_radius");
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -0500167 if (radiusU.fVar != nullptr) {
168 radiusU = radius->value;
169 }
170
171 SkRuntimeShaderBuilder::BuilderUniform progressU =
172 runtimeEffectBuilder.uniform("in_progress");
173 if (progressU.fVar != nullptr) {
174 progressU = progress->value;
175 }
176
177 SkPaint paintMod = paint->value;
178 paintMod.setShader(runtimeEffectBuilder.makeShader(nullptr, false));
179 canvas->drawCircle(x->value, y->value, radius->value, paintMod);
180 }
181 ASSERT_DRAWABLE()
182};
183
John Reck013127b2020-10-29 20:53:51 -0400184template <>
185struct CanvasOp<CanvasOpType::DrawColor> {
186 SkColor4f color;
187 SkBlendMode mode;
188 void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
189 ASSERT_DRAWABLE()
190};
191
192template <>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800193struct CanvasOp<CanvasOpType::DrawPaint> {
194 SkPaint paint;
195 void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
196 ASSERT_DRAWABLE()
197};
198
199template <>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800200struct CanvasOp<CanvasOpType::DrawPoint> {
201 float x;
202 float y;
203 SkPaint paint;
204 void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); }
205 ASSERT_DRAWABLE()
206};
207
208template <>
Nader Jawad4285c8a2020-11-06 22:49:42 -0800209struct CanvasOp<CanvasOpType::DrawPoints> {
210 size_t count;
211 SkPaint paint;
212 sk_sp<Points> points;
213 void draw(SkCanvas* canvas) const {
214 canvas->drawPoints(
215 SkCanvas::kPoints_PointMode,
216 count,
217 points->data(),
218 paint
219 );
220 }
221 ASSERT_DRAWABLE()
222};
223
224template <>
John Reck013127b2020-10-29 20:53:51 -0400225struct CanvasOp<CanvasOpType::DrawRect> {
226 SkRect rect;
227 SkPaint paint;
228 void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
229 ASSERT_DRAWABLE()
230};
231
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800232template <>
233struct CanvasOp<CanvasOpType::DrawRegion> {
234 SkRegion region;
235 SkPaint paint;
236 void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
237 ASSERT_DRAWABLE()
238};
239
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800240template<>
241struct CanvasOp<CanvasOpType::DrawRoundRect> {
242 SkRect rect;
243 SkScalar rx;
244 SkScalar ry;
245 SkPaint paint;
246 void draw(SkCanvas* canvas) const {
247 canvas->drawRoundRect(rect, rx, ry, paint);
248 }
249 ASSERT_DRAWABLE()
250};
251
252template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800253struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> {
254 SkRRect outer;
255 SkRRect inner;
256 SkPaint paint;
257 void draw(SkCanvas* canvas) const {
258 canvas->drawDRRect(outer, inner, paint);
259 }
260 ASSERT_DRAWABLE()
261};
262
263template<>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800264struct CanvasOp<CanvasOpType::DrawCircle> {
265 SkScalar cx;
266 SkScalar cy;
267 SkScalar radius;
268 SkPaint paint;
269 void draw(SkCanvas* canvas) const {
270 canvas->drawCircle(cx, cy, radius, paint);
271 }
272 ASSERT_DRAWABLE()
273};
274
275template<>
276struct CanvasOp<CanvasOpType::DrawOval> {
277 SkRect oval;
278 SkPaint paint;
279 void draw(SkCanvas* canvas) const {
280 canvas->drawOval(oval, paint);
281 }
282 ASSERT_DRAWABLE()
283};
284
285template<>
286struct CanvasOp<CanvasOpType::DrawArc> {
287 SkRect oval;
288 SkScalar startAngle;
289 SkScalar sweepAngle;
290 bool useCenter;
291 SkPaint paint;
292
293 void draw(SkCanvas* canvas) const {
294 canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
295 }
296 ASSERT_DRAWABLE()
297};
John Reck013127b2020-10-29 20:53:51 -0400298
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800299template<>
300struct CanvasOp<CanvasOpType::DrawPath> {
301 SkPath path;
302 SkPaint paint;
303
304 void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); }
305 ASSERT_DRAWABLE()
306};
307
308template<>
309struct CanvasOp<CanvasOpType::DrawLine> {
310 float startX;
311 float startY;
312 float endX;
313 float endY;
314 SkPaint paint;
315
316 void draw(SkCanvas* canvas) const {
317 canvas->drawLine(startX, startY, endX, endY, paint);
318 }
319 ASSERT_DRAWABLE()
320};
321
322template<>
Nader Jawad4285c8a2020-11-06 22:49:42 -0800323struct CanvasOp<CanvasOpType::DrawLines> {
324 size_t count;
325 SkPaint paint;
326 sk_sp<Points> points;
327 void draw(SkCanvas* canvas) const {
328 canvas->drawPoints(
329 SkCanvas::kLines_PointMode,
330 count,
331 points->data(),
332 paint
333 );
334 }
335 ASSERT_DRAWABLE()
336};
337
338template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800339struct CanvasOp<CanvasOpType::DrawVertices> {
340 sk_sp<SkVertices> vertices;
341 SkBlendMode mode;
342 SkPaint paint;
343 void draw(SkCanvas* canvas) const {
344 canvas->drawVertices(vertices, mode, paint);
345 }
346 ASSERT_DRAWABLE()
347};
348
Nader Jawadda9248c2020-11-09 17:27:36 -0800349template<>
350struct CanvasOp<CanvasOpType::DrawImage> {
351
John Reckb5eeb182020-12-09 13:45:39 -0500352 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800353 const sk_sp<Bitmap>& bitmap,
354 float left,
355 float top,
Mike Reed7994a312021-01-28 18:06:26 -0500356 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800357 SkPaint paint
358 ) : left(left),
359 top(top),
Mike Reed7994a312021-01-28 18:06:26 -0500360 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800361 paint(std::move(paint)),
362 bitmap(bitmap),
363 image(bitmap->makeImage()) { }
364
365 float left;
366 float top;
Mike Reed7994a312021-01-28 18:06:26 -0500367 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800368 SkPaint paint;
369 sk_sp<Bitmap> bitmap;
370 sk_sp<SkImage> image;
371
372 void draw(SkCanvas* canvas) const {
Mike Reed7994a312021-01-28 18:06:26 -0500373 canvas->drawImage(image, left, top, SkSamplingOptions(filter), &paint);
Nader Jawadda9248c2020-11-09 17:27:36 -0800374 }
375 ASSERT_DRAWABLE()
376};
377
378template<>
379struct CanvasOp<CanvasOpType::DrawImageRect> {
380
John Reckb5eeb182020-12-09 13:45:39 -0500381 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800382 const sk_sp<Bitmap>& bitmap,
383 SkRect src,
384 SkRect dst,
Mike Reed7994a312021-01-28 18:06:26 -0500385 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800386 SkPaint paint
387 ) : src(src),
388 dst(dst),
Mike Reed7994a312021-01-28 18:06:26 -0500389 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800390 paint(std::move(paint)),
391 bitmap(bitmap),
392 image(bitmap->makeImage()) { }
393
394 SkRect src;
395 SkRect dst;
Mike Reed7994a312021-01-28 18:06:26 -0500396 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800397 SkPaint paint;
398 sk_sp<Bitmap> bitmap;
399 sk_sp<SkImage> image;
400
401 void draw(SkCanvas* canvas) const {
402 canvas->drawImageRect(image,
403 src,
404 dst,
Mike Reed7994a312021-01-28 18:06:26 -0500405 SkSamplingOptions(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800406 &paint,
407 SkCanvas::kFast_SrcRectConstraint
408 );
409 }
410 ASSERT_DRAWABLE()
411};
412
413template<>
414struct CanvasOp<CanvasOpType::DrawImageLattice> {
415
John Reckb5eeb182020-12-09 13:45:39 -0500416 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800417 const sk_sp<Bitmap>& bitmap,
418 SkRect dst,
419 SkCanvas::Lattice lattice,
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500420 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800421 SkPaint paint
422 ): dst(dst),
423 lattice(lattice),
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500424 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800425 bitmap(bitmap),
426 image(bitmap->makeImage()),
427 paint(std::move(paint)) {}
428
429 SkRect dst;
430 SkCanvas::Lattice lattice;
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500431 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800432 const sk_sp<Bitmap> bitmap;
433 const sk_sp<SkImage> image;
434
435 SkPaint paint;
436 void draw(SkCanvas* canvas) const {
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500437 canvas->drawImageLattice(image.get(), lattice, dst, filter, &paint);
Nader Jawadda9248c2020-11-09 17:27:36 -0800438 }
439 ASSERT_DRAWABLE()
440};
441
442template<>
443struct CanvasOp<CanvasOpType::DrawPicture> {
444 sk_sp<SkPicture> picture;
445 void draw(SkCanvas* canvas) const {
446 picture->playback(canvas);
447 }
448};
449
Nader Jawad55f19762020-11-25 15:30:20 -0800450template<>
451struct CanvasOp<CanvasOpType::DrawLayer> {
452 sp<Layer> layer;
453};
454
John Reck064650b2021-01-19 21:29:24 -0500455template<>
456struct CanvasOp<CanvasOpType::DrawRenderNode> {
457 sp<RenderNode> renderNode;
458};
459
John Reck013127b2020-10-29 20:53:51 -0400460// cleanup our macros
461#undef ASSERT_DRAWABLE
462
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800463} // namespace android::uirenderer