| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/paint/paint_op_buffer.h" | 5 #include "cc/paint/paint_op_buffer.h" |
| 6 | 6 |
| 7 #include "cc/paint/display_item_list.h" | 7 #include "cc/paint/display_item_list.h" |
| 8 #include "cc/paint/paint_record.h" | 8 #include "cc/paint/paint_record.h" |
| 9 #include "third_party/skia/include/core/SkAnnotation.h" | 9 #include "third_party/skia/include/core/SkAnnotation.h" |
| 10 | 10 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 M(NoopOp) \ | 36 M(NoopOp) \ |
| 37 M(RestoreOp) \ | 37 M(RestoreOp) \ |
| 38 M(RotateOp) \ | 38 M(RotateOp) \ |
| 39 M(SaveOp) \ | 39 M(SaveOp) \ |
| 40 M(SaveLayerOp) \ | 40 M(SaveLayerOp) \ |
| 41 M(SaveLayerAlphaOp) \ | 41 M(SaveLayerAlphaOp) \ |
| 42 M(ScaleOp) \ | 42 M(ScaleOp) \ |
| 43 M(SetMatrixOp) \ | 43 M(SetMatrixOp) \ |
| 44 M(TranslateOp) | 44 M(TranslateOp) |
| 45 | 45 |
| 46 using RasterFunction = void (*)(const PaintOp* op, |
| 47 SkCanvas* canvas, |
| 48 const SkMatrix& original_ctm); |
| 49 |
| 50 NOINLINE static void RasterWithAlphaInternal(RasterFunction raster_fn, |
| 51 const PaintOp* op, |
| 52 SkCanvas* canvas, |
| 53 uint8_t alpha) { |
| 54 // TODO(enne): is it ok to just drop the bounds here? |
| 55 canvas->saveLayerAlpha(nullptr, alpha); |
| 56 SkMatrix unused_matrix; |
| 57 raster_fn(op, canvas, unused_matrix); |
| 58 canvas->restore(); |
| 59 } |
| 60 |
| 46 // Helper template to share common code for RasterWithAlpha when paint ops | 61 // Helper template to share common code for RasterWithAlpha when paint ops |
| 47 // have or don't have PaintFlags. | 62 // have or don't have PaintFlags. |
| 48 template <typename T, bool HasFlags> | 63 template <typename T, bool HasFlags> |
| 49 struct Rasterizer { | 64 struct Rasterizer { |
| 50 static void Raster(const T* op, | 65 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { |
| 51 SkCanvas* canvas, | |
| 52 const SkMatrix& original_ctm) { | |
| 53 // Paint ops with kHasPaintFlags need to declare RasterWithPaintFlags | |
| 54 // otherwise, the paint op needs its own Raster function. Without its | |
| 55 // own, this becomes an infinite loop as PaintOp::Raster calls itself. | |
| 56 static_assert( | 66 static_assert( |
| 57 !std::is_same<decltype(&PaintOp::Raster), decltype(&T::Raster)>::value, | 67 !T::kHasPaintFlags, |
| 58 "No Raster function"); | 68 "This function should not be used for a PaintOp that has PaintFlags"); |
| 59 | |
| 60 op->Raster(canvas); | |
| 61 } | |
| 62 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { | |
| 63 DCHECK(T::kIsDrawOp); | 69 DCHECK(T::kIsDrawOp); |
| 64 // TODO(enne): is it ok to just drop the bounds here? | 70 RasterWithAlphaInternal(&T::Raster, op, canvas, alpha); |
| 65 canvas->saveLayerAlpha(nullptr, alpha); | |
| 66 op->Raster(canvas); | |
| 67 canvas->restore(); | |
| 68 } | 71 } |
| 69 }; | 72 }; |
| 70 | 73 |
| 74 NOINLINE static void RasterWithAlphaInternalForFlags(RasterFunction raster_fn, |
| 75 const PaintOpWithFlags* op, |
| 76 SkCanvas* canvas, |
| 77 uint8_t alpha) { |
| 78 SkMatrix unused_matrix; |
| 79 if (alpha == 255) { |
| 80 raster_fn(op, canvas, unused_matrix); |
| 81 } else if (op->flags.SupportsFoldingAlpha()) { |
| 82 PaintOpWithFlags* mutable_op = const_cast<PaintOpWithFlags*>(op); |
| 83 uint8_t flags_alpha = op->flags.getAlpha(); |
| 84 mutable_op->flags.setAlpha(SkMulDiv255Round(flags_alpha, alpha)); |
| 85 raster_fn(op, canvas, unused_matrix); |
| 86 mutable_op->flags.setAlpha(flags_alpha); |
| 87 } else { |
| 88 canvas->saveLayerAlpha(nullptr, alpha); |
| 89 raster_fn(op, canvas, unused_matrix); |
| 90 canvas->restore(); |
| 91 } |
| 92 } |
| 93 |
| 71 template <typename T> | 94 template <typename T> |
| 72 struct Rasterizer<T, true> { | 95 struct Rasterizer<T, true> { |
| 73 static void Raster(const T* op, | |
| 74 SkCanvas* canvas, | |
| 75 const SkMatrix& original_ctm) { | |
| 76 op->RasterWithFlags(canvas, op->flags); | |
| 77 } | |
| 78 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { | 96 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { |
| 97 static_assert(T::kHasPaintFlags, |
| 98 "This function expects the PaintOp to have PaintFlags"); |
| 79 DCHECK(T::kIsDrawOp); | 99 DCHECK(T::kIsDrawOp); |
| 80 SkMatrix unused_matrix; | 100 RasterWithAlphaInternalForFlags(&T::Raster, op, canvas, alpha); |
| 81 if (alpha == 255) { | |
| 82 Raster(op, canvas, unused_matrix); | |
| 83 } else if (op->flags.SupportsFoldingAlpha()) { | |
| 84 PaintFlags flags = op->flags; | |
| 85 flags.setAlpha(SkMulDiv255Round(flags.getAlpha(), alpha)); | |
| 86 op->RasterWithFlags(canvas, flags); | |
| 87 } else { | |
| 88 canvas->saveLayerAlpha(nullptr, alpha); | |
| 89 op->RasterWithFlags(canvas, op->flags); | |
| 90 canvas->restore(); | |
| 91 } | |
| 92 } | |
| 93 }; | |
| 94 | |
| 95 template <> | |
| 96 struct Rasterizer<SetMatrixOp, false> { | |
| 97 static void Raster(const SetMatrixOp* op, | |
| 98 SkCanvas* canvas, | |
| 99 const SkMatrix& original_ctm) { | |
| 100 op->Raster(canvas, original_ctm); | |
| 101 } | |
| 102 static void RasterWithAlpha(const SetMatrixOp* op, | |
| 103 SkCanvas* canvas, | |
| 104 uint8_t alpha) { | |
| 105 NOTREACHED(); | |
| 106 } | 101 } |
| 107 }; | 102 }; |
| 108 | 103 |
| 109 template <> | 104 template <> |
| 110 struct Rasterizer<DrawRecordOp, false> { | 105 struct Rasterizer<DrawRecordOp, false> { |
| 111 static void Raster(const DrawRecordOp* op, | |
| 112 SkCanvas* canvas, | |
| 113 const SkMatrix& original_ctm) { | |
| 114 op->Raster(canvas); | |
| 115 } | |
| 116 static void RasterWithAlpha(const DrawRecordOp* op, | 106 static void RasterWithAlpha(const DrawRecordOp* op, |
| 117 SkCanvas* canvas, | 107 SkCanvas* canvas, |
| 118 uint8_t alpha) { | 108 uint8_t alpha) { |
| 119 // This "looking into records" optimization is done here instead of | 109 // This "looking into records" optimization is done here instead of |
| 120 // in the PaintOpBuffer::Raster function as DisplayItemList calls | 110 // in the PaintOpBuffer::Raster function as DisplayItemList calls |
| 121 // into RasterWithAlpha directly. | 111 // into RasterWithAlpha directly. |
| 122 if (op->record->approximateOpCount() == 1) { | 112 if (op->record->approximateOpCount() == 1) { |
| 123 PaintOp* single_op = op->record->GetFirstOp(); | 113 PaintOp* single_op = op->record->GetFirstOp(); |
| 124 // RasterWithAlpha only supported for draw ops. | 114 // RasterWithAlpha only supported for draw ops. |
| 125 if (single_op->IsDrawOp()) { | 115 if (single_op->IsDrawOp()) { |
| 126 single_op->RasterWithAlpha(canvas, alpha); | 116 single_op->RasterWithAlpha(canvas, alpha); |
| 127 return; | 117 return; |
| 128 } | 118 } |
| 129 } | 119 } |
| 130 | 120 |
| 131 canvas->saveLayerAlpha(nullptr, alpha); | 121 canvas->saveLayerAlpha(nullptr, alpha); |
| 132 op->Raster(canvas); | 122 SkMatrix unused_matrix; |
| 123 DrawRecordOp::Raster(op, canvas, unused_matrix); |
| 133 canvas->restore(); | 124 canvas->restore(); |
| 134 } | 125 } |
| 135 }; | 126 }; |
| 136 | 127 |
| 137 // TODO(enne): partially specialize RasterWithAlpha for draw color? | 128 // TODO(enne): partially specialize RasterWithAlpha for draw color? |
| 138 | 129 |
| 139 static constexpr size_t kNumOpTypes = | 130 static constexpr size_t kNumOpTypes = |
| 140 static_cast<size_t>(PaintOpType::LastPaintOpType) + 1; | 131 static_cast<size_t>(PaintOpType::LastPaintOpType) + 1; |
| 141 | 132 |
| 142 // Verify that every op is in the TYPES macro. | 133 // Verify that every op is in the TYPES macro. |
| 143 #define M(T) +1 | 134 #define M(T) +1 |
| 144 static_assert(kNumOpTypes == TYPES(M), "Missing op in list"); | 135 static_assert(kNumOpTypes == TYPES(M), "Missing op in list"); |
| 145 #undef M | 136 #undef M |
| 146 | 137 |
| 147 using RasterFunction = void (*)(const PaintOp* op, | 138 using RasterFunction = void (*)(const PaintOp* op, |
| 148 SkCanvas* canvas, | 139 SkCanvas* canvas, |
| 149 const SkMatrix& original_ctm); | 140 const SkMatrix& original_ctm); |
| 150 #define M(T) \ | 141 #define M(T) &T::Raster, |
| 151 [](const PaintOp* op, SkCanvas* canvas, const SkMatrix& original_ctm) { \ | |
| 152 Rasterizer<T, T::kHasPaintFlags>::Raster(static_cast<const T*>(op), \ | |
| 153 canvas, original_ctm); \ | |
| 154 }, | |
| 155 static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)}; | 142 static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)}; |
| 156 #undef M | 143 #undef M |
| 157 | 144 |
| 158 using RasterAlphaFunction = void (*)(const PaintOp* op, | 145 using RasterAlphaFunction = void (*)(const PaintOp* op, |
| 159 SkCanvas* canvas, | 146 SkCanvas* canvas, |
| 160 uint8_t alpha); | 147 uint8_t alpha); |
| 161 #define M(T) \ | 148 #define M(T) \ |
| 162 T::kIsDrawOp ? \ | 149 T::kIsDrawOp ? \ |
| 163 [](const PaintOp* op, SkCanvas* canvas, uint8_t alpha) { \ | 150 [](const PaintOp* op, SkCanvas* canvas, uint8_t alpha) { \ |
| 164 Rasterizer<T, T::kHasPaintFlags>::RasterWithAlpha( \ | 151 Rasterizer<T, T::kHasPaintFlags>::RasterWithAlpha( \ |
| (...skipping 27 matching lines...) Expand all Loading... |
| 192 #define M(T) \ | 179 #define M(T) \ |
| 193 static_assert(ALIGNOF(T) <= PaintOpBuffer::PaintOpAlign, \ | 180 static_assert(ALIGNOF(T) <= PaintOpBuffer::PaintOpAlign, \ |
| 194 #T " must have alignment no bigger than PaintOpAlign"); | 181 #T " must have alignment no bigger than PaintOpAlign"); |
| 195 TYPES(M); | 182 TYPES(M); |
| 196 #undef M | 183 #undef M |
| 197 | 184 |
| 198 #undef TYPES | 185 #undef TYPES |
| 199 | 186 |
| 200 SkRect PaintOp::kUnsetRect = {SK_ScalarInfinity, 0, 0, 0}; | 187 SkRect PaintOp::kUnsetRect = {SK_ScalarInfinity, 0, 0, 0}; |
| 201 | 188 |
| 202 void AnnotateOp::Raster(SkCanvas* canvas) const { | 189 void AnnotateOp::Raster(const PaintOp* base_op, |
| 203 switch (annotation_type) { | 190 SkCanvas* canvas, |
| 191 const SkMatrix& original_ctm) { |
| 192 auto* op = static_cast<const AnnotateOp*>(base_op); |
| 193 switch (op->annotation_type) { |
| 204 case PaintCanvas::AnnotationType::URL: | 194 case PaintCanvas::AnnotationType::URL: |
| 205 SkAnnotateRectWithURL(canvas, rect, data.get()); | 195 SkAnnotateRectWithURL(canvas, op->rect, op->data.get()); |
| 206 break; | 196 break; |
| 207 case PaintCanvas::AnnotationType::LINK_TO_DESTINATION: | 197 case PaintCanvas::AnnotationType::LINK_TO_DESTINATION: |
| 208 SkAnnotateLinkToDestination(canvas, rect, data.get()); | 198 SkAnnotateLinkToDestination(canvas, op->rect, op->data.get()); |
| 209 break; | 199 break; |
| 210 case PaintCanvas::AnnotationType::NAMED_DESTINATION: { | 200 case PaintCanvas::AnnotationType::NAMED_DESTINATION: { |
| 211 SkPoint point = SkPoint::Make(rect.x(), rect.y()); | 201 SkPoint point = SkPoint::Make(op->rect.x(), op->rect.y()); |
| 212 SkAnnotateNamedDestination(canvas, point, data.get()); | 202 SkAnnotateNamedDestination(canvas, point, op->data.get()); |
| 213 break; | 203 break; |
| 214 } | 204 } |
| 215 } | 205 } |
| 216 } | 206 } |
| 217 | 207 |
| 218 void ClipPathOp::Raster(SkCanvas* canvas) const { | 208 void ClipPathOp::Raster(const PaintOp* base_op, |
| 219 canvas->clipPath(path, op, antialias); | 209 SkCanvas* canvas, |
| 220 } | 210 const SkMatrix& original_ctm) { |
| 221 | 211 auto* op = static_cast<const ClipPathOp*>(base_op); |
| 222 void ClipRectOp::Raster(SkCanvas* canvas) const { | 212 canvas->clipPath(op->path, op->op, op->antialias); |
| 223 canvas->clipRect(rect, op, antialias); | 213 } |
| 224 } | 214 |
| 225 | 215 void ClipRectOp::Raster(const PaintOp* base_op, |
| 226 void ClipRRectOp::Raster(SkCanvas* canvas) const { | 216 SkCanvas* canvas, |
| 227 canvas->clipRRect(rrect, op, antialias); | 217 const SkMatrix& original_ctm) { |
| 228 } | 218 auto* op = static_cast<const ClipRectOp*>(base_op); |
| 229 | 219 canvas->clipRect(op->rect, op->op, op->antialias); |
| 230 void ConcatOp::Raster(SkCanvas* canvas) const { | 220 } |
| 231 canvas->concat(matrix); | 221 |
| 232 } | 222 void ClipRRectOp::Raster(const PaintOp* base_op, |
| 233 | 223 SkCanvas* canvas, |
| 234 void DrawArcOp::RasterWithFlags(SkCanvas* canvas, | 224 const SkMatrix& original_ctm) { |
| 235 const PaintFlags& flags) const { | 225 auto* op = static_cast<const ClipRRectOp*>(base_op); |
| 236 canvas->drawArc(oval, start_angle, sweep_angle, use_center, ToSkPaint(flags)); | 226 canvas->clipRRect(op->rrect, op->op, op->antialias); |
| 237 } | 227 } |
| 238 | 228 |
| 239 void DrawCircleOp::RasterWithFlags(SkCanvas* canvas, | 229 void ConcatOp::Raster(const PaintOp* base_op, |
| 240 const PaintFlags& flags) const { | 230 SkCanvas* canvas, |
| 241 canvas->drawCircle(cx, cy, radius, ToSkPaint(flags)); | 231 const SkMatrix& original_ctm) { |
| 242 } | 232 auto* op = static_cast<const ConcatOp*>(base_op); |
| 243 | 233 canvas->concat(op->matrix); |
| 244 void DrawColorOp::Raster(SkCanvas* canvas) const { | 234 } |
| 245 canvas->drawColor(color, mode); | 235 |
| 246 } | 236 void DrawArcOp::Raster(const PaintOp* base_op, |
| 247 | 237 SkCanvas* canvas, |
| 248 void DrawDisplayItemListOp::Raster(SkCanvas* canvas) const { | 238 const SkMatrix& original_ctm) { |
| 249 list->Raster(canvas, nullptr); | 239 auto* op = static_cast<const DrawArcOp*>(base_op); |
| 250 } | 240 canvas->drawArc(op->oval, op->start_angle, op->sweep_angle, op->use_center, |
| 251 | 241 ToSkPaint(op->flags)); |
| 252 void DrawDRRectOp::RasterWithFlags(SkCanvas* canvas, | 242 } |
| 253 const PaintFlags& flags) const { | 243 |
| 254 canvas->drawDRRect(outer, inner, ToSkPaint(flags)); | 244 void DrawCircleOp::Raster(const PaintOp* base_op, |
| 255 } | 245 SkCanvas* canvas, |
| 256 | 246 const SkMatrix& original_ctm) { |
| 257 void DrawImageOp::RasterWithFlags(SkCanvas* canvas, | 247 auto* op = static_cast<const DrawCircleOp*>(base_op); |
| 258 const PaintFlags& flags) const { | 248 canvas->drawCircle(op->cx, op->cy, op->radius, ToSkPaint(op->flags)); |
| 259 canvas->drawImage(image.sk_image().get(), left, top, ToSkPaint(&flags)); | 249 } |
| 260 } | 250 |
| 261 | 251 void DrawColorOp::Raster(const PaintOp* base_op, |
| 262 void DrawImageRectOp::RasterWithFlags(SkCanvas* canvas, | 252 SkCanvas* canvas, |
| 263 const PaintFlags& flags) const { | 253 const SkMatrix& original_ctm) { |
| 254 auto* op = static_cast<const DrawColorOp*>(base_op); |
| 255 canvas->drawColor(op->color, op->mode); |
| 256 } |
| 257 |
| 258 void DrawDisplayItemListOp::Raster(const PaintOp* base_op, |
| 259 SkCanvas* canvas, |
| 260 const SkMatrix& original_ctm) { |
| 261 auto* op = static_cast<const DrawDisplayItemListOp*>(base_op); |
| 262 op->list->Raster(canvas, nullptr); |
| 263 } |
| 264 |
| 265 void DrawDRRectOp::Raster(const PaintOp* base_op, |
| 266 SkCanvas* canvas, |
| 267 const SkMatrix& original_ctm) { |
| 268 auto* op = static_cast<const DrawDRRectOp*>(base_op); |
| 269 canvas->drawDRRect(op->outer, op->inner, ToSkPaint(op->flags)); |
| 270 } |
| 271 |
| 272 void DrawImageOp::Raster(const PaintOp* base_op, |
| 273 SkCanvas* canvas, |
| 274 const SkMatrix& original_ctm) { |
| 275 auto* op = static_cast<const DrawImageOp*>(base_op); |
| 276 canvas->drawImage(op->image.sk_image().get(), op->left, op->top, |
| 277 ToSkPaint(&op->flags)); |
| 278 } |
| 279 |
| 280 void DrawImageRectOp::Raster(const PaintOp* base_op, |
| 281 SkCanvas* canvas, |
| 282 const SkMatrix& original_ctm) { |
| 283 auto* op = static_cast<const DrawImageRectOp*>(base_op); |
| 264 // TODO(enne): Probably PaintCanvas should just use the skia enum directly. | 284 // TODO(enne): Probably PaintCanvas should just use the skia enum directly. |
| 265 SkCanvas::SrcRectConstraint skconstraint = | 285 SkCanvas::SrcRectConstraint skconstraint = |
| 266 static_cast<SkCanvas::SrcRectConstraint>(constraint); | 286 static_cast<SkCanvas::SrcRectConstraint>(op->constraint); |
| 267 canvas->drawImageRect(image.sk_image().get(), src, dst, ToSkPaint(&flags), | 287 canvas->drawImageRect(op->image.sk_image().get(), op->src, op->dst, |
| 268 skconstraint); | 288 ToSkPaint(&op->flags), skconstraint); |
| 269 } | 289 } |
| 270 | 290 |
| 271 void DrawIRectOp::RasterWithFlags(SkCanvas* canvas, | 291 void DrawIRectOp::Raster(const PaintOp* base_op, |
| 272 const PaintFlags& flags) const { | 292 SkCanvas* canvas, |
| 273 canvas->drawIRect(rect, ToSkPaint(flags)); | 293 const SkMatrix& original_ctm) { |
| 274 } | 294 auto* op = static_cast<const DrawIRectOp*>(base_op); |
| 275 | 295 canvas->drawIRect(op->rect, ToSkPaint(op->flags)); |
| 276 void DrawLineOp::RasterWithFlags(SkCanvas* canvas, | 296 } |
| 277 const PaintFlags& flags) const { | 297 |
| 278 canvas->drawLine(x0, y0, x1, y1, ToSkPaint(flags)); | 298 void DrawLineOp::Raster(const PaintOp* base_op, |
| 279 } | 299 SkCanvas* canvas, |
| 280 | 300 const SkMatrix& original_ctm) { |
| 281 void DrawOvalOp::RasterWithFlags(SkCanvas* canvas, | 301 auto* op = static_cast<const DrawLineOp*>(base_op); |
| 282 const PaintFlags& flags) const { | 302 canvas->drawLine(op->x0, op->y0, op->x1, op->y1, ToSkPaint(op->flags)); |
| 283 canvas->drawOval(oval, ToSkPaint(flags)); | 303 } |
| 284 } | 304 |
| 285 | 305 void DrawOvalOp::Raster(const PaintOp* base_op, |
| 286 void DrawPathOp::RasterWithFlags(SkCanvas* canvas, | 306 SkCanvas* canvas, |
| 287 const PaintFlags& flags) const { | 307 const SkMatrix& original_ctm) { |
| 288 canvas->drawPath(path, ToSkPaint(flags)); | 308 auto* op = static_cast<const DrawOvalOp*>(base_op); |
| 289 } | 309 canvas->drawOval(op->oval, ToSkPaint(op->flags)); |
| 290 | 310 } |
| 291 void DrawPosTextOp::RasterWithFlags(SkCanvas* canvas, | 311 |
| 292 const PaintFlags& flags) const { | 312 void DrawPathOp::Raster(const PaintOp* base_op, |
| 293 canvas->drawPosText(GetData(), bytes, GetArray(), ToSkPaint(flags)); | 313 SkCanvas* canvas, |
| 294 } | 314 const SkMatrix& original_ctm) { |
| 295 | 315 auto* op = static_cast<const DrawPathOp*>(base_op); |
| 296 void DrawRecordOp::Raster(SkCanvas* canvas) const { | 316 canvas->drawPath(op->path, ToSkPaint(op->flags)); |
| 297 record->playback(canvas); | 317 } |
| 298 } | 318 |
| 299 | 319 void DrawPosTextOp::Raster(const PaintOp* base_op, |
| 300 void DrawRectOp::RasterWithFlags(SkCanvas* canvas, | 320 SkCanvas* canvas, |
| 301 const PaintFlags& flags) const { | 321 const SkMatrix& original_ctm) { |
| 302 canvas->drawRect(rect, ToSkPaint(flags)); | 322 auto* op = static_cast<const DrawPosTextOp*>(base_op); |
| 303 } | 323 canvas->drawPosText(op->GetData(), op->bytes, op->GetArray(), |
| 304 | 324 ToSkPaint(op->flags)); |
| 305 void DrawRRectOp::RasterWithFlags(SkCanvas* canvas, | 325 } |
| 306 const PaintFlags& flags) const { | 326 |
| 307 canvas->drawRRect(rrect, ToSkPaint(flags)); | 327 void DrawRecordOp::Raster(const PaintOp* base_op, |
| 308 } | 328 SkCanvas* canvas, |
| 309 | 329 const SkMatrix& original_ctm) { |
| 310 void DrawTextOp::RasterWithFlags(SkCanvas* canvas, | 330 auto* op = static_cast<const DrawRecordOp*>(base_op); |
| 311 const PaintFlags& flags) const { | 331 op->record->playback(canvas); |
| 312 canvas->drawText(GetData(), bytes, x, y, ToSkPaint(flags)); | 332 } |
| 313 } | 333 |
| 314 | 334 void DrawRectOp::Raster(const PaintOp* base_op, |
| 315 void DrawTextBlobOp::RasterWithFlags(SkCanvas* canvas, | 335 SkCanvas* canvas, |
| 316 const PaintFlags& flags) const { | 336 const SkMatrix& original_ctm) { |
| 317 canvas->drawTextBlob(blob.get(), x, y, ToSkPaint(flags)); | 337 auto* op = static_cast<const DrawRectOp*>(base_op); |
| 318 } | 338 canvas->drawRect(op->rect, ToSkPaint(op->flags)); |
| 319 | 339 } |
| 320 void RestoreOp::Raster(SkCanvas* canvas) const { | 340 |
| 341 void DrawRRectOp::Raster(const PaintOp* base_op, |
| 342 SkCanvas* canvas, |
| 343 const SkMatrix& original_ctm) { |
| 344 auto* op = static_cast<const DrawRRectOp*>(base_op); |
| 345 canvas->drawRRect(op->rrect, ToSkPaint(op->flags)); |
| 346 } |
| 347 |
| 348 void DrawTextOp::Raster(const PaintOp* base_op, |
| 349 SkCanvas* canvas, |
| 350 const SkMatrix& original_ctm) { |
| 351 auto* op = static_cast<const DrawTextOp*>(base_op); |
| 352 canvas->drawText(op->GetData(), op->bytes, op->x, op->y, |
| 353 ToSkPaint(op->flags)); |
| 354 } |
| 355 |
| 356 void DrawTextBlobOp::Raster(const PaintOp* base_op, |
| 357 SkCanvas* canvas, |
| 358 const SkMatrix& original_ctm) { |
| 359 auto* op = static_cast<const DrawTextBlobOp*>(base_op); |
| 360 canvas->drawTextBlob(op->blob.get(), op->x, op->y, ToSkPaint(op->flags)); |
| 361 } |
| 362 |
| 363 void RestoreOp::Raster(const PaintOp* base_op, |
| 364 SkCanvas* canvas, |
| 365 const SkMatrix& original_ctm) { |
| 321 canvas->restore(); | 366 canvas->restore(); |
| 322 } | 367 } |
| 323 | 368 |
| 324 void RotateOp::Raster(SkCanvas* canvas) const { | 369 void RotateOp::Raster(const PaintOp* base_op, |
| 325 canvas->rotate(degrees); | 370 SkCanvas* canvas, |
| 326 } | 371 const SkMatrix& original_ctm) { |
| 327 | 372 auto* op = static_cast<const RotateOp*>(base_op); |
| 328 void SaveOp::Raster(SkCanvas* canvas) const { | 373 canvas->rotate(op->degrees); |
| 374 } |
| 375 |
| 376 void SaveOp::Raster(const PaintOp* base_op, |
| 377 SkCanvas* canvas, |
| 378 const SkMatrix& original_ctm) { |
| 329 canvas->save(); | 379 canvas->save(); |
| 330 } | 380 } |
| 331 | 381 |
| 332 void SaveLayerOp::RasterWithFlags(SkCanvas* canvas, | 382 void SaveLayerOp::Raster(const PaintOp* base_op, |
| 333 const PaintFlags& flags) const { | 383 SkCanvas* canvas, |
| 384 const SkMatrix& original_ctm) { |
| 385 auto* op = static_cast<const SaveLayerOp*>(base_op); |
| 334 // See PaintOp::kUnsetRect | 386 // See PaintOp::kUnsetRect |
| 335 bool unset = bounds.left() == SK_ScalarInfinity; | 387 bool unset = op->bounds.left() == SK_ScalarInfinity; |
| 336 | 388 |
| 337 canvas->saveLayer(unset ? nullptr : &bounds, ToSkPaint(&flags)); | 389 canvas->saveLayer(unset ? nullptr : &op->bounds, ToSkPaint(&op->flags)); |
| 338 } | 390 } |
| 339 | 391 |
| 340 void SaveLayerAlphaOp::Raster(SkCanvas* canvas) const { | 392 void SaveLayerAlphaOp::Raster(const PaintOp* base_op, |
| 393 SkCanvas* canvas, |
| 394 const SkMatrix& original_ctm) { |
| 395 auto* op = static_cast<const SaveLayerAlphaOp*>(base_op); |
| 341 // See PaintOp::kUnsetRect | 396 // See PaintOp::kUnsetRect |
| 342 bool unset = bounds.left() == SK_ScalarInfinity; | 397 bool unset = op->bounds.left() == SK_ScalarInfinity; |
| 343 canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); | 398 canvas->saveLayerAlpha(unset ? nullptr : &op->bounds, op->alpha); |
| 344 } | 399 } |
| 345 | 400 |
| 346 void ScaleOp::Raster(SkCanvas* canvas) const { | 401 void ScaleOp::Raster(const PaintOp* base_op, |
| 347 canvas->scale(sx, sy); | 402 SkCanvas* canvas, |
| 348 } | 403 const SkMatrix& original_ctm) { |
| 349 | 404 auto* op = static_cast<const ScaleOp*>(base_op); |
| 350 void SetMatrixOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { | 405 canvas->scale(op->sx, op->sy); |
| 351 canvas->setMatrix(SkMatrix::Concat(original_ctm, matrix)); | 406 } |
| 352 } | 407 |
| 353 | 408 void SetMatrixOp::Raster(const PaintOp* base_op, |
| 354 void TranslateOp::Raster(SkCanvas* canvas) const { | 409 SkCanvas* canvas, |
| 355 canvas->translate(dx, dy); | 410 const SkMatrix& original_ctm) { |
| 411 auto* op = static_cast<const SetMatrixOp*>(base_op); |
| 412 canvas->setMatrix(SkMatrix::Concat(original_ctm, op->matrix)); |
| 413 } |
| 414 |
| 415 void TranslateOp::Raster(const PaintOp* base_op, |
| 416 SkCanvas* canvas, |
| 417 const SkMatrix& original_ctm) { |
| 418 auto* op = static_cast<const TranslateOp*>(base_op); |
| 419 canvas->translate(op->dx, op->dy); |
| 356 } | 420 } |
| 357 | 421 |
| 358 bool PaintOp::IsDrawOp() const { | 422 bool PaintOp::IsDrawOp() const { |
| 359 return g_is_draw_op[type]; | 423 return g_is_draw_op[type]; |
| 360 } | 424 } |
| 361 | 425 |
| 362 void PaintOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { | 426 void PaintOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { |
| 363 g_raster_functions[type](this, canvas, original_ctm); | 427 g_raster_functions[type](this, canvas, original_ctm); |
| 364 } | 428 } |
| 365 | 429 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 | 490 |
| 427 DrawDisplayItemListOp& DrawDisplayItemListOp::operator=( | 491 DrawDisplayItemListOp& DrawDisplayItemListOp::operator=( |
| 428 const DrawDisplayItemListOp& op) = default; | 492 const DrawDisplayItemListOp& op) = default; |
| 429 | 493 |
| 430 DrawDisplayItemListOp::~DrawDisplayItemListOp() = default; | 494 DrawDisplayItemListOp::~DrawDisplayItemListOp() = default; |
| 431 | 495 |
| 432 DrawImageOp::DrawImageOp(const PaintImage& image, | 496 DrawImageOp::DrawImageOp(const PaintImage& image, |
| 433 SkScalar left, | 497 SkScalar left, |
| 434 SkScalar top, | 498 SkScalar top, |
| 435 const PaintFlags* flags) | 499 const PaintFlags* flags) |
| 436 : image(image), | 500 : PaintOpWithFlags(flags ? *flags : PaintFlags()), |
| 501 image(image), |
| 437 left(left), | 502 left(left), |
| 438 top(top), | 503 top(top) {} |
| 439 flags(flags ? *flags : PaintFlags()) {} | |
| 440 | 504 |
| 441 DrawImageOp::~DrawImageOp() = default; | 505 DrawImageOp::~DrawImageOp() = default; |
| 442 | 506 |
| 443 DrawImageRectOp::DrawImageRectOp(const PaintImage& image, | 507 DrawImageRectOp::DrawImageRectOp(const PaintImage& image, |
| 444 const SkRect& src, | 508 const SkRect& src, |
| 445 const SkRect& dst, | 509 const SkRect& dst, |
| 446 const PaintFlags* flags, | 510 const PaintFlags* flags, |
| 447 PaintCanvas::SrcRectConstraint constraint) | 511 PaintCanvas::SrcRectConstraint constraint) |
| 448 : image(image), | 512 : PaintOpWithFlags(flags ? *flags : PaintFlags()), |
| 449 flags(flags ? *flags : PaintFlags()), | 513 image(image), |
| 450 src(src), | 514 src(src), |
| 451 dst(dst), | 515 dst(dst), |
| 452 constraint(constraint) {} | 516 constraint(constraint) {} |
| 453 | 517 |
| 454 DrawImageRectOp::~DrawImageRectOp() = default; | 518 DrawImageRectOp::~DrawImageRectOp() = default; |
| 455 | 519 |
| 456 DrawPosTextOp::DrawPosTextOp(size_t bytes, | 520 DrawPosTextOp::DrawPosTextOp(size_t bytes, |
| 457 size_t count, | 521 size_t count, |
| 458 const PaintFlags& flags) | 522 const PaintFlags& flags) |
| 459 : PaintOpWithArray(bytes, count), flags(flags) {} | 523 : PaintOpWithArray(flags, bytes, count) {} |
| 460 | 524 |
| 461 DrawPosTextOp::~DrawPosTextOp() = default; | 525 DrawPosTextOp::~DrawPosTextOp() = default; |
| 462 | 526 |
| 463 DrawRecordOp::DrawRecordOp(sk_sp<const PaintRecord> record) | 527 DrawRecordOp::DrawRecordOp(sk_sp<const PaintRecord> record) |
| 464 : record(std::move(record)) {} | 528 : record(std::move(record)) {} |
| 465 | 529 |
| 466 DrawRecordOp::~DrawRecordOp() = default; | 530 DrawRecordOp::~DrawRecordOp() = default; |
| 467 | 531 |
| 468 size_t DrawRecordOp::AdditionalBytesUsed() const { | 532 size_t DrawRecordOp::AdditionalBytesUsed() const { |
| 469 return record->approximateBytesUsed(); | 533 return record->approximateBytesUsed(); |
| 470 } | 534 } |
| 471 | 535 |
| 472 DrawTextBlobOp::DrawTextBlobOp(sk_sp<SkTextBlob> blob, | 536 DrawTextBlobOp::DrawTextBlobOp(sk_sp<SkTextBlob> blob, |
| 473 SkScalar x, | 537 SkScalar x, |
| 474 SkScalar y, | 538 SkScalar y, |
| 475 const PaintFlags& flags) | 539 const PaintFlags& flags) |
| 476 : blob(std::move(blob)), x(x), y(y), flags(flags) {} | 540 : PaintOpWithFlags(flags), blob(std::move(blob)), x(x), y(y) {} |
| 477 | 541 |
| 478 DrawTextBlobOp::~DrawTextBlobOp() = default; | 542 DrawTextBlobOp::~DrawTextBlobOp() = default; |
| 479 | 543 |
| 480 PaintOpBuffer::PaintOpBuffer() : cull_rect_(SkRect::MakeEmpty()) {} | 544 PaintOpBuffer::PaintOpBuffer() : cull_rect_(SkRect::MakeEmpty()) {} |
| 481 | 545 |
| 482 PaintOpBuffer::PaintOpBuffer(const SkRect& cull_rect) : cull_rect_(cull_rect) {} | 546 PaintOpBuffer::PaintOpBuffer(const SkRect& cull_rect) : cull_rect_(cull_rect) {} |
| 483 | 547 |
| 484 PaintOpBuffer::~PaintOpBuffer() { | 548 PaintOpBuffer::~PaintOpBuffer() { |
| 485 Reset(); | 549 Reset(); |
| 486 } | 550 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 | 627 |
| 564 void PaintOpBuffer::ReallocBuffer(size_t new_size) { | 628 void PaintOpBuffer::ReallocBuffer(size_t new_size) { |
| 565 DCHECK_GE(new_size, used_); | 629 DCHECK_GE(new_size, used_); |
| 566 std::unique_ptr<char, base::AlignedFreeDeleter> new_data( | 630 std::unique_ptr<char, base::AlignedFreeDeleter> new_data( |
| 567 static_cast<char*>(base::AlignedAlloc(new_size, PaintOpAlign))); | 631 static_cast<char*>(base::AlignedAlloc(new_size, PaintOpAlign))); |
| 568 memcpy(new_data.get(), data_.get(), used_); | 632 memcpy(new_data.get(), data_.get(), used_); |
| 569 data_ = std::move(new_data); | 633 data_ = std::move(new_data); |
| 570 reserved_ = new_size; | 634 reserved_ = new_size; |
| 571 } | 635 } |
| 572 | 636 |
| 637 std::pair<void*, size_t> PaintOpBuffer::AllocatePaintOp(size_t sizeof_op, |
| 638 size_t bytes) { |
| 639 if (!op_count_) { |
| 640 if (bytes) { |
| 641 // Internal first_op buffer doesn't have room for extra data. |
| 642 // If the op wants extra bytes, then we'll just store a Noop |
| 643 // in the first_op and proceed from there. This seems unlikely |
| 644 // to be a common case. |
| 645 push<NoopOp>(); |
| 646 } else { |
| 647 op_count_++; |
| 648 return std::make_pair(first_op_.void_data(), 0); |
| 649 } |
| 650 } |
| 651 |
| 652 // We've filled |first_op_| by now so we need to allocate space in |data_|. |
| 653 DCHECK(op_count_); |
| 654 |
| 655 // Compute a skip such that all ops in the buffer are aligned to the |
| 656 // maximum required alignment of all ops. |
| 657 size_t skip = MathUtil::UncheckedRoundUp(sizeof_op + bytes, PaintOpAlign); |
| 658 DCHECK_LT(skip, static_cast<size_t>(1) << 24); |
| 659 if (used_ + skip > reserved_) { |
| 660 // Start reserved_ at kInitialBufferSize and then double. |
| 661 // ShrinkToFit can make this smaller afterwards. |
| 662 size_t new_size = reserved_ ? reserved_ : kInitialBufferSize; |
| 663 while (used_ + skip > new_size) |
| 664 new_size *= 2; |
| 665 ReallocBuffer(new_size); |
| 666 } |
| 667 DCHECK_LE(used_ + skip, reserved_); |
| 668 |
| 669 void* op = data_.get() + used_; |
| 670 used_ += skip; |
| 671 op_count_++; |
| 672 return std::make_pair(op, skip); |
| 673 } |
| 674 |
| 573 void PaintOpBuffer::ShrinkToFit() { | 675 void PaintOpBuffer::ShrinkToFit() { |
| 574 if (!used_ || used_ == reserved_) | 676 if (!used_ || used_ == reserved_) |
| 575 return; | 677 return; |
| 576 ReallocBuffer(used_); | 678 ReallocBuffer(used_); |
| 577 } | 679 } |
| 578 | 680 |
| 579 } // namespace cc | 681 } // namespace cc |
| OLD | NEW |