Chromium Code Reviews| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <unordered_map> | 9 #include <unordered_map> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 } | 107 } |
| 108 | 108 |
| 109 void DirectRenderer::InitializeViewport(DrawingFrame* frame, | 109 void DirectRenderer::InitializeViewport(DrawingFrame* frame, |
| 110 const gfx::Rect& draw_rect, | 110 const gfx::Rect& draw_rect, |
| 111 const gfx::Rect& viewport_rect, | 111 const gfx::Rect& viewport_rect, |
| 112 const gfx::Size& surface_size) { | 112 const gfx::Size& surface_size) { |
| 113 DCHECK_GE(viewport_rect.x(), 0); | 113 DCHECK_GE(viewport_rect.x(), 0); |
| 114 DCHECK_GE(viewport_rect.y(), 0); | 114 DCHECK_GE(viewport_rect.y(), 0); |
| 115 DCHECK_LE(viewport_rect.right(), surface_size.width()); | 115 DCHECK_LE(viewport_rect.right(), surface_size.width()); |
| 116 DCHECK_LE(viewport_rect.bottom(), surface_size.height()); | 116 DCHECK_LE(viewport_rect.bottom(), surface_size.height()); |
| 117 bool flip_y = FlippedFramebuffer(frame); | 117 bool flip_y = FlippedFramebuffer(); |
| 118 if (flip_y) { | 118 if (flip_y) { |
| 119 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), | 119 frame->projection_matrix = OrthoProjectionMatrix( |
| 120 draw_rect.right(), | 120 draw_rect.x(), draw_rect.right(), draw_rect.bottom(), draw_rect.y()); |
| 121 draw_rect.bottom(), | |
| 122 draw_rect.y()); | |
| 123 } else { | 121 } else { |
| 124 frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(), | 122 frame->projection_matrix = OrthoProjectionMatrix( |
| 125 draw_rect.right(), | 123 draw_rect.x(), draw_rect.right(), draw_rect.y(), draw_rect.bottom()); |
| 126 draw_rect.y(), | |
| 127 draw_rect.bottom()); | |
| 128 } | 124 } |
| 129 | 125 |
| 130 gfx::Rect window_rect = viewport_rect; | 126 gfx::Rect window_rect = viewport_rect; |
| 131 if (flip_y) | 127 if (flip_y) |
| 132 window_rect.set_y(surface_size.height() - viewport_rect.bottom()); | 128 window_rect.set_y(surface_size.height() - viewport_rect.bottom()); |
| 133 frame->window_matrix = window_matrix(window_rect.x(), | 129 frame->window_matrix = |
| 134 window_rect.y(), | 130 window_matrix(window_rect.x(), window_rect.y(), window_rect.width(), |
| 135 window_rect.width(), | 131 window_rect.height()); |
| 136 window_rect.height()); | |
| 137 current_draw_rect_ = draw_rect; | 132 current_draw_rect_ = draw_rect; |
| 138 current_viewport_rect_ = viewport_rect; | 133 current_viewport_rect_ = viewport_rect; |
| 139 current_surface_size_ = surface_size; | 134 current_surface_size_ = surface_size; |
| 140 current_window_space_viewport_ = window_rect; | 135 current_window_space_viewport_ = window_rect; |
| 141 } | 136 } |
| 142 | 137 |
| 143 gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace( | 138 gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace( |
| 144 const DrawingFrame* frame, | |
| 145 const gfx::Rect& draw_rect) const { | 139 const gfx::Rect& draw_rect) const { |
| 146 gfx::Rect window_rect = draw_rect; | 140 gfx::Rect window_rect = draw_rect; |
| 147 window_rect -= current_draw_rect_.OffsetFromOrigin(); | 141 window_rect -= current_draw_rect_.OffsetFromOrigin(); |
| 148 window_rect += current_viewport_rect_.OffsetFromOrigin(); | 142 window_rect += current_viewport_rect_.OffsetFromOrigin(); |
| 149 if (FlippedFramebuffer(frame)) | 143 if (FlippedFramebuffer()) |
| 150 window_rect.set_y(current_surface_size_.height() - window_rect.bottom()); | 144 window_rect.set_y(current_surface_size_.height() - window_rect.bottom()); |
| 151 return window_rect; | 145 return window_rect; |
| 152 } | 146 } |
| 153 | 147 |
| 154 const TileDrawQuad* DirectRenderer::CanPassBeDrawnDirectly( | 148 const TileDrawQuad* DirectRenderer::CanPassBeDrawnDirectly( |
| 155 const RenderPass* pass) { | 149 const RenderPass* pass) { |
| 156 return nullptr; | 150 return nullptr; |
| 157 } | 151 } |
| 158 | 152 |
| 159 void DirectRenderer::SetVisible(bool visible) { | 153 void DirectRenderer::SetVisible(bool visible) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 DLOG_IF(WARNING, !overdraw_feedback_support_missing_logged_once_) | 231 DLOG_IF(WARNING, !overdraw_feedback_support_missing_logged_once_) |
| 238 << "Overdraw feedback enabled on platform without support."; | 232 << "Overdraw feedback enabled on platform without support."; |
| 239 overdraw_feedback_support_missing_logged_once_ = true; | 233 overdraw_feedback_support_missing_logged_once_ = true; |
| 240 #endif | 234 #endif |
| 241 overdraw_feedback = false; | 235 overdraw_feedback = false; |
| 242 } | 236 } |
| 243 base::AutoReset<bool> auto_reset_overdraw_feedback(&overdraw_feedback_, | 237 base::AutoReset<bool> auto_reset_overdraw_feedback(&overdraw_feedback_, |
| 244 overdraw_feedback); | 238 overdraw_feedback); |
| 245 | 239 |
| 246 DrawingFrame frame; | 240 DrawingFrame frame; |
| 247 frame.render_passes_in_draw_order = render_passes_in_draw_order; | 241 current_frame_ = &frame; |
|
enne (OOO)
2017/02/08 22:32:40
In general I'm pretty fine with keeping the frame
ccameron
2017/02/08 22:35:59
That was what I originally had in the patch, but t
| |
| 248 frame.root_render_pass = root_render_pass; | 242 current_frame_->render_passes_in_draw_order = render_passes_in_draw_order; |
| 249 frame.root_damage_rect = root_render_pass->damage_rect; | 243 current_frame_->root_render_pass = root_render_pass; |
| 250 frame.root_damage_rect.Union(overlay_processor_->GetAndResetOverlayDamage()); | 244 current_frame_->root_damage_rect = root_render_pass->damage_rect; |
| 251 frame.root_damage_rect.Intersect(gfx::Rect(device_viewport_size)); | 245 current_frame_->root_damage_rect.Union( |
| 252 frame.device_viewport_size = device_viewport_size; | 246 overlay_processor_->GetAndResetOverlayDamage()); |
| 253 frame.device_color_space = device_color_space; | 247 current_frame_->root_damage_rect.Intersect(gfx::Rect(device_viewport_size)); |
| 248 current_frame_->device_viewport_size = device_viewport_size; | |
| 249 current_frame_->device_color_space = device_color_space; | |
| 254 | 250 |
| 255 // Only reshape when we know we are going to draw. Otherwise, the reshape | 251 // Only reshape when we know we are going to draw. Otherwise, the reshape |
| 256 // can leave the window at the wrong size if we never draw and the proper | 252 // can leave the window at the wrong size if we never draw and the proper |
| 257 // viewport size is never set. | 253 // viewport size is never set. |
| 258 bool frame_has_alpha = frame.root_render_pass->has_transparent_background; | 254 bool frame_has_alpha = |
| 255 current_frame_->root_render_pass->has_transparent_background; | |
| 259 bool use_stencil = overdraw_feedback_; | 256 bool use_stencil = overdraw_feedback_; |
| 260 if (device_viewport_size != reshape_surface_size_ || | 257 if (device_viewport_size != reshape_surface_size_ || |
| 261 device_scale_factor != reshape_device_scale_factor_ || | 258 device_scale_factor != reshape_device_scale_factor_ || |
| 262 device_color_space != reshape_device_color_space_ || | 259 device_color_space != reshape_device_color_space_ || |
| 263 frame_has_alpha != reshape_has_alpha_ || | 260 frame_has_alpha != reshape_has_alpha_ || |
| 264 use_stencil != reshape_use_stencil_) { | 261 use_stencil != reshape_use_stencil_) { |
| 265 reshape_surface_size_ = device_viewport_size; | 262 reshape_surface_size_ = device_viewport_size; |
| 266 reshape_device_scale_factor_ = device_scale_factor; | 263 reshape_device_scale_factor_ = device_scale_factor; |
| 267 reshape_device_color_space_ = device_color_space; | 264 reshape_device_color_space_ = device_color_space; |
| 268 reshape_has_alpha_ = frame.root_render_pass->has_transparent_background; | 265 reshape_has_alpha_ = |
| 266 current_frame_->root_render_pass->has_transparent_background; | |
| 269 reshape_use_stencil_ = overdraw_feedback_; | 267 reshape_use_stencil_ = overdraw_feedback_; |
| 270 output_surface_->Reshape( | 268 output_surface_->Reshape( |
| 271 reshape_surface_size_, reshape_device_scale_factor_, | 269 reshape_surface_size_, reshape_device_scale_factor_, |
| 272 reshape_device_color_space_, reshape_has_alpha_, reshape_use_stencil_); | 270 reshape_device_color_space_, reshape_has_alpha_, reshape_use_stencil_); |
| 273 } | 271 } |
| 274 | 272 |
| 275 BeginDrawingFrame(&frame); | 273 BeginDrawingFrame(); |
| 276 | 274 |
| 277 for (const auto& pass : *render_passes_in_draw_order) { | 275 for (const auto& pass : *render_passes_in_draw_order) { |
| 278 if (!pass->filters.IsEmpty()) | 276 if (!pass->filters.IsEmpty()) |
| 279 render_pass_filters_.push_back(std::make_pair(pass->id, &pass->filters)); | 277 render_pass_filters_.push_back(std::make_pair(pass->id, &pass->filters)); |
| 280 if (!pass->background_filters.IsEmpty()) { | 278 if (!pass->background_filters.IsEmpty()) { |
| 281 render_pass_background_filters_.push_back( | 279 render_pass_background_filters_.push_back( |
| 282 std::make_pair(pass->id, &pass->background_filters)); | 280 std::make_pair(pass->id, &pass->background_filters)); |
| 283 } | 281 } |
| 284 std::sort(render_pass_filters_.begin(), render_pass_filters_.end()); | 282 std::sort(render_pass_filters_.begin(), render_pass_filters_.end()); |
| 285 std::sort(render_pass_background_filters_.begin(), | 283 std::sort(render_pass_background_filters_.begin(), |
| 286 render_pass_background_filters_.end()); | 284 render_pass_background_filters_.end()); |
| 287 } | 285 } |
| 288 | 286 |
| 289 // Draw all non-root render passes except for the root render pass. | 287 // Draw all non-root render passes except for the root render pass. |
| 290 for (const auto& pass : *render_passes_in_draw_order) { | 288 for (const auto& pass : *render_passes_in_draw_order) { |
| 291 if (pass.get() == root_render_pass) | 289 if (pass.get() == root_render_pass) |
| 292 break; | 290 break; |
| 293 DrawRenderPassAndExecuteCopyRequests(&frame, pass.get()); | 291 DrawRenderPassAndExecuteCopyRequests(pass.get()); |
| 294 } | 292 } |
| 295 | 293 |
| 296 // Create the overlay candidate for the output surface, and mark it as | 294 // Create the overlay candidate for the output surface, and mark it as |
| 297 // always handled. | 295 // always handled. |
| 298 if (output_surface_->IsDisplayedAsOverlayPlane()) { | 296 if (output_surface_->IsDisplayedAsOverlayPlane()) { |
| 299 OverlayCandidate output_surface_plane; | 297 OverlayCandidate output_surface_plane; |
| 300 output_surface_plane.display_rect = | 298 output_surface_plane.display_rect = |
| 301 gfx::RectF(root_render_pass->output_rect); | 299 gfx::RectF(root_render_pass->output_rect); |
| 302 output_surface_plane.quad_rect_in_target_space = | 300 output_surface_plane.quad_rect_in_target_space = |
| 303 root_render_pass->output_rect; | 301 root_render_pass->output_rect; |
| 304 output_surface_plane.use_output_surface_for_resource = true; | 302 output_surface_plane.use_output_surface_for_resource = true; |
| 305 output_surface_plane.overlay_handled = true; | 303 output_surface_plane.overlay_handled = true; |
| 306 frame.overlay_list.push_back(output_surface_plane); | 304 current_frame_->overlay_list.push_back(output_surface_plane); |
| 307 } | 305 } |
| 308 | 306 |
| 309 // Attempt to replace some or all of the quads of the root render pass with | 307 // Attempt to replace some or all of the quads of the root render pass with |
| 310 // overlays. | 308 // overlays. |
| 311 overlay_processor_->ProcessForOverlays( | 309 overlay_processor_->ProcessForOverlays( |
| 312 resource_provider_, root_render_pass, render_pass_filters_, | 310 resource_provider_, root_render_pass, render_pass_filters_, |
| 313 render_pass_background_filters_, &frame.overlay_list, | 311 render_pass_background_filters_, ¤t_frame_->overlay_list, |
| 314 &frame.ca_layer_overlay_list, &frame.root_damage_rect); | 312 ¤t_frame_->ca_layer_overlay_list, |
| 313 ¤t_frame_->root_damage_rect); | |
| 315 | 314 |
| 316 // We can skip all drawing if the damage rect is now empty. | 315 // We can skip all drawing if the damage rect is now empty. |
| 317 bool skip_drawing_root_render_pass = | 316 bool skip_drawing_root_render_pass = |
| 318 frame.root_damage_rect.IsEmpty() && allow_empty_swap_; | 317 current_frame_->root_damage_rect.IsEmpty() && allow_empty_swap_; |
| 319 | 318 |
| 320 // If we have to draw but don't support partial swap, the whole output should | 319 // If we have to draw but don't support partial swap, the whole output should |
| 321 // be considered damaged. | 320 // be considered damaged. |
| 322 if (!skip_drawing_root_render_pass && !use_partial_swap_) | 321 if (!skip_drawing_root_render_pass && !use_partial_swap_) |
| 323 frame.root_damage_rect = root_render_pass->output_rect; | 322 current_frame_->root_damage_rect = root_render_pass->output_rect; |
| 324 | 323 |
| 325 if (skip_drawing_root_render_pass) { | 324 if (skip_drawing_root_render_pass) { |
| 326 // If any of the overlays is the output surface, then ensure that the | 325 // If any of the overlays is the output surface, then ensure that the |
| 327 // backbuffer be allocated (allocation of the backbuffer is a side-effect | 326 // backbuffer be allocated (allocation of the backbuffer is a side-effect |
| 328 // of BindFramebufferToOutputSurface). | 327 // of BindFramebufferToOutputSurface). |
| 329 for (auto& overlay : frame.overlay_list) { | 328 for (auto& overlay : current_frame_->overlay_list) { |
| 330 if (overlay.use_output_surface_for_resource) { | 329 if (overlay.use_output_surface_for_resource) { |
| 331 BindFramebufferToOutputSurface(&frame); | 330 BindFramebufferToOutputSurface(); |
| 332 break; | 331 break; |
| 333 } | 332 } |
| 334 } | 333 } |
| 335 } else { | 334 } else { |
| 336 DrawRenderPassAndExecuteCopyRequests(&frame, root_render_pass); | 335 DrawRenderPassAndExecuteCopyRequests(root_render_pass); |
| 337 } | 336 } |
| 338 | 337 |
| 339 FinishDrawingFrame(&frame); | 338 FinishDrawingFrame(); |
| 340 render_passes_in_draw_order->clear(); | 339 render_passes_in_draw_order->clear(); |
| 341 render_pass_filters_.clear(); | 340 render_pass_filters_.clear(); |
| 342 render_pass_background_filters_.clear(); | 341 render_pass_background_filters_.clear(); |
| 342 current_frame_ = nullptr; | |
| 343 } | 343 } |
| 344 | 344 |
| 345 gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass( | 345 gfx::Rect DirectRenderer::DrawingFrame::ComputeScissorRectForRenderPass() |
| 346 const DrawingFrame* frame) { | 346 const { |
| 347 if (frame->current_render_pass == frame->root_render_pass) | 347 if (current_render_pass == root_render_pass) |
| 348 return frame->root_damage_rect; | 348 return root_damage_rect; |
| 349 | 349 |
| 350 // If the root damage rect has been expanded due to overlays, all the other | 350 // If the root damage rect has been expanded due to overlays, all the other |
| 351 // damage rect calculations are incorrect. | 351 // damage rect calculations are incorrect. |
| 352 if (!frame->root_render_pass->damage_rect.Contains(frame->root_damage_rect)) | 352 if (!root_render_pass->damage_rect.Contains(root_damage_rect)) |
| 353 return frame->current_render_pass->output_rect; | 353 return current_render_pass->output_rect; |
| 354 | 354 |
| 355 DCHECK(frame->current_render_pass->copy_requests.empty() || | 355 DCHECK( |
| 356 (frame->current_render_pass->damage_rect == | 356 current_render_pass->copy_requests.empty() || |
| 357 frame->current_render_pass->output_rect)); | 357 (current_render_pass->damage_rect == current_render_pass->output_rect)); |
| 358 return frame->current_render_pass->damage_rect; | 358 return current_render_pass->damage_rect; |
| 359 } | 359 } |
| 360 | 360 |
| 361 gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace( | 361 gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace() const { |
| 362 const DrawingFrame* frame) const { | 362 gfx::Rect device_viewport_rect(current_frame_->device_viewport_size); |
| 363 gfx::Rect device_viewport_rect(frame->device_viewport_size); | |
| 364 device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin(); | 363 device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin(); |
| 365 device_viewport_rect += current_draw_rect_.OffsetFromOrigin(); | 364 device_viewport_rect += current_draw_rect_.OffsetFromOrigin(); |
| 366 return device_viewport_rect; | 365 return device_viewport_rect; |
| 367 } | 366 } |
| 368 | 367 |
| 369 gfx::Rect DirectRenderer::OutputSurfaceRectInDrawSpace( | 368 gfx::Rect DirectRenderer::OutputSurfaceRectInDrawSpace() const { |
| 370 const DrawingFrame* frame) const { | 369 if (current_frame_->current_render_pass == current_frame_->root_render_pass) { |
| 371 if (frame->current_render_pass == frame->root_render_pass) { | 370 gfx::Rect output_surface_rect(current_frame_->device_viewport_size); |
| 372 gfx::Rect output_surface_rect(frame->device_viewport_size); | |
| 373 output_surface_rect -= current_viewport_rect_.OffsetFromOrigin(); | 371 output_surface_rect -= current_viewport_rect_.OffsetFromOrigin(); |
| 374 output_surface_rect += current_draw_rect_.OffsetFromOrigin(); | 372 output_surface_rect += current_draw_rect_.OffsetFromOrigin(); |
| 375 return output_surface_rect; | 373 return output_surface_rect; |
| 376 } else { | 374 } else { |
| 377 return frame->current_render_pass->output_rect; | 375 return current_frame_->current_render_pass->output_rect; |
| 378 } | 376 } |
| 379 } | 377 } |
| 380 | 378 |
| 381 bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad, | 379 bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad, |
| 382 const gfx::Rect& render_pass_scissor) { | 380 const gfx::Rect& render_pass_scissor) { |
| 383 if (render_pass_scissor.IsEmpty()) | 381 if (render_pass_scissor.IsEmpty()) |
| 384 return true; | 382 return true; |
| 385 | 383 |
| 386 if (quad.shared_quad_state->is_clipped) { | 384 if (quad.shared_quad_state->is_clipped) { |
| 387 gfx::Rect r = quad.shared_quad_state->clip_rect; | 385 gfx::Rect r = quad.shared_quad_state->clip_rect; |
| 388 r.Intersect(render_pass_scissor); | 386 r.Intersect(render_pass_scissor); |
| 389 return r.IsEmpty(); | 387 return r.IsEmpty(); |
| 390 } | 388 } |
| 391 | 389 |
| 392 return false; | 390 return false; |
| 393 } | 391 } |
| 394 | 392 |
| 395 void DirectRenderer::SetScissorStateForQuad( | 393 void DirectRenderer::SetScissorStateForQuad( |
| 396 const DrawingFrame* frame, | |
| 397 const DrawQuad& quad, | 394 const DrawQuad& quad, |
| 398 const gfx::Rect& render_pass_scissor, | 395 const gfx::Rect& render_pass_scissor, |
| 399 bool use_render_pass_scissor) { | 396 bool use_render_pass_scissor) { |
| 400 if (use_render_pass_scissor) { | 397 if (use_render_pass_scissor) { |
| 401 gfx::Rect quad_scissor_rect = render_pass_scissor; | 398 gfx::Rect quad_scissor_rect = render_pass_scissor; |
| 402 if (quad.shared_quad_state->is_clipped) | 399 if (quad.shared_quad_state->is_clipped) |
| 403 quad_scissor_rect.Intersect(quad.shared_quad_state->clip_rect); | 400 quad_scissor_rect.Intersect(quad.shared_quad_state->clip_rect); |
| 404 SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); | 401 SetScissorTestRectInDrawSpace(quad_scissor_rect); |
| 405 return; | 402 return; |
| 406 } else if (quad.shared_quad_state->is_clipped) { | 403 } else if (quad.shared_quad_state->is_clipped) { |
| 407 SetScissorTestRectInDrawSpace(frame, quad.shared_quad_state->clip_rect); | 404 SetScissorTestRectInDrawSpace(quad.shared_quad_state->clip_rect); |
| 408 return; | 405 return; |
| 409 } | 406 } |
| 410 | 407 |
| 411 EnsureScissorTestDisabled(); | 408 EnsureScissorTestDisabled(); |
| 412 } | 409 } |
| 413 | 410 |
| 414 void DirectRenderer::SetScissorTestRectInDrawSpace( | 411 void DirectRenderer::SetScissorTestRectInDrawSpace( |
| 415 const DrawingFrame* frame, | |
| 416 const gfx::Rect& draw_space_rect) { | 412 const gfx::Rect& draw_space_rect) { |
| 417 gfx::Rect window_space_rect = | 413 gfx::Rect window_space_rect = MoveFromDrawToWindowSpace(draw_space_rect); |
| 418 MoveFromDrawToWindowSpace(frame, draw_space_rect); | |
| 419 SetScissorTestRect(window_space_rect); | 414 SetScissorTestRect(window_space_rect); |
| 420 } | 415 } |
| 421 | 416 |
| 422 void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, | 417 void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, |
| 423 DrawingFrame* frame, | |
| 424 const gfx::Rect& render_pass_scissor, | 418 const gfx::Rect& render_pass_scissor, |
| 425 bool use_render_pass_scissor) { | 419 bool use_render_pass_scissor) { |
| 426 SetScissorStateForQuad(frame, *poly.original_ref(), render_pass_scissor, | 420 SetScissorStateForQuad(*poly.original_ref(), render_pass_scissor, |
| 427 use_render_pass_scissor); | 421 use_render_pass_scissor); |
| 428 | 422 |
| 429 // If the poly has not been split, then it is just a normal DrawQuad, | 423 // If the poly has not been split, then it is just a normal DrawQuad, |
| 430 // and we should save any extra processing that would have to be done. | 424 // and we should save any extra processing that would have to be done. |
| 431 if (!poly.is_split()) { | 425 if (!poly.is_split()) { |
| 432 DoDrawQuad(frame, poly.original_ref(), NULL); | 426 DoDrawQuad(poly.original_ref(), NULL); |
| 433 return; | 427 return; |
| 434 } | 428 } |
| 435 | 429 |
| 436 std::vector<gfx::QuadF> quads; | 430 std::vector<gfx::QuadF> quads; |
| 437 poly.ToQuads2D(&quads); | 431 poly.ToQuads2D(&quads); |
| 438 for (size_t i = 0; i < quads.size(); ++i) { | 432 for (size_t i = 0; i < quads.size(); ++i) { |
| 439 DoDrawQuad(frame, poly.original_ref(), &quads[i]); | 433 DoDrawQuad(poly.original_ref(), &quads[i]); |
| 440 } | 434 } |
| 441 } | 435 } |
| 442 | 436 |
| 443 const FilterOperations* DirectRenderer::FiltersForPass( | 437 const FilterOperations* DirectRenderer::FiltersForPass( |
| 444 int render_pass_id) const { | 438 int render_pass_id) const { |
| 445 auto it = std::lower_bound( | 439 auto it = std::lower_bound( |
| 446 render_pass_filters_.begin(), render_pass_filters_.end(), | 440 render_pass_filters_.begin(), render_pass_filters_.end(), |
| 447 std::pair<int, FilterOperations*>(render_pass_id, nullptr)); | 441 std::pair<int, FilterOperations*>(render_pass_id, nullptr)); |
| 448 if (it != render_pass_filters_.end() && it->first == render_pass_id) | 442 if (it != render_pass_filters_.end() && it->first == render_pass_id) |
| 449 return it->second; | 443 return it->second; |
| 450 return nullptr; | 444 return nullptr; |
| 451 } | 445 } |
| 452 | 446 |
| 453 const FilterOperations* DirectRenderer::BackgroundFiltersForPass( | 447 const FilterOperations* DirectRenderer::BackgroundFiltersForPass( |
| 454 int render_pass_id) const { | 448 int render_pass_id) const { |
| 455 auto it = std::lower_bound( | 449 auto it = std::lower_bound( |
| 456 render_pass_background_filters_.begin(), | 450 render_pass_background_filters_.begin(), |
| 457 render_pass_background_filters_.end(), | 451 render_pass_background_filters_.end(), |
| 458 std::pair<int, FilterOperations*>(render_pass_id, nullptr)); | 452 std::pair<int, FilterOperations*>(render_pass_id, nullptr)); |
| 459 if (it != render_pass_background_filters_.end() && | 453 if (it != render_pass_background_filters_.end() && |
| 460 it->first == render_pass_id) | 454 it->first == render_pass_id) |
| 461 return it->second; | 455 return it->second; |
| 462 return nullptr; | 456 return nullptr; |
| 463 } | 457 } |
| 464 | 458 |
| 465 void DirectRenderer::FlushPolygons( | 459 void DirectRenderer::FlushPolygons( |
| 466 std::deque<std::unique_ptr<DrawPolygon>>* poly_list, | 460 std::deque<std::unique_ptr<DrawPolygon>>* poly_list, |
| 467 DrawingFrame* frame, | |
| 468 const gfx::Rect& render_pass_scissor, | 461 const gfx::Rect& render_pass_scissor, |
| 469 bool use_render_pass_scissor) { | 462 bool use_render_pass_scissor) { |
| 470 if (poly_list->empty()) { | 463 if (poly_list->empty()) { |
| 471 return; | 464 return; |
| 472 } | 465 } |
| 473 | 466 |
| 474 BspTree bsp_tree(poly_list); | 467 BspTree bsp_tree(poly_list); |
| 475 BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor, | 468 BspWalkActionDrawPolygon action_handler(this, render_pass_scissor, |
| 476 use_render_pass_scissor); | 469 use_render_pass_scissor); |
| 477 bsp_tree.TraverseWithActionHandler(&action_handler); | 470 bsp_tree.TraverseWithActionHandler(&action_handler); |
| 478 DCHECK(poly_list->empty()); | 471 DCHECK(poly_list->empty()); |
| 479 } | 472 } |
| 480 | 473 |
| 481 void DirectRenderer::DrawRenderPassAndExecuteCopyRequests( | 474 void DirectRenderer::DrawRenderPassAndExecuteCopyRequests( |
| 482 DrawingFrame* frame, | |
| 483 RenderPass* render_pass) { | 475 RenderPass* render_pass) { |
| 484 if (render_pass_bypass_quads_.find(render_pass->id) != | 476 if (render_pass_bypass_quads_.find(render_pass->id) != |
| 485 render_pass_bypass_quads_.end()) { | 477 render_pass_bypass_quads_.end()) { |
| 486 return; | 478 return; |
| 487 } | 479 } |
| 488 | 480 |
| 489 DrawRenderPass(frame, render_pass); | 481 DrawRenderPass(render_pass); |
| 490 | 482 |
| 491 bool first_request = true; | 483 bool first_request = true; |
| 492 for (auto& copy_request : render_pass->copy_requests) { | 484 for (auto& copy_request : render_pass->copy_requests) { |
| 493 // Doing a readback is destructive of our state on Mac, so make sure | 485 // Doing a readback is destructive of our state on Mac, so make sure |
| 494 // we restore the state between readbacks. http://crbug.com/99393. | 486 // we restore the state between readbacks. http://crbug.com/99393. |
| 495 if (!first_request) | 487 if (!first_request) |
| 496 UseRenderPass(frame, render_pass); | 488 UseRenderPass(render_pass); |
| 497 CopyCurrentRenderPassToBitmap(frame, std::move(copy_request)); | 489 CopyCurrentRenderPassToBitmap(std::move(copy_request)); |
| 498 first_request = false; | 490 first_request = false; |
| 499 } | 491 } |
| 500 } | 492 } |
| 501 | 493 |
| 502 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, | 494 void DirectRenderer::DrawRenderPass(const RenderPass* render_pass) { |
| 503 const RenderPass* render_pass) { | |
| 504 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); | 495 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); |
| 505 if (!UseRenderPass(frame, render_pass)) | 496 if (!UseRenderPass(render_pass)) |
| 506 return; | 497 return; |
| 507 | 498 |
| 508 const gfx::Rect surface_rect_in_draw_space = | 499 const gfx::Rect surface_rect_in_draw_space = OutputSurfaceRectInDrawSpace(); |
| 509 OutputSurfaceRectInDrawSpace(frame); | |
| 510 gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space; | 500 gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space; |
| 511 | 501 |
| 512 if (frame->current_render_pass == frame->root_render_pass) { | 502 if (current_frame_->current_render_pass == current_frame_->root_render_pass) { |
| 513 render_pass_scissor_in_draw_space.Intersect( | 503 render_pass_scissor_in_draw_space.Intersect( |
| 514 DeviceViewportRectInDrawSpace(frame)); | 504 DeviceViewportRectInDrawSpace()); |
| 515 } | 505 } |
| 516 | 506 |
| 517 if (use_partial_swap_) { | 507 if (use_partial_swap_) { |
| 518 render_pass_scissor_in_draw_space.Intersect( | 508 render_pass_scissor_in_draw_space.Intersect( |
| 519 ComputeScissorRectForRenderPass(frame)); | 509 current_frame_->ComputeScissorRectForRenderPass()); |
| 520 } | 510 } |
| 521 | 511 |
| 522 bool render_pass_is_clipped = | 512 bool render_pass_is_clipped = |
| 523 !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space); | 513 !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space); |
| 524 bool is_root_render_pass = | 514 bool is_root_render_pass = |
| 525 frame->current_render_pass == frame->root_render_pass; | 515 current_frame_->current_render_pass == current_frame_->root_render_pass; |
| 526 bool has_external_stencil_test = | 516 bool has_external_stencil_test = |
| 527 is_root_render_pass && output_surface_->HasExternalStencilTest(); | 517 is_root_render_pass && output_surface_->HasExternalStencilTest(); |
| 528 bool should_clear_surface = | 518 bool should_clear_surface = |
| 529 !has_external_stencil_test && | 519 !has_external_stencil_test && |
| 530 (!is_root_render_pass || settings_->should_clear_root_render_pass); | 520 (!is_root_render_pass || settings_->should_clear_root_render_pass); |
| 531 | 521 |
| 532 // If |has_external_stencil_test| we can't discard or clear. Make sure we | 522 // If |has_external_stencil_test| we can't discard or clear. Make sure we |
| 533 // don't need to. | 523 // don't need to. |
| 534 DCHECK(!has_external_stencil_test || | 524 DCHECK(!has_external_stencil_test || |
| 535 !frame->current_render_pass->has_transparent_background); | 525 !current_frame_->current_render_pass->has_transparent_background); |
| 536 | 526 |
| 537 SurfaceInitializationMode mode; | 527 SurfaceInitializationMode mode; |
| 538 if (should_clear_surface && render_pass_is_clipped) { | 528 if (should_clear_surface && render_pass_is_clipped) { |
| 539 mode = SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR; | 529 mode = SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR; |
| 540 } else if (should_clear_surface) { | 530 } else if (should_clear_surface) { |
| 541 mode = SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR; | 531 mode = SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR; |
| 542 } else { | 532 } else { |
| 543 mode = SURFACE_INITIALIZATION_MODE_PRESERVE; | 533 mode = SURFACE_INITIALIZATION_MODE_PRESERVE; |
| 544 } | 534 } |
| 545 | 535 |
| 546 PrepareSurfaceForPass( | 536 PrepareSurfaceForPass( |
| 547 frame, mode, | 537 mode, MoveFromDrawToWindowSpace(render_pass_scissor_in_draw_space)); |
| 548 MoveFromDrawToWindowSpace(frame, render_pass_scissor_in_draw_space)); | |
| 549 | 538 |
| 550 const QuadList& quad_list = render_pass->quad_list; | 539 const QuadList& quad_list = render_pass->quad_list; |
| 551 std::deque<std::unique_ptr<DrawPolygon>> poly_list; | 540 std::deque<std::unique_ptr<DrawPolygon>> poly_list; |
| 552 | 541 |
| 553 int next_polygon_id = 0; | 542 int next_polygon_id = 0; |
| 554 int last_sorting_context_id = 0; | 543 int last_sorting_context_id = 0; |
| 555 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); | 544 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); |
| 556 ++it) { | 545 ++it) { |
| 557 const DrawQuad& quad = **it; | 546 const DrawQuad& quad = **it; |
| 558 | 547 |
| 559 if (render_pass_is_clipped && | 548 if (render_pass_is_clipped && |
| 560 ShouldSkipQuad(quad, render_pass_scissor_in_draw_space)) { | 549 ShouldSkipQuad(quad, render_pass_scissor_in_draw_space)) { |
| 561 continue; | 550 continue; |
| 562 } | 551 } |
| 563 | 552 |
| 564 if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) { | 553 if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) { |
| 565 last_sorting_context_id = quad.shared_quad_state->sorting_context_id; | 554 last_sorting_context_id = quad.shared_quad_state->sorting_context_id; |
| 566 FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space, | 555 FlushPolygons(&poly_list, render_pass_scissor_in_draw_space, |
| 567 render_pass_is_clipped); | 556 render_pass_is_clipped); |
| 568 } | 557 } |
| 569 | 558 |
| 570 // This layer is in a 3D sorting context so we add it to the list of | 559 // This layer is in a 3D sorting context so we add it to the list of |
| 571 // polygons to go into the BSP tree. | 560 // polygons to go into the BSP tree. |
| 572 if (quad.shared_quad_state->sorting_context_id != 0) { | 561 if (quad.shared_quad_state->sorting_context_id != 0) { |
| 573 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon( | 562 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon( |
| 574 *it, gfx::RectF(quad.visible_rect), | 563 *it, gfx::RectF(quad.visible_rect), |
| 575 quad.shared_quad_state->quad_to_target_transform, next_polygon_id++)); | 564 quad.shared_quad_state->quad_to_target_transform, next_polygon_id++)); |
| 576 if (new_polygon->points().size() > 2u) { | 565 if (new_polygon->points().size() > 2u) { |
| 577 poly_list.push_back(std::move(new_polygon)); | 566 poly_list.push_back(std::move(new_polygon)); |
| 578 } | 567 } |
| 579 continue; | 568 continue; |
| 580 } | 569 } |
| 581 | 570 |
| 582 // We are not in a 3d sorting context, so we should draw the quad normally. | 571 // We are not in a 3d sorting context, so we should draw the quad normally. |
| 583 SetScissorStateForQuad(frame, quad, render_pass_scissor_in_draw_space, | 572 SetScissorStateForQuad(quad, render_pass_scissor_in_draw_space, |
| 584 render_pass_is_clipped); | 573 render_pass_is_clipped); |
| 585 | 574 |
| 586 DoDrawQuad(frame, &quad, nullptr); | 575 DoDrawQuad(&quad, nullptr); |
| 587 } | 576 } |
| 588 FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space, | 577 FlushPolygons(&poly_list, render_pass_scissor_in_draw_space, |
| 589 render_pass_is_clipped); | 578 render_pass_is_clipped); |
| 590 FinishDrawingQuadList(); | 579 FinishDrawingQuadList(); |
| 591 } | 580 } |
| 592 | 581 |
| 593 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, | 582 bool DirectRenderer::UseRenderPass(const RenderPass* render_pass) { |
| 594 const RenderPass* render_pass) { | 583 current_frame_->current_render_pass = render_pass; |
| 595 frame->current_render_pass = render_pass; | 584 current_frame_->current_texture = NULL; |
| 596 frame->current_texture = NULL; | 585 if (render_pass == current_frame_->root_render_pass) { |
| 597 if (render_pass == frame->root_render_pass) { | 586 BindFramebufferToOutputSurface(); |
| 598 BindFramebufferToOutputSurface(frame); | 587 InitializeViewport(current_frame_, render_pass->output_rect, |
| 599 InitializeViewport(frame, render_pass->output_rect, | 588 gfx::Rect(current_frame_->device_viewport_size), |
| 600 gfx::Rect(frame->device_viewport_size), | 589 current_frame_->device_viewport_size); |
| 601 frame->device_viewport_size); | |
| 602 return true; | 590 return true; |
| 603 } | 591 } |
| 604 | 592 |
| 605 ScopedResource* texture = render_pass_textures_[render_pass->id].get(); | 593 ScopedResource* texture = render_pass_textures_[render_pass->id].get(); |
| 606 DCHECK(texture); | 594 DCHECK(texture); |
| 607 | 595 |
| 608 gfx::Size size = RenderPassTextureSize(render_pass); | 596 gfx::Size size = RenderPassTextureSize(render_pass); |
| 609 size.Enlarge(enlarge_pass_texture_amount_.width(), | 597 size.Enlarge(enlarge_pass_texture_amount_.width(), |
| 610 enlarge_pass_texture_amount_.height()); | 598 enlarge_pass_texture_amount_.height()); |
| 611 if (!texture->id()) { | 599 if (!texture->id()) { |
| 612 texture->Allocate(size, | 600 texture->Allocate(size, |
| 613 ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, | 601 ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, |
| 614 BackbufferFormat(), frame->device_color_space); | 602 BackbufferFormat(), current_frame_->device_color_space); |
| 615 } | 603 } |
| 616 DCHECK(texture->id()); | 604 DCHECK(texture->id()); |
| 617 | 605 |
| 618 if (BindFramebufferToTexture(frame, texture)) { | 606 if (BindFramebufferToTexture(texture)) { |
| 619 InitializeViewport(frame, render_pass->output_rect, | 607 InitializeViewport(current_frame_, render_pass->output_rect, |
| 620 gfx::Rect(render_pass->output_rect.size()), | 608 gfx::Rect(render_pass->output_rect.size()), |
| 621 texture->size()); | 609 texture->size()); |
| 622 return true; | 610 return true; |
| 623 } | 611 } |
| 624 | 612 |
| 625 return false; | 613 return false; |
| 626 } | 614 } |
| 627 | 615 |
| 628 bool DirectRenderer::HasAllocatedResourcesForTesting(int render_pass_id) const { | 616 bool DirectRenderer::HasAllocatedResourcesForTesting(int render_pass_id) const { |
| 629 auto iter = render_pass_textures_.find(render_pass_id); | 617 auto iter = render_pass_textures_.find(render_pass_id); |
| 630 return iter != render_pass_textures_.end() && iter->second->id(); | 618 return iter != render_pass_textures_.end() && iter->second->id(); |
| 631 } | 619 } |
| 632 | 620 |
| 633 // static | 621 // static |
| 634 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { | 622 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { |
| 635 return render_pass->output_rect.size(); | 623 return render_pass->output_rect.size(); |
| 636 } | 624 } |
| 637 | 625 |
| 638 } // namespace cc | 626 } // namespace cc |
| OLD | NEW |