Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: cc/paint/paint_op_buffer.cc

Issue 2914863003: Use SaveLayerAlpha bounds when doing Save-Draw-Restore optimization (Closed)
Patch Set: savebounds . Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/paint/paint_op_buffer.h ('k') | third_party/WebKit/Source/platform/graphics/PaintGeneratedImage.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698