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

Side by Side Diff: cc/output/dc_layer_overlay.cc

Issue 2931833005: Split DCLayerOverlayProcessor::Process into three functions. (Closed)
Patch Set: rebase 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
« no previous file with comments | « cc/output/dc_layer_overlay.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/output/dc_layer_overlay.h" 5 #include "cc/output/dc_layer_overlay.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "cc/base/math_util.h" 8 #include "cc/base/math_util.h"
9 #include "cc/quads/solid_color_draw_quad.h" 9 #include "cc/quads/solid_color_draw_quad.h"
10 #include "cc/quads/yuv_video_draw_quad.h" 10 #include "cc/quads/yuv_video_draw_quad.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 return result; 122 return result;
123 } 123 }
124 124
125 void DCLayerOverlayProcessor::Process(ResourceProvider* resource_provider, 125 void DCLayerOverlayProcessor::Process(ResourceProvider* resource_provider,
126 const gfx::RectF& display_rect, 126 const gfx::RectF& display_rect,
127 QuadList* quad_list, 127 QuadList* quad_list,
128 gfx::Rect* overlay_damage_rect, 128 gfx::Rect* overlay_damage_rect,
129 gfx::Rect* damage_rect, 129 gfx::Rect* damage_rect,
130 DCLayerOverlayList* ca_layer_overlays) { 130 DCLayerOverlayList* ca_layer_overlays) {
131 gfx::Rect this_frame_underlay_rect; 131 gfx::Rect this_frame_underlay_rect;
132 bool display_rect_changed = (display_rect != previous_display_rect_);
133 for (auto it = quad_list->begin(); it != quad_list->end(); ++it) { 132 for (auto it = quad_list->begin(); it != quad_list->end(); ++it) {
134 DCLayerOverlay ca_layer; 133 DCLayerOverlay dc_layer;
135 DCLayerResult result = FromDrawQuad(resource_provider, display_rect, 134 DCLayerResult result = FromDrawQuad(resource_provider, display_rect,
136 quad_list->begin(), it, &ca_layer); 135 quad_list->begin(), it, &dc_layer);
137 if (result != DC_LAYER_SUCCESS) { 136 if (result != DC_LAYER_SUCCESS) {
138 RecordDCLayerResult(result); 137 RecordDCLayerResult(result);
139 continue; 138 continue;
140 } 139 }
141 140
142 if (!it->shared_quad_state->quad_to_target_transform 141 if (!it->shared_quad_state->quad_to_target_transform
143 .Preserves2dAxisAlignment() && 142 .Preserves2dAxisAlignment() &&
144 !base::FeatureList::IsEnabled( 143 !base::FeatureList::IsEnabled(
145 features::kDirectCompositionComplexOverlays)) { 144 features::kDirectCompositionComplexOverlays)) {
146 RecordDCLayerResult(DC_LAYER_FAILED_COMPLEX_TRANSFORM); 145 RecordDCLayerResult(DC_LAYER_FAILED_COMPLEX_TRANSFORM);
147 continue; 146 continue;
148 } 147 }
149 148
150 gfx::Rect quad_rectangle = gfx::ToEnclosingRect(ClippedQuadRectangle(*it)); 149 gfx::Rect quad_rectangle = gfx::ToEnclosingRect(ClippedQuadRectangle(*it));
151 gfx::RectF occlusion_bounding_box = 150 gfx::RectF occlusion_bounding_box =
152 GetOcclusionBounds(gfx::RectF(quad_rectangle), quad_list->begin(), it); 151 GetOcclusionBounds(gfx::RectF(quad_rectangle), quad_list->begin(), it);
153 if (occlusion_bounding_box.IsEmpty()) {
154 // The quad is on top, so promote it to an overlay and remove all damage
155 // underneath it.
156 if (it->shared_quad_state->quad_to_target_transform
157 .Preserves2dAxisAlignment() &&
158 !display_rect_changed && !it->ShouldDrawWithBlending()) {
159 damage_rect->Subtract(quad_rectangle);
160 }
161 quad_list->EraseAndInvalidateAllPointers(it);
162 } else if (!base::FeatureList::IsEnabled(
163 features::kDirectCompositionUnderlays)) {
164 RecordDCLayerResult(DC_LAYER_FAILED_OCCLUDED);
165 continue;
166 } else {
167 // The quad is occluded, so replace it with a black solid color quad and
168 // place the overlay itself under the quad.
169 if (it->shared_quad_state->quad_to_target_transform
170 .IsIdentityOrIntegerTranslation()) {
171 this_frame_underlay_rect = quad_rectangle;
172 }
173 ca_layer.shared_state->z_order = -1;
174 const SharedQuadState* shared_quad_state = it->shared_quad_state;
175 gfx::Rect rect = it->visible_rect;
176 SolidColorDrawQuad* replacement =
177 quad_list->ReplaceExistingElement<SolidColorDrawQuad>(it);
178 replacement->SetAll(shared_quad_state, rect, rect, rect, false,
179 SK_ColorTRANSPARENT, true);
180 152
181 if (this_frame_underlay_rect == previous_frame_underlay_rect_) { 153 // Underlays are less efficient, so attempt regular overlays first.
182 // If this underlay rect is the same as for last frame, subtract its 154 if (ProcessForOverlay(display_rect, quad_list, quad_rectangle,
183 // area from the damage of the main surface, as the cleared area was 155 occlusion_bounding_box, it, damage_rect) ||
184 // already cleared last frame. Add back the damage from the occluded 156 ProcessForUnderlay(display_rect, quad_list, quad_rectangle,
185 // area for this and last frame, as that may have changed. 157 occlusion_bounding_box, it, damage_rect,
186 if (it->shared_quad_state->quad_to_target_transform 158 &this_frame_underlay_rect, &dc_layer)) {
187 .Preserves2dAxisAlignment() && 159 overlay_damage_rect->Union(quad_rectangle);
188 !display_rect_changed) {
189 gfx::Rect occluding_damage_rect = *damage_rect;
190 occluding_damage_rect.Intersect(quad_rectangle);
191 damage_rect->Subtract(quad_rectangle);
192 gfx::Rect new_occlusion_bounding_box =
193 gfx::ToEnclosingRect(occlusion_bounding_box);
194 new_occlusion_bounding_box.Union(previous_occlusion_bounding_box_);
195 occluding_damage_rect.Intersect(new_occlusion_bounding_box);
196 160
197 damage_rect->Union(occluding_damage_rect); 161 RecordDCLayerResult(DC_LAYER_SUCCESS);
198 } 162 ca_layer_overlays->push_back(dc_layer);
199 } else { 163 // Only allow one overlay for now.
200 // Entire replacement quad must be redrawn. 164 break;
201 damage_rect->Union(quad_rectangle);
202 }
203 previous_occlusion_bounding_box_ =
204 gfx::ToEnclosingRect(occlusion_bounding_box);
205 } 165 }
206 overlay_damage_rect->Union(quad_rectangle);
207
208 RecordDCLayerResult(DC_LAYER_SUCCESS);
209 ca_layer_overlays->push_back(ca_layer);
210 // Only allow one overlay for now.
211 break;
212 } 166 }
213 damage_rect->Intersect(gfx::ToEnclosingRect(display_rect)); 167 damage_rect->Intersect(gfx::ToEnclosingRect(display_rect));
214 previous_frame_underlay_rect_ = this_frame_underlay_rect; 168 previous_frame_underlay_rect_ = this_frame_underlay_rect;
215 previous_display_rect_ = display_rect; 169 previous_display_rect_ = display_rect;
216 } 170 }
217 171
172 bool DCLayerOverlayProcessor::ProcessForOverlay(
173 const gfx::RectF& display_rect,
174 QuadList* quad_list,
175 const gfx::Rect& quad_rectangle,
176 const gfx::RectF& occlusion_bounding_box,
177 const QuadList::Iterator& it,
178 gfx::Rect* damage_rect) {
179 bool display_rect_changed = (display_rect != previous_display_rect_);
180 if (!occlusion_bounding_box.IsEmpty())
181 return false;
182 // The quad is on top, so promote it to an overlay and remove all damage
183 // underneath it.
184 if (it->shared_quad_state->quad_to_target_transform
185 .Preserves2dAxisAlignment() &&
186 !display_rect_changed && !it->ShouldDrawWithBlending()) {
187 damage_rect->Subtract(quad_rectangle);
188 }
189 quad_list->EraseAndInvalidateAllPointers(it);
190 return true;
191 }
192
193 bool DCLayerOverlayProcessor::ProcessForUnderlay(
194 const gfx::RectF& display_rect,
195 QuadList* quad_list,
196 const gfx::Rect& quad_rectangle,
197 const gfx::RectF& occlusion_bounding_box,
198 const QuadList::Iterator& it,
199 gfx::Rect* damage_rect,
200 gfx::Rect* this_frame_underlay_rect,
201 DCLayerOverlay* dc_layer) {
202 if (!base::FeatureList::IsEnabled(features::kDirectCompositionUnderlays)) {
203 RecordDCLayerResult(DC_LAYER_FAILED_OCCLUDED);
204 return false;
205 }
206 bool display_rect_changed = (display_rect != previous_display_rect_);
207 // The quad is occluded, so replace it with a black solid color quad and
208 // place the overlay itself under the quad.
209 if (it->shared_quad_state->quad_to_target_transform
210 .IsIdentityOrIntegerTranslation()) {
211 *this_frame_underlay_rect = quad_rectangle;
212 }
213 dc_layer->shared_state->z_order = -1;
214 const SharedQuadState* shared_quad_state = it->shared_quad_state;
215 gfx::Rect rect = it->visible_rect;
216 SolidColorDrawQuad* replacement =
217 quad_list->ReplaceExistingElement<SolidColorDrawQuad>(it);
218 replacement->SetAll(shared_quad_state, rect, rect, rect, false,
219 SK_ColorTRANSPARENT, true);
220
221 if (*this_frame_underlay_rect == previous_frame_underlay_rect_) {
222 // If this underlay rect is the same as for last frame, subtract its
223 // area from the damage of the main surface, as the cleared area was
224 // already cleared last frame. Add back the damage from the occluded
225 // area for this and last frame, as that may have changed.
226 if (it->shared_quad_state->quad_to_target_transform
227 .Preserves2dAxisAlignment() &&
228 !display_rect_changed) {
229 gfx::Rect occluding_damage_rect = *damage_rect;
230 occluding_damage_rect.Intersect(quad_rectangle);
231 damage_rect->Subtract(quad_rectangle);
232 gfx::Rect new_occlusion_bounding_box =
233 gfx::ToEnclosingRect(occlusion_bounding_box);
234 new_occlusion_bounding_box.Union(previous_occlusion_bounding_box_);
235 occluding_damage_rect.Intersect(new_occlusion_bounding_box);
236
237 damage_rect->Union(occluding_damage_rect);
238 }
239 } else {
240 // Entire replacement quad must be redrawn.
241 damage_rect->Union(quad_rectangle);
242 }
243 previous_occlusion_bounding_box_ =
244 gfx::ToEnclosingRect(occlusion_bounding_box);
245 return true;
246 }
247
218 } // namespace cc 248 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/dc_layer_overlay.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698