• 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 <SkBlendMode.h>
21 #include <SkCanvas.h>
22 #include <SkClipOp.h>
23 #include <SkImage.h>
24 #include <SkPaint.h>
25 #include <SkPath.h>
26 #include <SkPicture.h>
27 #include <SkRRect.h>
28 #include <SkRect.h>
29 #include <SkRegion.h>
30 #include <SkRuntimeEffect.h>
31 #include <SkSamplingOptions.h>
32 #include <SkVertices.h>
33 
34 #include <log/log.h>
35 
36 #include "hwui/Bitmap.h"
37 #include "CanvasProperty.h"
38 #include "CanvasOpTypes.h"
39 #include "Layer.h"
40 #include "Points.h"
41 #include "RenderNode.h"
42 
43 #include <experimental/type_traits>
44 #include <utility>
45 
46 namespace android::uirenderer {
47 
48 template <CanvasOpType T>
49 struct CanvasOp;
50 
51 struct 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 
68 template <>
69 struct CanvasOp<CanvasOpType::Save> {
70     void draw(SkCanvas* canvas) const { canvas->save(); }
71     ASSERT_DRAWABLE()
72 };
73 
74 template <>
75 struct CanvasOp<CanvasOpType::SaveLayer> {
76     SkCanvas::SaveLayerRec saveLayerRec;
77     void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
78     ASSERT_DRAWABLE()
79 };
80 
81 template <>
82 struct CanvasOp<CanvasOpType::SaveBehind> {
83     SkRect bounds;
84     void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
85     ASSERT_DRAWABLE()
86 };
87 
88 template <>
89 struct CanvasOp<CanvasOpType::Restore> {
90     void draw(SkCanvas* canvas) const { canvas->restore(); }
91     ASSERT_DRAWABLE()
92 };
93 
94 template <>
95 struct CanvasOp<CanvasOpType::BeginZ> {
96 };
97 template <>
98 struct CanvasOp<CanvasOpType::EndZ> {};
99 
100 // ----------------------------------------------
101 //   Clip Ops
102 //  ---------------------------------------------
103 
104 template <>
105 struct CanvasOp<CanvasOpType::ClipRect> {
106     SkRect rect;
107     SkClipOp clipOp;
108     void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
109     ASSERT_DRAWABLE()
110 };
111 
112 template <>
113 struct 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 
124 template<>
125 struct 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 
141 template<>
142 struct 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 
154 template <>
155 struct CanvasOp<CanvasOpType::DrawRippleDrawable> {
156     skiapipeline::RippleDrawableParams params;
157 
158     void draw(SkCanvas* canvas) const {
159         skiapipeline::AnimatedRippleDrawable::draw(canvas, params);
160     }
161     ASSERT_DRAWABLE()
162 };
163 
164 template <>
165 struct CanvasOp<CanvasOpType::DrawColor> {
166     SkColor4f color;
167     SkBlendMode mode;
168     void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
169     ASSERT_DRAWABLE()
170 };
171 
172 template <>
173 struct CanvasOp<CanvasOpType::DrawPaint> {
174     SkPaint paint;
175     void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
176     ASSERT_DRAWABLE()
177 };
178 
179 template <>
180 struct 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 
188 template <>
189 struct 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 
204 template <>
205 struct CanvasOp<CanvasOpType::DrawRect> {
206     SkRect rect;
207     SkPaint paint;
208     void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
209     ASSERT_DRAWABLE()
210 };
211 
212 template <>
213 struct CanvasOp<CanvasOpType::DrawRegion> {
214     SkRegion region;
215     SkPaint paint;
216     void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
217     ASSERT_DRAWABLE()
218 };
219 
220 template<>
221 struct 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 
232 template<>
233 struct 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 
243 template<>
244 struct 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 
255 template<>
256 struct 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 
265 template<>
266 struct 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 };
278 
279 template<>
280 struct 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 
288 template<>
289 struct 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 
302 template<>
303 struct 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 
318 template<>
319 struct 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 
329 template<>
330 struct CanvasOp<CanvasOpType::DrawImage> {
331 
332     CanvasOp(
333         const sk_sp<Bitmap>& bitmap,
334         float left,
335         float top,
336         SkFilterMode filter,
337         SkPaint paint
338     ) : left(left),
339         top(top),
340         filter(filter),
341         paint(std::move(paint)),
342         bitmap(bitmap),
343         image(bitmap->makeImage()) { }
344 
345     float left;
346     float top;
347     SkFilterMode filter;
348     SkPaint paint;
349     sk_sp<Bitmap> bitmap;
350     sk_sp<SkImage> image;
351 
352     void draw(SkCanvas* canvas) const {
353         canvas->drawImage(image, left, top, SkSamplingOptions(filter), &paint);
354     }
355     ASSERT_DRAWABLE()
356 };
357 
358 template<>
359 struct CanvasOp<CanvasOpType::DrawImageRect> {
360 
361     CanvasOp(
362         const sk_sp<Bitmap>& bitmap,
363         SkRect src,
364         SkRect dst,
365         SkFilterMode filter,
366         SkPaint paint
367     ) : src(src),
368         dst(dst),
369         filter(filter),
370         paint(std::move(paint)),
371         bitmap(bitmap),
372         image(bitmap->makeImage()) { }
373 
374     SkRect src;
375     SkRect dst;
376     SkFilterMode filter;
377     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,
385                 SkSamplingOptions(filter),
386                 &paint,
387                 SkCanvas::kFast_SrcRectConstraint
388         );
389     }
390     ASSERT_DRAWABLE()
391 };
392 
393 template<>
394 struct CanvasOp<CanvasOpType::DrawImageLattice> {
395 
396     CanvasOp(
397         const sk_sp<Bitmap>& bitmap,
398         SkRect dst,
399         SkCanvas::Lattice lattice,
400         SkFilterMode filter,
401         SkPaint  paint
402     ):  dst(dst),
403         lattice(lattice),
404         filter(filter),
405         bitmap(bitmap),
406         image(bitmap->makeImage()),
407         paint(std::move(paint)) {}
408 
409     SkRect dst;
410     SkCanvas::Lattice lattice;
411     SkFilterMode filter;
412     const sk_sp<Bitmap> bitmap;
413     const sk_sp<SkImage> image;
414 
415     SkPaint paint;
416     void draw(SkCanvas* canvas) const {
417         canvas->drawImageLattice(image.get(), lattice, dst, filter, &paint);
418     }
419     ASSERT_DRAWABLE()
420 };
421 
422 template<>
423 struct CanvasOp<CanvasOpType::DrawPicture> {
424     sk_sp<SkPicture> picture;
425     void draw(SkCanvas* canvas) const {
426         picture->playback(canvas);
427     }
428 };
429 
430 template<>
431 struct CanvasOp<CanvasOpType::DrawLayer> {
432     sp<Layer> layer;
433 };
434 
435 template<>
436 struct CanvasOp<CanvasOpType::DrawRenderNode> {
437     sp<RenderNode> renderNode;
438 };
439 
440 // cleanup our macros
441 #undef ASSERT_DRAWABLE
442 
443 }  // namespace android::uirenderer
444