| 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 "base/containers/stack_container.h" | 7 #include "base/containers/stack_container.h" |
| 8 #include "cc/paint/display_item_list.h" | 8 #include "cc/paint/display_item_list.h" |
| 9 #include "cc/paint/paint_record.h" | 9 #include "cc/paint/paint_record.h" |
| 10 #include "third_party/skia/include/core/SkAnnotation.h" | 10 #include "third_party/skia/include/core/SkAnnotation.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 SkCanvas* canvas, | 48 SkCanvas* canvas, |
| 49 const SkMatrix& original_ctm); | 49 const SkMatrix& original_ctm); |
| 50 using RasterWithFlagsFunction = void (*)(const PaintOpWithFlags* op, | 50 using RasterWithFlagsFunction = void (*)(const PaintOpWithFlags* op, |
| 51 const PaintFlags* flags, | 51 const PaintFlags* flags, |
| 52 SkCanvas* canvas, | 52 SkCanvas* canvas, |
| 53 const SkMatrix& original_ctm); | 53 const SkMatrix& original_ctm); |
| 54 | 54 |
| 55 NOINLINE static void RasterWithAlphaInternal(RasterFunction raster_fn, | 55 NOINLINE static void RasterWithAlphaInternal(RasterFunction raster_fn, |
| 56 const PaintOp* op, | 56 const PaintOp* op, |
| 57 SkCanvas* canvas, | 57 SkCanvas* canvas, |
| 58 const SkRect& bounds, |
| 58 uint8_t alpha) { | 59 uint8_t alpha) { |
| 59 // TODO(enne): is it ok to just drop the bounds here? | 60 bool unset = bounds.x() == PaintOp::kUnsetRect.x(); |
| 60 canvas->saveLayerAlpha(nullptr, alpha); | 61 canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); |
| 61 SkMatrix unused_matrix; | 62 SkMatrix unused_matrix; |
| 62 raster_fn(op, canvas, unused_matrix); | 63 raster_fn(op, canvas, unused_matrix); |
| 63 canvas->restore(); | 64 canvas->restore(); |
| 64 } | 65 } |
| 65 | 66 |
| 66 // Helper template to share common code for RasterWithAlpha when paint ops | 67 // Helper template to share common code for RasterWithAlpha when paint ops |
| 67 // have or don't have PaintFlags. | 68 // have or don't have PaintFlags. |
| 68 template <typename T, bool HasFlags> | 69 template <typename T, bool HasFlags> |
| 69 struct Rasterizer { | 70 struct Rasterizer { |
| 70 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { | 71 static void RasterWithAlpha(const T* op, |
| 72 SkCanvas* canvas, |
| 73 const SkRect& bounds, |
| 74 uint8_t alpha) { |
| 71 static_assert( | 75 static_assert( |
| 72 !T::kHasPaintFlags, | 76 !T::kHasPaintFlags, |
| 73 "This function should not be used for a PaintOp that has PaintFlags"); | 77 "This function should not be used for a PaintOp that has PaintFlags"); |
| 74 DCHECK(T::kIsDrawOp); | 78 DCHECK(T::kIsDrawOp); |
| 75 RasterWithAlphaInternal(&T::Raster, op, canvas, alpha); | 79 RasterWithAlphaInternal(&T::Raster, op, canvas, bounds, alpha); |
| 76 } | 80 } |
| 77 }; | 81 }; |
| 78 | 82 |
| 79 NOINLINE static void RasterWithAlphaInternalForFlags( | 83 NOINLINE static void RasterWithAlphaInternalForFlags( |
| 80 RasterWithFlagsFunction raster_fn, | 84 RasterWithFlagsFunction raster_fn, |
| 81 const PaintOpWithFlags* op, | 85 const PaintOpWithFlags* op, |
| 82 SkCanvas* canvas, | 86 SkCanvas* canvas, |
| 87 const SkRect& bounds, |
| 83 uint8_t alpha) { | 88 uint8_t alpha) { |
| 84 SkMatrix unused_matrix; | 89 SkMatrix unused_matrix; |
| 85 if (alpha == 255) { | 90 if (alpha == 255) { |
| 86 raster_fn(op, &op->flags, canvas, unused_matrix); | 91 raster_fn(op, &op->flags, canvas, unused_matrix); |
| 87 } else if (op->flags.SupportsFoldingAlpha()) { | 92 } else if (op->flags.SupportsFoldingAlpha()) { |
| 88 PaintFlags flags = op->flags; | 93 PaintFlags flags = op->flags; |
| 89 flags.setAlpha(SkMulDiv255Round(flags.getAlpha(), alpha)); | 94 flags.setAlpha(SkMulDiv255Round(flags.getAlpha(), alpha)); |
| 90 raster_fn(op, &flags, canvas, unused_matrix); | 95 raster_fn(op, &flags, canvas, unused_matrix); |
| 91 } else { | 96 } else { |
| 92 canvas->saveLayerAlpha(nullptr, alpha); | 97 bool unset = bounds.x() == PaintOp::kUnsetRect.x(); |
| 98 canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); |
| 93 raster_fn(op, &op->flags, canvas, unused_matrix); | 99 raster_fn(op, &op->flags, canvas, unused_matrix); |
| 94 canvas->restore(); | 100 canvas->restore(); |
| 95 } | 101 } |
| 96 } | 102 } |
| 97 | 103 |
| 98 template <typename T> | 104 template <typename T> |
| 99 struct Rasterizer<T, true> { | 105 struct Rasterizer<T, true> { |
| 100 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { | 106 static void RasterWithAlpha(const T* op, |
| 107 SkCanvas* canvas, |
| 108 const SkRect& bounds, |
| 109 uint8_t alpha) { |
| 101 static_assert(T::kHasPaintFlags, | 110 static_assert(T::kHasPaintFlags, |
| 102 "This function expects the PaintOp to have PaintFlags"); | 111 "This function expects the PaintOp to have PaintFlags"); |
| 103 DCHECK(T::kIsDrawOp); | 112 DCHECK(T::kIsDrawOp); |
| 104 RasterWithAlphaInternalForFlags(&T::RasterWithFlags, op, canvas, alpha); | 113 RasterWithAlphaInternalForFlags(&T::RasterWithFlags, op, canvas, bounds, |
| 114 alpha); |
| 105 } | 115 } |
| 106 }; | 116 }; |
| 107 | 117 |
| 108 template <> | 118 template <> |
| 109 struct Rasterizer<DrawRecordOp, false> { | 119 struct Rasterizer<DrawRecordOp, false> { |
| 110 static void RasterWithAlpha(const DrawRecordOp* op, | 120 static void RasterWithAlpha(const DrawRecordOp* op, |
| 111 SkCanvas* canvas, | 121 SkCanvas* canvas, |
| 122 const SkRect& bounds, |
| 112 uint8_t alpha) { | 123 uint8_t alpha) { |
| 113 // This "looking into records" optimization is done here instead of | 124 // This "looking into records" optimization is done here instead of |
| 114 // in the PaintOpBuffer::Raster function as DisplayItemList calls | 125 // in the PaintOpBuffer::Raster function as DisplayItemList calls |
| 115 // into RasterWithAlpha directly. | 126 // into RasterWithAlpha directly. |
| 116 if (op->record->size() == 1u) { | 127 if (op->record->size() == 1u) { |
| 117 PaintOp* single_op = op->record->GetFirstOp(); | 128 PaintOp* single_op = op->record->GetFirstOp(); |
| 118 // RasterWithAlpha only supported for draw ops. | 129 // RasterWithAlpha only supported for draw ops. |
| 119 if (single_op->IsDrawOp()) { | 130 if (single_op->IsDrawOp()) { |
| 120 single_op->RasterWithAlpha(canvas, alpha); | 131 single_op->RasterWithAlpha(canvas, bounds, alpha); |
| 121 return; | 132 return; |
| 122 } | 133 } |
| 123 } | 134 } |
| 124 | 135 |
| 125 canvas->saveLayerAlpha(nullptr, alpha); | 136 bool unset = bounds.x() == PaintOp::kUnsetRect.x(); |
| 137 canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); |
| 126 SkMatrix unused_matrix; | 138 SkMatrix unused_matrix; |
| 127 DrawRecordOp::Raster(op, canvas, unused_matrix); | 139 DrawRecordOp::Raster(op, canvas, unused_matrix); |
| 128 canvas->restore(); | 140 canvas->restore(); |
| 129 } | 141 } |
| 130 }; | 142 }; |
| 131 | 143 |
| 132 // TODO(enne): partially specialize RasterWithAlpha for draw color? | 144 // TODO(enne): partially specialize RasterWithAlpha for draw color? |
| 133 | 145 |
| 134 static constexpr size_t kNumOpTypes = | 146 static constexpr size_t kNumOpTypes = |
| 135 static_cast<size_t>(PaintOpType::LastPaintOpType) + 1; | 147 static_cast<size_t>(PaintOpType::LastPaintOpType) + 1; |
| 136 | 148 |
| 137 // Verify that every op is in the TYPES macro. | 149 // Verify that every op is in the TYPES macro. |
| 138 #define M(T) +1 | 150 #define M(T) +1 |
| 139 static_assert(kNumOpTypes == TYPES(M), "Missing op in list"); | 151 static_assert(kNumOpTypes == TYPES(M), "Missing op in list"); |
| 140 #undef M | 152 #undef M |
| 141 | 153 |
| 142 using RasterFunction = void (*)(const PaintOp* op, | 154 using RasterFunction = void (*)(const PaintOp* op, |
| 143 SkCanvas* canvas, | 155 SkCanvas* canvas, |
| 144 const SkMatrix& original_ctm); | 156 const SkMatrix& original_ctm); |
| 145 #define M(T) &T::Raster, | 157 #define M(T) &T::Raster, |
| 146 static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)}; | 158 static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)}; |
| 147 #undef M | 159 #undef M |
| 148 | 160 |
| 149 using RasterAlphaFunction = void (*)(const PaintOp* op, | 161 using RasterAlphaFunction = void (*)(const PaintOp* op, |
| 150 SkCanvas* canvas, | 162 SkCanvas* canvas, |
| 163 const SkRect& bounds, |
| 151 uint8_t alpha); | 164 uint8_t alpha); |
| 152 #define M(T) \ | 165 #define M(T) \ |
| 153 T::kIsDrawOp ? \ | 166 T::kIsDrawOp ? [](const PaintOp* op, SkCanvas* canvas, const SkRect& bounds, \ |
| 154 [](const PaintOp* op, SkCanvas* canvas, uint8_t alpha) { \ | 167 uint8_t alpha) { \ |
| 155 Rasterizer<T, T::kHasPaintFlags>::RasterWithAlpha( \ | 168 Rasterizer<T, T::kHasPaintFlags>::RasterWithAlpha( \ |
| 156 static_cast<const T*>(op), canvas, alpha); \ | 169 static_cast<const T*>(op), canvas, bounds, alpha); \ |
| 157 } : static_cast<RasterAlphaFunction>(nullptr), | 170 } : static_cast<RasterAlphaFunction>(nullptr), |
| 158 static const RasterAlphaFunction g_raster_alpha_functions[kNumOpTypes] = { | 171 static const RasterAlphaFunction g_raster_alpha_functions[kNumOpTypes] = { |
| 159 TYPES(M)}; | 172 TYPES(M)}; |
| 160 #undef M | 173 #undef M |
| 161 | 174 |
| 162 // Most state ops (matrix, clip, save, restore) have a trivial destructor. | 175 // Most state ops (matrix, clip, save, restore) have a trivial destructor. |
| 163 // TODO(enne): evaluate if we need the nullptr optimization or if | 176 // TODO(enne): evaluate if we need the nullptr optimization or if |
| 164 // we even need to differentiate trivial destructors here. | 177 // we even need to differentiate trivial destructors here. |
| 165 using VoidFunction = void (*)(PaintOp* op); | 178 using VoidFunction = void (*)(PaintOp* op); |
| 166 #define M(T) \ | 179 #define M(T) \ |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 } | 452 } |
| 440 | 453 |
| 441 bool PaintOp::IsDrawOp() const { | 454 bool PaintOp::IsDrawOp() const { |
| 442 return g_is_draw_op[type]; | 455 return g_is_draw_op[type]; |
| 443 } | 456 } |
| 444 | 457 |
| 445 void PaintOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { | 458 void PaintOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { |
| 446 g_raster_functions[type](this, canvas, original_ctm); | 459 g_raster_functions[type](this, canvas, original_ctm); |
| 447 } | 460 } |
| 448 | 461 |
| 449 void PaintOp::RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const { | 462 void PaintOp::RasterWithAlpha(SkCanvas* canvas, |
| 450 g_raster_alpha_functions[type](this, canvas, alpha); | 463 const SkRect& bounds, |
| 464 uint8_t alpha) const { |
| 465 g_raster_alpha_functions[type](this, canvas, bounds, alpha); |
| 451 } | 466 } |
| 452 | 467 |
| 453 int ClipPathOp::CountSlowPaths() const { | 468 int ClipPathOp::CountSlowPaths() const { |
| 454 return antialias && !path.isConvex() ? 1 : 0; | 469 return antialias && !path.isConvex() ? 1 : 0; |
| 455 } | 470 } |
| 456 | 471 |
| 457 int DrawLineOp::CountSlowPaths() const { | 472 int DrawLineOp::CountSlowPaths() const { |
| 458 if (const SkPathEffect* effect = flags.getPathEffect()) { | 473 if (const SkPathEffect* effect = flags.getPathEffect()) { |
| 459 SkPathEffect::DashInfo info; | 474 SkPathEffect::DashInfo info; |
| 460 SkPathEffect::DashType dashType = effect->asADash(&info); | 475 SkPathEffect::DashType dashType = effect->asADash(&info); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 if (second) { | 723 if (second) { |
| 709 if (second->GetType() == PaintOpType::Restore) { | 724 if (second->GetType() == PaintOpType::Restore) { |
| 710 continue; | 725 continue; |
| 711 } | 726 } |
| 712 if (second->IsDrawOp()) { | 727 if (second->IsDrawOp()) { |
| 713 third = | 728 third = |
| 714 NextOp(range_starts, range_indices, &stack, &iter, &range_index); | 729 NextOp(range_starts, range_indices, &stack, &iter, &range_index); |
| 715 if (third && third->GetType() == PaintOpType::Restore) { | 730 if (third && third->GetType() == PaintOpType::Restore) { |
| 716 const SaveLayerAlphaOp* save_op = | 731 const SaveLayerAlphaOp* save_op = |
| 717 static_cast<const SaveLayerAlphaOp*>(op); | 732 static_cast<const SaveLayerAlphaOp*>(op); |
| 718 second->RasterWithAlpha(canvas, save_op->alpha); | 733 second->RasterWithAlpha(canvas, save_op->bounds, save_op->alpha); |
| 719 continue; | 734 continue; |
| 720 } | 735 } |
| 721 } | 736 } |
| 722 | 737 |
| 723 // Store deferred ops for later. | 738 // Store deferred ops for later. |
| 724 stack->push_back(second); | 739 stack->push_back(second); |
| 725 if (third) | 740 if (third) |
| 726 stack->push_back(third); | 741 stack->push_back(third); |
| 727 } | 742 } |
| 728 } | 743 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 return std::make_pair(op, skip); | 799 return std::make_pair(op, skip); |
| 785 } | 800 } |
| 786 | 801 |
| 787 void PaintOpBuffer::ShrinkToFit() { | 802 void PaintOpBuffer::ShrinkToFit() { |
| 788 if (!used_ || used_ == reserved_) | 803 if (!used_ || used_ == reserved_) |
| 789 return; | 804 return; |
| 790 ReallocBuffer(used_); | 805 ReallocBuffer(used_); |
| 791 } | 806 } |
| 792 | 807 |
| 793 } // namespace cc | 808 } // namespace cc |
| OLD | NEW |