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