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 |