OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/direct_renderer.h" | 5 #include "cc/output/direct_renderer.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 200 |
201 const RenderPass* root_render_pass = render_passes_in_draw_order->back(); | 201 const RenderPass* root_render_pass = render_passes_in_draw_order->back(); |
202 DCHECK(root_render_pass); | 202 DCHECK(root_render_pass); |
203 | 203 |
204 DrawingFrame frame; | 204 DrawingFrame frame; |
205 frame.render_passes_in_draw_order = render_passes_in_draw_order; | 205 frame.render_passes_in_draw_order = render_passes_in_draw_order; |
206 frame.root_render_pass = root_render_pass; | 206 frame.root_render_pass = root_render_pass; |
207 frame.root_damage_rect = Capabilities().using_partial_swap | 207 frame.root_damage_rect = Capabilities().using_partial_swap |
208 ? root_render_pass->damage_rect | 208 ? root_render_pass->damage_rect |
209 : root_render_pass->output_rect; | 209 : root_render_pass->output_rect; |
210 frame.root_damage_rect.Union(next_root_damage_rect_); | 210 frame.root_damage_rect.Union(overlay_processor_->GetAndResetOverlayDamage()); |
211 next_root_damage_rect_ = gfx::Rect(); | |
212 frame.root_damage_rect.Intersect(gfx::Rect(device_viewport_rect.size())); | 211 frame.root_damage_rect.Intersect(gfx::Rect(device_viewport_rect.size())); |
213 frame.device_viewport_rect = device_viewport_rect; | 212 frame.device_viewport_rect = device_viewport_rect; |
214 frame.device_clip_rect = device_clip_rect; | 213 frame.device_clip_rect = device_clip_rect; |
215 frame.disable_picture_quad_image_filtering = | 214 frame.disable_picture_quad_image_filtering = |
216 disable_picture_quad_image_filtering; | 215 disable_picture_quad_image_filtering; |
217 | 216 |
218 EnsureBackbuffer(); | 217 EnsureBackbuffer(); |
219 | 218 |
220 // Only reshape when we know we are going to draw. Otherwise, the reshape | 219 // Only reshape when we know we are going to draw. Otherwise, the reshape |
221 // can leave the window at the wrong size if we never draw and the proper | 220 // can leave the window at the wrong size if we never draw and the proper |
222 // viewport size is never set. | 221 // viewport size is never set. |
223 output_surface_->Reshape(device_viewport_rect.size(), device_scale_factor); | 222 output_surface_->Reshape(device_viewport_rect.size(), device_scale_factor); |
224 | 223 |
225 BeginDrawingFrame(&frame); | 224 BeginDrawingFrame(&frame); |
226 | 225 |
227 if (output_surface_->IsDisplayedAsOverlayPlane()) { | 226 if (output_surface_->IsDisplayedAsOverlayPlane()) { |
228 // Create the overlay candidate for the output surface, and mark it as | 227 // Create the overlay candidate for the output surface, and mark it as |
229 // always | 228 // always |
230 // handled. | 229 // handled. |
231 OverlayCandidate output_surface_plane; | 230 OverlayCandidate output_surface_plane; |
232 output_surface_plane.display_rect = | 231 output_surface_plane.display_rect = |
233 gfx::RectF(root_render_pass->output_rect); | 232 gfx::RectF(root_render_pass->output_rect); |
234 output_surface_plane.quad_rect_in_target_space = | 233 output_surface_plane.quad_rect_in_target_space = |
235 root_render_pass->output_rect; | 234 root_render_pass->output_rect; |
236 output_surface_plane.use_output_surface_for_resource = true; | 235 output_surface_plane.use_output_surface_for_resource = true; |
237 output_surface_plane.overlay_handled = true; | 236 output_surface_plane.overlay_handled = true; |
238 frame.overlay_list.push_back(output_surface_plane); | 237 frame.overlay_list.push_back(output_surface_plane); |
239 } | 238 } |
240 | 239 |
241 // If we have any copy requests, we can't remove any quads for overlays, | 240 // If we have any copy requests, we can't remove any quads for overlays or |
242 // otherwise the framebuffer will be missing the overlay contents. | 241 // CALayers because the framebuffer would be missing the removed quads' |
243 if (root_render_pass->copy_requests.empty()) { | 242 // contents. |
244 if (overlay_processor_->ProcessForCALayers( | 243 bool has_copy_requests = false; |
245 resource_provider_, render_passes_in_draw_order, | 244 for (auto* pass : *render_passes_in_draw_order) { |
246 &frame.ca_layer_overlay_list, &frame.overlay_list)) { | 245 if (!pass->copy_requests.empty()) { |
247 // Ensure that the next frame to use the backbuffer will do a full redraw. | 246 has_copy_requests = true; |
248 next_root_damage_rect_.Union(root_render_pass->output_rect); | 247 break; |
249 } else { | 248 } |
250 overlay_processor_->ProcessForOverlays( | 249 } |
251 resource_provider_, render_passes_in_draw_order, &frame.overlay_list, | 250 if (!has_copy_requests) { |
252 &frame.root_damage_rect); | 251 overlay_processor_->ProcessForOverlays( |
| 252 resource_provider_, render_passes_in_draw_order, &frame.overlay_list, |
| 253 &frame.ca_layer_overlay_list, &frame.root_damage_rect); |
| 254 } |
253 | 255 |
254 // No need to render in case the damage rect is completely composited | 256 // If all damage is being drawn with overlays or CALayers then skip drawing |
255 // using | 257 // the render passes. |
256 // overlays and dont have any copy requests. | 258 if (frame.root_damage_rect.IsEmpty() && !has_copy_requests) { |
257 if (frame.root_damage_rect.IsEmpty()) { | 259 BindFramebufferToOutputSurface(&frame); |
258 bool handle_copy_requests = false; | 260 } else { |
259 for (auto* pass : *render_passes_in_draw_order) { | 261 for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) { |
260 if (!pass->copy_requests.empty()) { | 262 RenderPass* pass = render_passes_in_draw_order->at(i); |
261 handle_copy_requests = true; | 263 DrawRenderPass(&frame, pass); |
262 break; | 264 |
263 } | 265 for (ScopedPtrVector<CopyOutputRequest>::iterator it = |
| 266 pass->copy_requests.begin(); |
| 267 it != pass->copy_requests.end(); ++it) { |
| 268 if (it != pass->copy_requests.begin()) { |
| 269 // Doing a readback is destructive of our state on Mac, so make sure |
| 270 // we restore the state between readbacks. http://crbug.com/99393. |
| 271 UseRenderPass(&frame, pass); |
264 } | 272 } |
265 | 273 CopyCurrentRenderPassToBitmap(&frame, pass->copy_requests.take(it)); |
266 if (!handle_copy_requests) { | |
267 BindFramebufferToOutputSurface(&frame); | |
268 FinishDrawingFrame(&frame); | |
269 render_passes_in_draw_order->clear(); | |
270 return; | |
271 } | |
272 overlay_processor_->ProcessForOverlays( | |
273 resource_provider_, render_passes_in_draw_order, | |
274 &frame.overlay_list, &frame.root_damage_rect); | |
275 } | 274 } |
276 } | 275 } |
277 } | 276 } |
278 | |
279 for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) { | |
280 RenderPass* pass = render_passes_in_draw_order->at(i); | |
281 DrawRenderPass(&frame, pass); | |
282 | |
283 for (ScopedPtrVector<CopyOutputRequest>::iterator it = | |
284 pass->copy_requests.begin(); | |
285 it != pass->copy_requests.end(); | |
286 ++it) { | |
287 if (it != pass->copy_requests.begin()) { | |
288 // Doing a readback is destructive of our state on Mac, so make sure | |
289 // we restore the state between readbacks. http://crbug.com/99393. | |
290 UseRenderPass(&frame, pass); | |
291 } | |
292 CopyCurrentRenderPassToBitmap(&frame, pass->copy_requests.take(it)); | |
293 } | |
294 } | |
295 FinishDrawingFrame(&frame); | 277 FinishDrawingFrame(&frame); |
296 | |
297 render_passes_in_draw_order->clear(); | 278 render_passes_in_draw_order->clear(); |
298 } | 279 } |
299 | 280 |
300 gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass( | 281 gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass( |
301 const DrawingFrame* frame) { | 282 const DrawingFrame* frame) { |
302 gfx::Rect render_pass_scissor = frame->current_render_pass->output_rect; | 283 gfx::Rect render_pass_scissor = frame->current_render_pass->output_rect; |
303 | 284 |
304 if (frame->root_damage_rect == frame->root_render_pass->output_rect || | 285 if (frame->root_damage_rect == frame->root_render_pass->output_rect || |
305 !frame->current_render_pass->copy_requests.empty()) | 286 !frame->current_render_pass->copy_requests.empty()) |
306 return render_pass_scissor; | 287 return render_pass_scissor; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 ScopedResource* texture = render_pass_textures_.get(id); | 551 ScopedResource* texture = render_pass_textures_.get(id); |
571 return texture && texture->id(); | 552 return texture && texture->id(); |
572 } | 553 } |
573 | 554 |
574 // static | 555 // static |
575 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { | 556 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { |
576 return render_pass->output_rect.size(); | 557 return render_pass->output_rect.size(); |
577 } | 558 } |
578 | 559 |
579 } // namespace cc | 560 } // namespace cc |
OLD | NEW |