| 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 <hash_map> |
| 8 #include <list> |
| 9 #include <set> |
| 7 #include <utility> | 10 #include <utility> |
| 8 #include <vector> | 11 #include <vector> |
| 9 | 12 |
| 10 #include "base/containers/hash_tables.h" | 13 #include "base/containers/hash_tables.h" |
| 11 #include "base/containers/scoped_ptr_hash_map.h" | 14 #include "base/containers/scoped_ptr_hash_map.h" |
| 12 #include "base/debug/trace_event.h" | 15 #include "base/debug/trace_event.h" |
| 13 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 14 #include "cc/base/math_util.h" | 17 #include "cc/base/math_util.h" |
| 18 #include "cc/output/bsp_tree.h" |
| 19 #include "cc/output/bsp_walk_action.h" |
| 15 #include "cc/output/copy_output_request.h" | 20 #include "cc/output/copy_output_request.h" |
| 16 #include "cc/quads/draw_quad.h" | 21 #include "cc/quads/draw_quad.h" |
| 17 #include "ui/gfx/geometry/rect_conversions.h" | 22 #include "ui/gfx/geometry/rect_conversions.h" |
| 18 #include "ui/gfx/transform.h" | 23 #include "ui/gfx/transform.h" |
| 19 | 24 |
| 20 static gfx::Transform OrthoProjectionMatrix(float left, | 25 static gfx::Transform OrthoProjectionMatrix(float left, |
| 21 float right, | 26 float right, |
| 22 float bottom, | 27 float bottom, |
| 23 float top) { | 28 float top) { |
| 24 // Use the standard formula to map the clipping frustum to the cube from | 29 // Use the standard formula to map the clipping frustum to the cube from |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 return; | 297 return; |
| 293 } | 298 } |
| 294 if (NeedDeviceClip(frame)) { | 299 if (NeedDeviceClip(frame)) { |
| 295 SetScissorTestRect(DeviceClipRectInWindowSpace(frame)); | 300 SetScissorTestRect(DeviceClipRectInWindowSpace(frame)); |
| 296 return; | 301 return; |
| 297 } | 302 } |
| 298 | 303 |
| 299 EnsureScissorTestDisabled(); | 304 EnsureScissorTestDisabled(); |
| 300 } | 305 } |
| 301 | 306 |
| 307 bool DirectRenderer::ShouldSkipQuad( |
| 308 const DrawQuad& quad, |
| 309 const gfx::Rect& render_pass_scissor |
| 310 ) { |
| 311 if(render_pass_scissor.IsEmpty()) |
| 312 return true; |
| 313 |
| 314 if (quad.isClipped()) { |
| 315 gfx::Rect r = quad.clipRect(); |
| 316 r.Intersect(render_pass_scissor); |
| 317 return r.IsEmpty(); |
| 318 } |
| 319 |
| 320 return false; |
| 321 } |
| 322 |
| 323 |
| 302 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( | 324 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( |
| 303 const DrawingFrame* frame, | 325 const DrawingFrame* frame, |
| 304 const DrawQuad& quad, | 326 const DrawQuad& quad, |
| 305 const gfx::Rect& render_pass_scissor, | 327 const gfx::Rect& render_pass_scissor) { |
| 306 bool* should_skip_quad) { | |
| 307 gfx::Rect quad_scissor_rect = render_pass_scissor; | 328 gfx::Rect quad_scissor_rect = render_pass_scissor; |
| 308 | |
| 309 if (quad.isClipped()) | 329 if (quad.isClipped()) |
| 310 quad_scissor_rect.Intersect(quad.clipRect()); | 330 quad_scissor_rect.Intersect(quad.clipRect()); |
| 311 | |
| 312 if (quad_scissor_rect.IsEmpty()) { | |
| 313 *should_skip_quad = true; | |
| 314 return; | |
| 315 } | |
| 316 | |
| 317 *should_skip_quad = false; | |
| 318 SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); | 331 SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); |
| 319 } | 332 } |
| 320 | 333 |
| 321 void DirectRenderer::SetScissorTestRectInDrawSpace( | 334 void DirectRenderer::SetScissorTestRectInDrawSpace( |
| 322 const DrawingFrame* frame, | 335 const DrawingFrame* frame, |
| 323 const gfx::Rect& draw_space_rect) { | 336 const gfx::Rect& draw_space_rect) { |
| 324 gfx::Rect window_space_rect = MoveFromDrawToWindowSpace(draw_space_rect); | 337 gfx::Rect window_space_rect = MoveFromDrawToWindowSpace(draw_space_rect); |
| 325 if (NeedDeviceClip(frame)) | 338 if (NeedDeviceClip(frame)) |
| 326 window_space_rect.Intersect(DeviceClipRectInWindowSpace(frame)); | 339 window_space_rect.Intersect(DeviceClipRectInWindowSpace(frame)); |
| 327 SetScissorTestRect(window_space_rect); | 340 SetScissorTestRect(window_space_rect); |
| 328 } | 341 } |
| 329 | 342 |
| 330 void DirectRenderer::FinishDrawingQuadList() {} | 343 void DirectRenderer::FinishDrawingQuadList() {} |
| 331 | 344 |
| 345 void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, |
| 346 DrawingFrame* frame, |
| 347 const gfx::Rect& render_pass_scissor, |
| 348 bool using_scissor_as_optimization) { |
| 349 if (using_scissor_as_optimization) { |
| 350 SetScissorStateForQuadWithRenderPassScissor( |
| 351 frame, *poly.original_ref(), render_pass_scissor); |
| 352 } else { |
| 353 SetScissorStateForQuad(frame, *poly.original_ref()); |
| 354 } |
| 355 std::vector<gfx::QuadF> quads; |
| 356 poly.ToQuads2D(&quads); |
| 357 for (unsigned int i = 0; i < quads.size(); ++i) { |
| 358 DoDrawQuad(frame, poly.original_ref(), &quads[i]); |
| 359 } |
| 360 } |
| 361 |
| 362 void DirectRenderer::FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list, |
| 363 DrawingFrame* frame, |
| 364 const gfx::Rect& render_pass_scissor, |
| 365 bool using_scissor_as_optimization) { |
| 366 if (poly_list->size() == 0) { |
| 367 return; |
| 368 } |
| 369 |
| 370 BspTree bsp_tree(poly_list); |
| 371 // Very important to use a new list here because we're relying on the old |
| 372 // list to be intact for cleanup |
| 373 BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor, |
| 374 using_scissor_as_optimization); |
| 375 bsp_tree.TraverseWithActionHandler(&action_handler); |
| 376 // Clear the polygon list for the next transformation layer block |
| 377 poly_list->clear(); |
| 378 } |
| 379 |
| 332 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, | 380 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, |
| 333 const RenderPass* render_pass) { | 381 const RenderPass* render_pass) { |
| 334 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); | 382 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); |
| 335 if (!UseRenderPass(frame, render_pass)) | 383 if (!UseRenderPass(frame, render_pass)) |
| 336 return; | 384 return; |
| 337 | 385 |
| 338 bool using_scissor_as_optimization = Capabilities().using_partial_swap; | 386 bool using_scissor_as_optimization = Capabilities().using_partial_swap; |
| 339 gfx::Rect render_pass_scissor; | 387 gfx::Rect render_pass_scissor; |
| 340 bool draw_rect_covers_full_surface = true; | 388 bool draw_rect_covers_full_surface = true; |
| 341 if (frame->current_render_pass == frame->root_render_pass && | 389 if (frame->current_render_pass == frame->root_render_pass && |
| (...skipping 19 matching lines...) Expand all Loading... |
| 361 | 409 |
| 362 bool has_external_stencil_test = | 410 bool has_external_stencil_test = |
| 363 output_surface_->HasExternalStencilTest() && | 411 output_surface_->HasExternalStencilTest() && |
| 364 frame->current_render_pass == frame->root_render_pass; | 412 frame->current_render_pass == frame->root_render_pass; |
| 365 | 413 |
| 366 DiscardPixels(has_external_stencil_test, draw_rect_covers_full_surface); | 414 DiscardPixels(has_external_stencil_test, draw_rect_covers_full_surface); |
| 367 ClearFramebuffer(frame, has_external_stencil_test); | 415 ClearFramebuffer(frame, has_external_stencil_test); |
| 368 } | 416 } |
| 369 | 417 |
| 370 const QuadList& quad_list = render_pass->quad_list; | 418 const QuadList& quad_list = render_pass->quad_list; |
| 419 ScopedPtrDeque<DrawPolygon> poly_list; |
| 420 |
| 421 int count = 0; |
| 422 int last_context_id = 0; |
| 371 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin(); | 423 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin(); |
| 372 it != quad_list.BackToFrontEnd(); | 424 it != quad_list.BackToFrontEnd(); |
| 373 ++it) { | 425 ++it) { |
| 374 const DrawQuad& quad = *(*it); | 426 DrawQuad& quad = *(*it); |
| 375 bool should_skip_quad = false; | 427 gfx::QuadF send_quad(quad.visible_rect); |
| 428 gfx::Transform quad_transform = quad.quadTransform(); |
| 429 |
| 430 if (using_scissor_as_optimization) { |
| 431 if (ShouldSkipQuad(quad, render_pass_scissor)) { |
| 432 continue; |
| 433 } |
| 434 } |
| 435 if (last_context_id != quad.shared_quad_state->sorting_context_id) { |
| 436 last_context_id = quad.shared_quad_state->sorting_context_id; |
| 437 FlushPolygons(&poly_list, frame, |
| 438 render_pass_scissor, using_scissor_as_optimization); |
| 439 } |
| 440 |
| 441 // This layer is in a 3D sorting context so we add it to the list of |
| 442 // polygons to go into the BSP tree. |
| 443 if (quad.shared_quad_state->sorting_context_id != 0) { |
| 444 scoped_ptr<DrawPolygon> new_polygon( |
| 445 new DrawPolygon(*it, quad.visible_rect, quad_transform, count++)); |
| 446 if (new_polygon->points().size() > 2u) { |
| 447 poly_list.push_back(new_polygon.Pass()); |
| 448 } |
| 449 continue; |
| 450 } |
| 376 | 451 |
| 377 if (using_scissor_as_optimization) { | 452 if (using_scissor_as_optimization) { |
| 378 SetScissorStateForQuadWithRenderPassScissor( | 453 SetScissorStateForQuadWithRenderPassScissor( |
| 379 frame, quad, render_pass_scissor, &should_skip_quad); | 454 frame, quad, render_pass_scissor); |
| 380 } else { | 455 } else { |
| 381 SetScissorStateForQuad(frame, quad); | 456 SetScissorStateForQuad(frame, quad); |
| 382 } | 457 } |
| 383 | 458 // Go ahead and draw the flat layers as normal and reset the draw mode |
| 384 if (!should_skip_quad) | 459 // flag to show that we're now drawing flat layers |
| 385 DoDrawQuad(frame, *it); | 460 DoDrawQuad(frame, *it); |
| 386 } | 461 } |
| 462 FlushPolygons(&poly_list, frame, |
| 463 render_pass_scissor, using_scissor_as_optimization); |
| 387 FinishDrawingQuadList(); | 464 FinishDrawingQuadList(); |
| 388 } | 465 } |
| 389 | 466 |
| 390 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, | 467 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, |
| 391 const RenderPass* render_pass) { | 468 const RenderPass* render_pass) { |
| 392 frame->current_render_pass = render_pass; | 469 frame->current_render_pass = render_pass; |
| 393 frame->current_texture = NULL; | 470 frame->current_texture = NULL; |
| 394 | 471 |
| 395 if (render_pass == frame->root_render_pass) { | 472 if (render_pass == frame->root_render_pass) { |
| 396 BindFramebufferToOutputSurface(frame); | 473 BindFramebufferToOutputSurface(frame); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 419 ScopedResource* texture = render_pass_textures_.get(id); | 496 ScopedResource* texture = render_pass_textures_.get(id); |
| 420 return texture && texture->id(); | 497 return texture && texture->id(); |
| 421 } | 498 } |
| 422 | 499 |
| 423 // static | 500 // static |
| 424 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { | 501 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { |
| 425 return render_pass->output_rect.size(); | 502 return render_pass->output_rect.size(); |
| 426 } | 503 } |
| 427 | 504 |
| 428 } // namespace cc | 505 } // namespace cc |
| OLD | NEW |