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