blob: 6a7653958981591e153ec52c6cd4cc9e38421191 [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>
John Reck013127b2020-10-29 20:53:51 -040024#include <log/log.h>
Nader Jawadde3ce842020-11-06 16:54:48 -080025#include "CanvasProperty.h"
John Reck013127b2020-10-29 20:53:51 -040026
27#include "CanvasOpTypes.h"
28
29#include <experimental/type_traits>
30
31namespace android::uirenderer {
32
33template <CanvasOpType T>
34struct CanvasOp;
35
36struct CanvasOpTraits {
37 CanvasOpTraits() = delete;
38
39 template<class T>
40 using draw_t = decltype(std::integral_constant<void (T::*)(SkCanvas*) const, &T::draw>{});
41
42 template <class T>
43 static constexpr bool can_draw = std::experimental::is_detected_v<draw_t, T>;
44};
45
46#define ASSERT_DRAWABLE() private: constexpr void _check_drawable() \
47 { static_assert(CanvasOpTraits::can_draw<std::decay_t<decltype(*this)>>); }
48
49// ----------------------------------------------
50// State Ops
51// ---------------------------------------------
52
53template <>
54struct CanvasOp<CanvasOpType::Save> {
55 void draw(SkCanvas* canvas) const { canvas->save(); }
56 ASSERT_DRAWABLE()
57};
58
59template <>
60struct CanvasOp<CanvasOpType::SaveLayer> {
61 SkCanvas::SaveLayerRec saveLayerRec;
62 void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
63 ASSERT_DRAWABLE()
64};
65
66template <>
67struct CanvasOp<CanvasOpType::SaveBehind> {
68 SkRect bounds;
69 void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
70 ASSERT_DRAWABLE()
71};
72
73template <>
74struct CanvasOp<CanvasOpType::Restore> {
75 void draw(SkCanvas* canvas) const { canvas->restore(); }
76 ASSERT_DRAWABLE()
77};
78
79template <>
80struct CanvasOp<CanvasOpType::BeginZ> {
81};
82template <>
83struct CanvasOp<CanvasOpType::EndZ> {};
84
85// ----------------------------------------------
86// Clip Ops
87// ---------------------------------------------
88
89template <>
90struct CanvasOp<CanvasOpType::ClipRect> {
91 SkRect rect;
92 SkClipOp clipOp;
93 void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
94 ASSERT_DRAWABLE()
95};
96
97template <>
98struct CanvasOp<CanvasOpType::ClipPath> {
99 SkPath path;
100 SkClipOp op;
101 void draw(SkCanvas* canvas) const { canvas->clipPath(path, op, true); }
102 ASSERT_DRAWABLE()
103};
104
105// ----------------------------------------------
106// Drawing Ops
107// ---------------------------------------------
108
Nader Jawadde3ce842020-11-06 16:54:48 -0800109template<>
110struct CanvasOp<CanvasOpType::DrawRoundRectProperty> {
111 sp<uirenderer::CanvasPropertyPrimitive> left;
112 sp<uirenderer::CanvasPropertyPrimitive> top;
113 sp<uirenderer::CanvasPropertyPrimitive> right;
114 sp<uirenderer::CanvasPropertyPrimitive> bottom;
115 sp<uirenderer::CanvasPropertyPrimitive> rx;
116 sp<uirenderer::CanvasPropertyPrimitive> ry;
117 sp<uirenderer::CanvasPropertyPaint> paint;
118
119 void draw(SkCanvas* canvas) const {
120 SkRect rect = SkRect::MakeLTRB(left->value, top->value, right->value, bottom->value);
121 canvas->drawRoundRect(rect, rx->value, ry->value, paint->value);
122 }
123 ASSERT_DRAWABLE()
124};
125
126template<>
127struct CanvasOp<CanvasOpType::DrawCircleProperty> {
128 sp<uirenderer::CanvasPropertyPrimitive> x;
129 sp<uirenderer::CanvasPropertyPrimitive> y;
130 sp<uirenderer::CanvasPropertyPrimitive> radius;
131 sp<uirenderer::CanvasPropertyPaint> paint;
132
133 void draw(SkCanvas* canvas) const {
134 canvas->drawCircle(x->value, y->value, radius->value, paint->value);
135 }
136 ASSERT_DRAWABLE()
137};
138
John Reck013127b2020-10-29 20:53:51 -0400139template <>
140struct CanvasOp<CanvasOpType::DrawColor> {
141 SkColor4f color;
142 SkBlendMode mode;
143 void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
144 ASSERT_DRAWABLE()
145};
146
147template <>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800148struct CanvasOp<CanvasOpType::DrawPaint> {
149 SkPaint paint;
150 void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
151 ASSERT_DRAWABLE()
152};
153
154template <>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800155struct CanvasOp<CanvasOpType::DrawPoint> {
156 float x;
157 float y;
158 SkPaint paint;
159 void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); }
160 ASSERT_DRAWABLE()
161};
162
163template <>
John Reck013127b2020-10-29 20:53:51 -0400164struct CanvasOp<CanvasOpType::DrawRect> {
165 SkRect rect;
166 SkPaint paint;
167 void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
168 ASSERT_DRAWABLE()
169};
170
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800171template <>
172struct CanvasOp<CanvasOpType::DrawRegion> {
173 SkRegion region;
174 SkPaint paint;
175 void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); }
176 ASSERT_DRAWABLE()
177};
178
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800179template<>
180struct CanvasOp<CanvasOpType::DrawRoundRect> {
181 SkRect rect;
182 SkScalar rx;
183 SkScalar ry;
184 SkPaint paint;
185 void draw(SkCanvas* canvas) const {
186 canvas->drawRoundRect(rect, rx, ry, paint);
187 }
188 ASSERT_DRAWABLE()
189};
190
191template<>
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800192struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> {
193 SkRRect outer;
194 SkRRect inner;
195 SkPaint paint;
196 void draw(SkCanvas* canvas) const {
197 canvas->drawDRRect(outer, inner, paint);
198 }
199 ASSERT_DRAWABLE()
200};
201
202template<>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800203struct CanvasOp<CanvasOpType::DrawCircle> {
204 SkScalar cx;
205 SkScalar cy;
206 SkScalar radius;
207 SkPaint paint;
208 void draw(SkCanvas* canvas) const {
209 canvas->drawCircle(cx, cy, radius, paint);
210 }
211 ASSERT_DRAWABLE()
212};
213
214template<>
215struct CanvasOp<CanvasOpType::DrawOval> {
216 SkRect oval;
217 SkPaint paint;
218 void draw(SkCanvas* canvas) const {
219 canvas->drawOval(oval, paint);
220 }
221 ASSERT_DRAWABLE()
222};
223
224template<>
225struct CanvasOp<CanvasOpType::DrawArc> {
226 SkRect oval;
227 SkScalar startAngle;
228 SkScalar sweepAngle;
229 bool useCenter;
230 SkPaint paint;
231
232 void draw(SkCanvas* canvas) const {
233 canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
234 }
235 ASSERT_DRAWABLE()
236};
John Reck013127b2020-10-29 20:53:51 -0400237
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800238template<>
239struct CanvasOp<CanvasOpType::DrawPath> {
240 SkPath path;
241 SkPaint paint;
242
243 void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); }
244 ASSERT_DRAWABLE()
245};
246
247template<>
248struct CanvasOp<CanvasOpType::DrawLine> {
249 float startX;
250 float startY;
251 float endX;
252 float endY;
253 SkPaint paint;
254
255 void draw(SkCanvas* canvas) const {
256 canvas->drawLine(startX, startY, endX, endY, paint);
257 }
258 ASSERT_DRAWABLE()
259};
260
261template<>
262struct CanvasOp<CanvasOpType::DrawVertices> {
263 sk_sp<SkVertices> vertices;
264 SkBlendMode mode;
265 SkPaint paint;
266 void draw(SkCanvas* canvas) const {
267 canvas->drawVertices(vertices, mode, paint);
268 }
269 ASSERT_DRAWABLE()
270};
271
John Reck013127b2020-10-29 20:53:51 -0400272// cleanup our macros
273#undef ASSERT_DRAWABLE
274
Nader Jawadfb1e7f12020-11-06 22:49:42 -0800275} // namespace android::uirenderer