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