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