blob: b499733757a8184e4f3f675c8fa3f23f24402355 [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"
Nader Jawad55f19762020-11-25 15:30:20 -080031#include "Layer.h"
John Reck013127b2020-10-29 20:53:51 -040032
33#include <experimental/type_traits>
Nader Jawadda9248c2020-11-09 17:27:36 -080034#include <utility>
John Reck013127b2020-10-29 20:53:51 -040035
36namespace android::uirenderer {
37
38template <CanvasOpType T>
39struct CanvasOp;
40
41struct CanvasOpTraits {
42 CanvasOpTraits() = delete;
43
44 template<class T>
45 using draw_t = decltype(std::integral_constant<void (T::*)(SkCanvas*) const, &T::draw>{});
46
47 template <class T>
48 static constexpr bool can_draw = std::experimental::is_detected_v<draw_t, T>;
49};
50
51#define ASSERT_DRAWABLE() private: constexpr void _check_drawable() \
52 { static_assert(CanvasOpTraits::can_draw<std::decay_t<decltype(*this)>>); }
53
54// ----------------------------------------------
55// State Ops
56// ---------------------------------------------
57
58template <>
59struct CanvasOp<CanvasOpType::Save> {
60 void draw(SkCanvas* canvas) const { canvas->save(); }
61 ASSERT_DRAWABLE()
62};
63
64template <>
65struct CanvasOp<CanvasOpType::SaveLayer> {
66 SkCanvas::SaveLayerRec saveLayerRec;
67 void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
68 ASSERT_DRAWABLE()
69};
70
71template <>
72struct CanvasOp<CanvasOpType::SaveBehind> {
73 SkRect bounds;
74 void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
75 ASSERT_DRAWABLE()
76};
77
78template <>
79struct CanvasOp<CanvasOpType::Restore> {
80 void draw(SkCanvas* canvas) const { canvas->restore(); }
81 ASSERT_DRAWABLE()
82};
83
84template <>
85struct CanvasOp<CanvasOpType::BeginZ> {
86};
87template <>
88struct CanvasOp<CanvasOpType::EndZ> {};
89
90// ----------------------------------------------
91// Clip Ops
92// ---------------------------------------------
93
94template <>
95struct CanvasOp<CanvasOpType::ClipRect> {
96 SkRect rect;
97 SkClipOp clipOp;
98 void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
99 ASSERT_DRAWABLE()
100};
101
102template <>
103struct CanvasOp<CanvasOpType::ClipPath> {
104 SkPath path;
105 SkClipOp op;
106 void draw(SkCanvas* canvas) const { canvas->clipPath(path, op, true); }
107 ASSERT_DRAWABLE()
108};
109
110// ----------------------------------------------
111// Drawing Ops
112// ---------------------------------------------
113
Nader Jawadde3ce842020-11-06 16:54:48 -0800114template<>
115struct CanvasOp<CanvasOpType::DrawRoundRectProperty> {
116 sp<uirenderer::CanvasPropertyPrimitive> left;
117 sp<uirenderer::CanvasPropertyPrimitive> top;
118 sp<uirenderer::CanvasPropertyPrimitive> right;
119 sp<uirenderer::CanvasPropertyPrimitive> bottom;
120 sp<uirenderer::CanvasPropertyPrimitive> rx;
121 sp<uirenderer::CanvasPropertyPrimitive> ry;
122 sp<uirenderer::CanvasPropertyPaint> paint;
123
124 void draw(SkCanvas* canvas) const {
125 SkRect rect = SkRect::MakeLTRB(left->value, top->value, right->value, bottom->value);
126 canvas->drawRoundRect(rect, rx->value, ry->value, paint->value);
127 }
128 ASSERT_DRAWABLE()
129};
130
131template<>
132struct CanvasOp<CanvasOpType::DrawCircleProperty> {
133 sp<uirenderer::CanvasPropertyPrimitive> x;
134 sp<uirenderer::CanvasPropertyPrimitive> y;
135 sp<uirenderer::CanvasPropertyPrimitive> radius;
136 sp<uirenderer::CanvasPropertyPaint> paint;
137
138 void draw(SkCanvas* canvas) const {
139 canvas->drawCircle(x->value, y->value, radius->value, paint->value);
140 }
141 ASSERT_DRAWABLE()
142};
143
John Reck013127b2020-10-29 20:53:51 -0400144template <>
145struct CanvasOp<CanvasOpType::DrawColor> {
146 SkColor4f color;
147 SkBlendMode mode;
148 void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
149 ASSERT_DRAWABLE()
150};
151
152template <>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800153struct CanvasOp<CanvasOpType::DrawPaint> {
154 SkPaint paint;
155 void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
156 ASSERT_DRAWABLE()
157};
158
159template <>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800160struct CanvasOp<CanvasOpType::DrawPoint> {
161 float x;
162 float y;
163 SkPaint paint;
164 void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); }
165 ASSERT_DRAWABLE()
166};
167
168template <>
John Reck013127b2020-10-29 20:53:51 -0400169struct CanvasOp<CanvasOpType::DrawRect> {
170 SkRect rect;
171 SkPaint paint;
172 void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
173 ASSERT_DRAWABLE()
174};
175
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800176template <>
177struct CanvasOp<CanvasOpType::DrawRegion> {
178 SkRegion region;
179 SkPaint paint;
180 void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
181 ASSERT_DRAWABLE()
182};
183
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800184template<>
185struct CanvasOp<CanvasOpType::DrawRoundRect> {
186 SkRect rect;
187 SkScalar rx;
188 SkScalar ry;
189 SkPaint paint;
190 void draw(SkCanvas* canvas) const {
191 canvas->drawRoundRect(rect, rx, ry, paint);
192 }
193 ASSERT_DRAWABLE()
194};
195
196template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800197struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> {
198 SkRRect outer;
199 SkRRect inner;
200 SkPaint paint;
201 void draw(SkCanvas* canvas) const {
202 canvas->drawDRRect(outer, inner, paint);
203 }
204 ASSERT_DRAWABLE()
205};
206
207template<>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800208struct CanvasOp<CanvasOpType::DrawCircle> {
209 SkScalar cx;
210 SkScalar cy;
211 SkScalar radius;
212 SkPaint paint;
213 void draw(SkCanvas* canvas) const {
214 canvas->drawCircle(cx, cy, radius, paint);
215 }
216 ASSERT_DRAWABLE()
217};
218
219template<>
220struct CanvasOp<CanvasOpType::DrawOval> {
221 SkRect oval;
222 SkPaint paint;
223 void draw(SkCanvas* canvas) const {
224 canvas->drawOval(oval, paint);
225 }
226 ASSERT_DRAWABLE()
227};
228
229template<>
230struct CanvasOp<CanvasOpType::DrawArc> {
231 SkRect oval;
232 SkScalar startAngle;
233 SkScalar sweepAngle;
234 bool useCenter;
235 SkPaint paint;
236
237 void draw(SkCanvas* canvas) const {
238 canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
239 }
240 ASSERT_DRAWABLE()
241};
John Reck013127b2020-10-29 20:53:51 -0400242
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800243template<>
244struct CanvasOp<CanvasOpType::DrawPath> {
245 SkPath path;
246 SkPaint paint;
247
248 void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); }
249 ASSERT_DRAWABLE()
250};
251
252template<>
253struct CanvasOp<CanvasOpType::DrawLine> {
254 float startX;
255 float startY;
256 float endX;
257 float endY;
258 SkPaint paint;
259
260 void draw(SkCanvas* canvas) const {
261 canvas->drawLine(startX, startY, endX, endY, paint);
262 }
263 ASSERT_DRAWABLE()
264};
265
266template<>
267struct CanvasOp<CanvasOpType::DrawVertices> {
268 sk_sp<SkVertices> vertices;
269 SkBlendMode mode;
270 SkPaint paint;
271 void draw(SkCanvas* canvas) const {
272 canvas->drawVertices(vertices, mode, paint);
273 }
274 ASSERT_DRAWABLE()
275};
276
Nader Jawadda9248c2020-11-09 17:27:36 -0800277template<>
278struct CanvasOp<CanvasOpType::DrawImage> {
279
280 CanvasOp<CanvasOpType::DrawImageRect>(
281 const sk_sp<Bitmap>& bitmap,
282 float left,
283 float top,
284 SkPaint paint
285 ) : left(left),
286 top(top),
287 paint(std::move(paint)),
288 bitmap(bitmap),
289 image(bitmap->makeImage()) { }
290
291 float left;
292 float top;
293 SkPaint paint;
294 sk_sp<Bitmap> bitmap;
295 sk_sp<SkImage> image;
296
297 void draw(SkCanvas* canvas) const {
298 canvas->drawImage(image, left, top, &paint);
299 }
300 ASSERT_DRAWABLE()
301};
302
303template<>
304struct CanvasOp<CanvasOpType::DrawImageRect> {
305
306 CanvasOp<CanvasOpType::DrawImageRect>(
307 const sk_sp<Bitmap>& bitmap,
308 SkRect src,
309 SkRect dst,
310 SkPaint paint
311 ) : src(src),
312 dst(dst),
313 paint(std::move(paint)),
314 bitmap(bitmap),
315 image(bitmap->makeImage()) { }
316
317 SkRect src;
318 SkRect dst;
319 SkPaint paint;
320 sk_sp<Bitmap> bitmap;
321 sk_sp<SkImage> image;
322
323 void draw(SkCanvas* canvas) const {
324 canvas->drawImageRect(image,
325 src,
326 dst,
327 &paint,
328 SkCanvas::kFast_SrcRectConstraint
329 );
330 }
331 ASSERT_DRAWABLE()
332};
333
334template<>
335struct CanvasOp<CanvasOpType::DrawImageLattice> {
336
337 CanvasOp<CanvasOpType::DrawImageLattice>(
338 const sk_sp<Bitmap>& bitmap,
339 SkRect dst,
340 SkCanvas::Lattice lattice,
341 SkPaint paint
342 ): dst(dst),
343 lattice(lattice),
344 bitmap(bitmap),
345 image(bitmap->makeImage()),
346 paint(std::move(paint)) {}
347
348 SkRect dst;
349 SkCanvas::Lattice lattice;
350 const sk_sp<Bitmap> bitmap;
351 const sk_sp<SkImage> image;
352
353 SkPaint paint;
354 void draw(SkCanvas* canvas) const {
355 canvas->drawImageLattice(image.get(), lattice, dst, &paint);
356 }
357 ASSERT_DRAWABLE()
358};
359
360template<>
361struct CanvasOp<CanvasOpType::DrawPicture> {
362 sk_sp<SkPicture> picture;
363 void draw(SkCanvas* canvas) const {
364 picture->playback(canvas);
365 }
366};
367
Nader Jawad55f19762020-11-25 15:30:20 -0800368template<>
369struct CanvasOp<CanvasOpType::DrawLayer> {
370 sp<Layer> layer;
371};
372
John Reck013127b2020-10-29 20:53:51 -0400373// cleanup our macros
374#undef ASSERT_DRAWABLE
375
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800376} // namespace android::uirenderer