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