• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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>
22 #include <SkRegion.h>
23 #include <SkVertices.h>
24 #include <SkImage.h>
25 #include <SkPicture.h>
26 #include <SkRuntimeEffect.h>
27 
28 #include <log/log.h>
29 
30 #include "hwui/Bitmap.h"
31 #include "CanvasProperty.h"
32 #include "CanvasOpTypes.h"
33 #include "Layer.h"
34 #include "Points.h"
35 #include "RenderNode.h"
36 
37 #include <experimental/type_traits>
38 #include <utility>
39 
40 namespace android::uirenderer {
41 
42 template <CanvasOpType T>
43 struct CanvasOp;
44 
45 struct 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 
62 template <>
63 struct CanvasOp<CanvasOpType::Save> {
64     void draw(SkCanvas* canvas) const { canvas->save(); }
65     ASSERT_DRAWABLE()
66 };
67 
68 template <>
69 struct CanvasOp<CanvasOpType::SaveLayer> {
70     SkCanvas::SaveLayerRec saveLayerRec;
71     void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
72     ASSERT_DRAWABLE()
73 };
74 
75 template <>
76 struct CanvasOp<CanvasOpType::SaveBehind> {
77     SkRect bounds;
78     void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
79     ASSERT_DRAWABLE()
80 };
81 
82 template <>
83 struct CanvasOp<CanvasOpType::Restore> {
84     void draw(SkCanvas* canvas) const { canvas->restore(); }
85     ASSERT_DRAWABLE()
86 };
87 
88 template <>
89 struct CanvasOp<CanvasOpType::BeginZ> {
90 };
91 template <>
92 struct CanvasOp<CanvasOpType::EndZ> {};
93 
94 // ----------------------------------------------
95 //   Clip Ops
96 //  ---------------------------------------------
97 
98 template <>
99 struct CanvasOp<CanvasOpType::ClipRect> {
100     SkRect rect;
101     SkClipOp clipOp;
102     void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
103     ASSERT_DRAWABLE()
104 };
105 
106 template <>
107 struct 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 
118 template<>
119 struct 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 
135 template<>
136 struct 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 
148 template <>
149 struct CanvasOp<CanvasOpType::DrawRippleDrawable> {
150     skiapipeline::RippleDrawableParams params;
151 
152     void draw(SkCanvas* canvas) const {
153         skiapipeline::AnimatedRippleDrawable::draw(canvas, params);
154     }
155     ASSERT_DRAWABLE()
156 };
157 
158 template <>
159 struct CanvasOp<CanvasOpType::DrawColor> {
160     SkColor4f color;
161     SkBlendMode mode;
162     void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
163     ASSERT_DRAWABLE()
164 };
165 
166 template <>
167 struct CanvasOp<CanvasOpType::DrawPaint> {
168     SkPaint paint;
169     void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
170     ASSERT_DRAWABLE()
171 };
172 
173 template <>
174 struct 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 
182 template <>
183 struct 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 
198 template <>
199 struct CanvasOp<CanvasOpType::DrawRect> {
200     SkRect rect;
201     SkPaint paint;
202     void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
203     ASSERT_DRAWABLE()
204 };
205 
206 template <>
207 struct CanvasOp<CanvasOpType::DrawRegion> {
208     SkRegion region;
209     SkPaint paint;
210     void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
211     ASSERT_DRAWABLE()
212 };
213 
214 template<>
215 struct 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 
226 template<>
227 struct 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 
237 template<>
238 struct 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 
249 template<>
250 struct 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 
259 template<>
260 struct 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 };
272 
273 template<>
274 struct 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 
282 template<>
283 struct 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 
296 template<>
297 struct 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 
312 template<>
313 struct 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 
323 template<>
324 struct CanvasOp<CanvasOpType::DrawImage> {
325 
326     CanvasOp(
327         const sk_sp<Bitmap>& bitmap,
328         float left,
329         float top,
330         SkFilterMode filter,
331         SkPaint paint
332     ) : left(left),
333         top(top),
334         filter(filter),
335         paint(std::move(paint)),
336         bitmap(bitmap),
337         image(bitmap->makeImage()) { }
338 
339     float left;
340     float top;
341     SkFilterMode filter;
342     SkPaint paint;
343     sk_sp<Bitmap> bitmap;
344     sk_sp<SkImage> image;
345 
346     void draw(SkCanvas* canvas) const {
347         canvas->drawImage(image, left, top, SkSamplingOptions(filter), &paint);
348     }
349     ASSERT_DRAWABLE()
350 };
351 
352 template<>
353 struct CanvasOp<CanvasOpType::DrawImageRect> {
354 
355     CanvasOp(
356         const sk_sp<Bitmap>& bitmap,
357         SkRect src,
358         SkRect dst,
359         SkFilterMode filter,
360         SkPaint paint
361     ) : src(src),
362         dst(dst),
363         filter(filter),
364         paint(std::move(paint)),
365         bitmap(bitmap),
366         image(bitmap->makeImage()) { }
367 
368     SkRect src;
369     SkRect dst;
370     SkFilterMode filter;
371     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,
379                 SkSamplingOptions(filter),
380                 &paint,
381                 SkCanvas::kFast_SrcRectConstraint
382         );
383     }
384     ASSERT_DRAWABLE()
385 };
386 
387 template<>
388 struct CanvasOp<CanvasOpType::DrawImageLattice> {
389 
390     CanvasOp(
391         const sk_sp<Bitmap>& bitmap,
392         SkRect dst,
393         SkCanvas::Lattice lattice,
394         SkFilterMode filter,
395         SkPaint  paint
396     ):  dst(dst),
397         lattice(lattice),
398         filter(filter),
399         bitmap(bitmap),
400         image(bitmap->makeImage()),
401         paint(std::move(paint)) {}
402 
403     SkRect dst;
404     SkCanvas::Lattice lattice;
405     SkFilterMode filter;
406     const sk_sp<Bitmap> bitmap;
407     const sk_sp<SkImage> image;
408 
409     SkPaint paint;
410     void draw(SkCanvas* canvas) const {
411         canvas->drawImageLattice(image.get(), lattice, dst, filter, &paint);
412     }
413     ASSERT_DRAWABLE()
414 };
415 
416 template<>
417 struct CanvasOp<CanvasOpType::DrawPicture> {
418     sk_sp<SkPicture> picture;
419     void draw(SkCanvas* canvas) const {
420         picture->playback(canvas);
421     }
422 };
423 
424 template<>
425 struct CanvasOp<CanvasOpType::DrawLayer> {
426     sp<Layer> layer;
427 };
428 
429 template<>
430 struct CanvasOp<CanvasOpType::DrawRenderNode> {
431     sp<RenderNode> renderNode;
432 };
433 
434 // cleanup our macros
435 #undef ASSERT_DRAWABLE
436 
437 }  // namespace android::uirenderer
438