blob: 2dcbca8273e7bf9a99ae55b1d3fb0f70611beda3 [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>
Kevin Lubick856848e2022-02-24 16:24:09 +000020#include <SkBlendMode.h>
John Reck013127b2020-10-29 20:53:51 -040021#include <SkCanvas.h>
Kevin Lubick856848e2022-02-24 16:24:09 +000022#include <SkClipOp.h>
Nader Jawadda9248c2020-11-09 17:27:36 -080023#include <SkImage.h>
Kevin Lubick856848e2022-02-24 16:24:09 +000024#include <SkPaint.h>
25#include <SkPath.h>
Nader Jawadda9248c2020-11-09 17:27:36 -080026#include <SkPicture.h>
Kevin Lubick856848e2022-02-24 16:24:09 +000027#include <SkRRect.h>
28#include <SkRect.h>
29#include <SkRegion.h>
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -050030#include <SkRuntimeEffect.h>
Kevin Lubick856848e2022-02-24 16:24:09 +000031#include <SkSamplingOptions.h>
32#include <SkVertices.h>
John Reck013127b2020-10-29 20:53:51 -040033
John Reck064650b2021-01-19 21:29:24 -050034#include <log/log.h>
35
36#include "hwui/Bitmap.h"
37#include "CanvasProperty.h"
John Reck013127b2020-10-29 20:53:51 -040038#include "CanvasOpTypes.h"
Nader Jawad55f19762020-11-25 15:30:20 -080039#include "Layer.h"
John Reck064650b2021-01-19 21:29:24 -050040#include "Points.h"
41#include "RenderNode.h"
John Reck013127b2020-10-29 20:53:51 -040042
43#include <experimental/type_traits>
Nader Jawadda9248c2020-11-09 17:27:36 -080044#include <utility>
John Reck013127b2020-10-29 20:53:51 -040045
46namespace android::uirenderer {
47
48template <CanvasOpType T>
49struct CanvasOp;
50
51struct CanvasOpTraits {
52 CanvasOpTraits() = delete;
53
54 template<class T>
55 using draw_t = decltype(std::integral_constant<void (T::*)(SkCanvas*) const, &T::draw>{});
56
57 template <class T>
58 static constexpr bool can_draw = std::experimental::is_detected_v<draw_t, T>;
59};
60
61#define ASSERT_DRAWABLE() private: constexpr void _check_drawable() \
62 { static_assert(CanvasOpTraits::can_draw<std::decay_t<decltype(*this)>>); }
63
64// ----------------------------------------------
65// State Ops
66// ---------------------------------------------
67
68template <>
69struct CanvasOp<CanvasOpType::Save> {
70 void draw(SkCanvas* canvas) const { canvas->save(); }
71 ASSERT_DRAWABLE()
72};
73
74template <>
75struct CanvasOp<CanvasOpType::SaveLayer> {
76 SkCanvas::SaveLayerRec saveLayerRec;
77 void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
78 ASSERT_DRAWABLE()
79};
80
81template <>
82struct CanvasOp<CanvasOpType::SaveBehind> {
83 SkRect bounds;
84 void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
85 ASSERT_DRAWABLE()
86};
87
88template <>
89struct CanvasOp<CanvasOpType::Restore> {
90 void draw(SkCanvas* canvas) const { canvas->restore(); }
91 ASSERT_DRAWABLE()
92};
93
94template <>
95struct CanvasOp<CanvasOpType::BeginZ> {
96};
97template <>
98struct CanvasOp<CanvasOpType::EndZ> {};
99
100// ----------------------------------------------
101// Clip Ops
102// ---------------------------------------------
103
104template <>
105struct CanvasOp<CanvasOpType::ClipRect> {
106 SkRect rect;
107 SkClipOp clipOp;
108 void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
109 ASSERT_DRAWABLE()
110};
111
112template <>
113struct CanvasOp<CanvasOpType::ClipPath> {
114 SkPath path;
115 SkClipOp op;
116 void draw(SkCanvas* canvas) const { canvas->clipPath(path, op, true); }
117 ASSERT_DRAWABLE()
118};
119
120// ----------------------------------------------
121// Drawing Ops
122// ---------------------------------------------
123
Nader Jawadde3ce842020-11-06 16:54:48 -0800124template<>
125struct CanvasOp<CanvasOpType::DrawRoundRectProperty> {
126 sp<uirenderer::CanvasPropertyPrimitive> left;
127 sp<uirenderer::CanvasPropertyPrimitive> top;
128 sp<uirenderer::CanvasPropertyPrimitive> right;
129 sp<uirenderer::CanvasPropertyPrimitive> bottom;
130 sp<uirenderer::CanvasPropertyPrimitive> rx;
131 sp<uirenderer::CanvasPropertyPrimitive> ry;
132 sp<uirenderer::CanvasPropertyPaint> paint;
133
134 void draw(SkCanvas* canvas) const {
135 SkRect rect = SkRect::MakeLTRB(left->value, top->value, right->value, bottom->value);
136 canvas->drawRoundRect(rect, rx->value, ry->value, paint->value);
137 }
138 ASSERT_DRAWABLE()
139};
140
141template<>
142struct CanvasOp<CanvasOpType::DrawCircleProperty> {
143 sp<uirenderer::CanvasPropertyPrimitive> x;
144 sp<uirenderer::CanvasPropertyPrimitive> y;
145 sp<uirenderer::CanvasPropertyPrimitive> radius;
146 sp<uirenderer::CanvasPropertyPaint> paint;
147
148 void draw(SkCanvas* canvas) const {
149 canvas->drawCircle(x->value, y->value, radius->value, paint->value);
150 }
151 ASSERT_DRAWABLE()
152};
153
Lucas Dupin00af5272021-04-29 20:30:01 -0700154template <>
155struct CanvasOp<CanvasOpType::DrawRippleDrawable> {
156 skiapipeline::RippleDrawableParams params;
Lucas Dupin6d1601a2021-04-15 08:39:50 -0700157
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -0500158 void draw(SkCanvas* canvas) const {
Lucas Dupin00af5272021-04-29 20:30:01 -0700159 skiapipeline::AnimatedRippleDrawable::draw(canvas, params);
Derek Sollenbergerdf301aa2020-12-17 11:06:03 -0500160 }
161 ASSERT_DRAWABLE()
162};
163
John Reck013127b2020-10-29 20:53:51 -0400164template <>
165struct CanvasOp<CanvasOpType::DrawColor> {
166 SkColor4f color;
167 SkBlendMode mode;
168 void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
169 ASSERT_DRAWABLE()
170};
171
172template <>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800173struct CanvasOp<CanvasOpType::DrawPaint> {
174 SkPaint paint;
175 void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
176 ASSERT_DRAWABLE()
177};
178
179template <>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800180struct CanvasOp<CanvasOpType::DrawPoint> {
181 float x;
182 float y;
183 SkPaint paint;
184 void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); }
185 ASSERT_DRAWABLE()
186};
187
188template <>
Nader Jawad4285c8a2020-11-06 22:49:42 -0800189struct CanvasOp<CanvasOpType::DrawPoints> {
190 size_t count;
191 SkPaint paint;
192 sk_sp<Points> points;
193 void draw(SkCanvas* canvas) const {
194 canvas->drawPoints(
195 SkCanvas::kPoints_PointMode,
196 count,
197 points->data(),
198 paint
199 );
200 }
201 ASSERT_DRAWABLE()
202};
203
204template <>
John Reck013127b2020-10-29 20:53:51 -0400205struct CanvasOp<CanvasOpType::DrawRect> {
206 SkRect rect;
207 SkPaint paint;
208 void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
209 ASSERT_DRAWABLE()
210};
211
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800212template <>
213struct CanvasOp<CanvasOpType::DrawRegion> {
214 SkRegion region;
215 SkPaint paint;
216 void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
217 ASSERT_DRAWABLE()
218};
219
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800220template<>
221struct CanvasOp<CanvasOpType::DrawRoundRect> {
222 SkRect rect;
223 SkScalar rx;
224 SkScalar ry;
225 SkPaint paint;
226 void draw(SkCanvas* canvas) const {
227 canvas->drawRoundRect(rect, rx, ry, paint);
228 }
229 ASSERT_DRAWABLE()
230};
231
232template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800233struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> {
234 SkRRect outer;
235 SkRRect inner;
236 SkPaint paint;
237 void draw(SkCanvas* canvas) const {
238 canvas->drawDRRect(outer, inner, paint);
239 }
240 ASSERT_DRAWABLE()
241};
242
243template<>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800244struct CanvasOp<CanvasOpType::DrawCircle> {
245 SkScalar cx;
246 SkScalar cy;
247 SkScalar radius;
248 SkPaint paint;
249 void draw(SkCanvas* canvas) const {
250 canvas->drawCircle(cx, cy, radius, paint);
251 }
252 ASSERT_DRAWABLE()
253};
254
255template<>
256struct CanvasOp<CanvasOpType::DrawOval> {
257 SkRect oval;
258 SkPaint paint;
259 void draw(SkCanvas* canvas) const {
260 canvas->drawOval(oval, paint);
261 }
262 ASSERT_DRAWABLE()
263};
264
265template<>
266struct CanvasOp<CanvasOpType::DrawArc> {
267 SkRect oval;
268 SkScalar startAngle;
269 SkScalar sweepAngle;
270 bool useCenter;
271 SkPaint paint;
272
273 void draw(SkCanvas* canvas) const {
274 canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
275 }
276 ASSERT_DRAWABLE()
277};
John Reck013127b2020-10-29 20:53:51 -0400278
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800279template<>
280struct CanvasOp<CanvasOpType::DrawPath> {
281 SkPath path;
282 SkPaint paint;
283
284 void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); }
285 ASSERT_DRAWABLE()
286};
287
288template<>
289struct CanvasOp<CanvasOpType::DrawLine> {
290 float startX;
291 float startY;
292 float endX;
293 float endY;
294 SkPaint paint;
295
296 void draw(SkCanvas* canvas) const {
297 canvas->drawLine(startX, startY, endX, endY, paint);
298 }
299 ASSERT_DRAWABLE()
300};
301
302template<>
Nader Jawad4285c8a2020-11-06 22:49:42 -0800303struct CanvasOp<CanvasOpType::DrawLines> {
304 size_t count;
305 SkPaint paint;
306 sk_sp<Points> points;
307 void draw(SkCanvas* canvas) const {
308 canvas->drawPoints(
309 SkCanvas::kLines_PointMode,
310 count,
311 points->data(),
312 paint
313 );
314 }
315 ASSERT_DRAWABLE()
316};
317
318template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800319struct CanvasOp<CanvasOpType::DrawVertices> {
320 sk_sp<SkVertices> vertices;
321 SkBlendMode mode;
322 SkPaint paint;
323 void draw(SkCanvas* canvas) const {
324 canvas->drawVertices(vertices, mode, paint);
325 }
326 ASSERT_DRAWABLE()
327};
328
Nader Jawadda9248c2020-11-09 17:27:36 -0800329template<>
330struct CanvasOp<CanvasOpType::DrawImage> {
331
John Reckb5eeb182020-12-09 13:45:39 -0500332 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800333 const sk_sp<Bitmap>& bitmap,
334 float left,
335 float top,
Mike Reed7994a312021-01-28 18:06:26 -0500336 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800337 SkPaint paint
338 ) : left(left),
339 top(top),
Mike Reed7994a312021-01-28 18:06:26 -0500340 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800341 paint(std::move(paint)),
342 bitmap(bitmap),
343 image(bitmap->makeImage()) { }
344
345 float left;
346 float top;
Mike Reed7994a312021-01-28 18:06:26 -0500347 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800348 SkPaint paint;
349 sk_sp<Bitmap> bitmap;
350 sk_sp<SkImage> image;
351
352 void draw(SkCanvas* canvas) const {
Mike Reed7994a312021-01-28 18:06:26 -0500353 canvas->drawImage(image, left, top, SkSamplingOptions(filter), &paint);
Nader Jawadda9248c2020-11-09 17:27:36 -0800354 }
355 ASSERT_DRAWABLE()
356};
357
358template<>
359struct CanvasOp<CanvasOpType::DrawImageRect> {
360
John Reckb5eeb182020-12-09 13:45:39 -0500361 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800362 const sk_sp<Bitmap>& bitmap,
363 SkRect src,
364 SkRect dst,
Mike Reed7994a312021-01-28 18:06:26 -0500365 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800366 SkPaint paint
367 ) : src(src),
368 dst(dst),
Mike Reed7994a312021-01-28 18:06:26 -0500369 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800370 paint(std::move(paint)),
371 bitmap(bitmap),
372 image(bitmap->makeImage()) { }
373
374 SkRect src;
375 SkRect dst;
Mike Reed7994a312021-01-28 18:06:26 -0500376 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800377 SkPaint paint;
378 sk_sp<Bitmap> bitmap;
379 sk_sp<SkImage> image;
380
381 void draw(SkCanvas* canvas) const {
382 canvas->drawImageRect(image,
383 src,
384 dst,
Mike Reed7994a312021-01-28 18:06:26 -0500385 SkSamplingOptions(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800386 &paint,
387 SkCanvas::kFast_SrcRectConstraint
388 );
389 }
390 ASSERT_DRAWABLE()
391};
392
393template<>
394struct CanvasOp<CanvasOpType::DrawImageLattice> {
395
John Reckb5eeb182020-12-09 13:45:39 -0500396 CanvasOp(
Nader Jawadda9248c2020-11-09 17:27:36 -0800397 const sk_sp<Bitmap>& bitmap,
398 SkRect dst,
399 SkCanvas::Lattice lattice,
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500400 SkFilterMode filter,
Nader Jawadda9248c2020-11-09 17:27:36 -0800401 SkPaint paint
402 ): dst(dst),
403 lattice(lattice),
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500404 filter(filter),
Nader Jawadda9248c2020-11-09 17:27:36 -0800405 bitmap(bitmap),
406 image(bitmap->makeImage()),
407 paint(std::move(paint)) {}
408
409 SkRect dst;
410 SkCanvas::Lattice lattice;
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500411 SkFilterMode filter;
Nader Jawadda9248c2020-11-09 17:27:36 -0800412 const sk_sp<Bitmap> bitmap;
413 const sk_sp<SkImage> image;
414
415 SkPaint paint;
416 void draw(SkCanvas* canvas) const {
Mike Reed1b3dcfc2021-01-26 20:31:20 -0500417 canvas->drawImageLattice(image.get(), lattice, dst, filter, &paint);
Nader Jawadda9248c2020-11-09 17:27:36 -0800418 }
419 ASSERT_DRAWABLE()
420};
421
422template<>
423struct CanvasOp<CanvasOpType::DrawPicture> {
424 sk_sp<SkPicture> picture;
425 void draw(SkCanvas* canvas) const {
426 picture->playback(canvas);
427 }
428};
429
Nader Jawad55f19762020-11-25 15:30:20 -0800430template<>
431struct CanvasOp<CanvasOpType::DrawLayer> {
432 sp<Layer> layer;
433};
434
John Reck064650b2021-01-19 21:29:24 -0500435template<>
436struct CanvasOp<CanvasOpType::DrawRenderNode> {
437 sp<RenderNode> renderNode;
438};
439
John Reck013127b2020-10-29 20:53:51 -0400440// cleanup our macros
441#undef ASSERT_DRAWABLE
442
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800443} // namespace android::uirenderer