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" | |
15 #include "cc/output/copy_output_request.h" | 17 #include "cc/output/copy_output_request.h" |
16 #include "cc/quads/draw_quad.h" | 18 #include "cc/quads/draw_quad.h" |
17 #include "ui/gfx/geometry/rect_conversions.h" | 19 #include "ui/gfx/geometry/rect_conversions.h" |
18 #include "ui/gfx/transform.h" | 20 #include "ui/gfx/transform.h" |
19 | 21 |
20 static gfx::Transform OrthoProjectionMatrix(float left, | 22 static gfx::Transform OrthoProjectionMatrix(float left, |
21 float right, | 23 float right, |
22 float bottom, | 24 float bottom, |
23 float top) { | 25 float top) { |
24 // Use the standard formula to map the clipping frustum to the cube from | 26 // 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; | 294 return; |
293 } | 295 } |
294 if (NeedDeviceClip(frame)) { | 296 if (NeedDeviceClip(frame)) { |
295 SetScissorTestRect(DeviceClipRectInWindowSpace(frame)); | 297 SetScissorTestRect(DeviceClipRectInWindowSpace(frame)); |
296 return; | 298 return; |
297 } | 299 } |
298 | 300 |
299 EnsureScissorTestDisabled(); | 301 EnsureScissorTestDisabled(); |
300 } | 302 } |
301 | 303 |
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 | |
302 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( | 318 void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( |
303 const DrawingFrame* frame, | 319 const DrawingFrame* frame, |
304 const DrawQuad& quad, | 320 const DrawQuad& quad, |
305 const gfx::Rect& render_pass_scissor, | 321 const gfx::Rect& render_pass_scissor) { |
306 bool* should_skip_quad) { | |
307 gfx::Rect quad_scissor_rect = render_pass_scissor; | 322 gfx::Rect quad_scissor_rect = render_pass_scissor; |
308 | |
309 if (quad.isClipped()) | 323 if (quad.isClipped()) |
310 quad_scissor_rect.Intersect(quad.clipRect()); | 324 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); | 325 SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); |
319 } | 326 } |
320 | 327 |
321 void DirectRenderer::SetScissorTestRectInDrawSpace( | 328 void DirectRenderer::SetScissorTestRectInDrawSpace( |
322 const DrawingFrame* frame, | 329 const DrawingFrame* frame, |
323 const gfx::Rect& draw_space_rect) { | 330 const gfx::Rect& draw_space_rect) { |
324 gfx::Rect window_space_rect = | 331 gfx::Rect window_space_rect = |
325 MoveFromDrawToWindowSpace(frame, draw_space_rect); | 332 MoveFromDrawToWindowSpace(frame, draw_space_rect); |
326 if (NeedDeviceClip(frame)) | 333 if (NeedDeviceClip(frame)) |
327 window_space_rect.Intersect(DeviceClipRectInWindowSpace(frame)); | 334 window_space_rect.Intersect(DeviceClipRectInWindowSpace(frame)); |
328 SetScissorTestRect(window_space_rect); | 335 SetScissorTestRect(window_space_rect); |
329 } | 336 } |
330 | 337 |
331 void DirectRenderer::FinishDrawingQuadList() {} | 338 void DirectRenderer::FinishDrawingQuadList() {} |
332 | 339 |
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); | |
enne (OOO)
2015/02/12 18:00:26
style nit: early return, no else case below
(also
awoloszyn
2015/02/23 22:28:26
Done.
| |
355 } else { | |
356 std::vector<gfx::QuadF> quads; | |
357 poly.ToQuads2D(&quads); | |
358 for (unsigned int i = 0; i < quads.size(); ++i) { | |
enne (OOO)
2015/02/12 18:00:26
unsigned int => size_t
awoloszyn
2015/02/23 22:28:26
Done.
| |
359 DoDrawQuad(frame, poly.original_ref(), &quads[i]); | |
360 } | |
361 } | |
362 } | |
363 | |
364 void DirectRenderer::FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list, | |
365 DrawingFrame* frame, | |
366 const gfx::Rect& render_pass_scissor, | |
367 bool using_scissor_as_optimization) { | |
368 if (poly_list->size() == 0) { | |
369 return; | |
370 } | |
371 | |
372 BspTree bsp_tree(poly_list); | |
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(); | |
enne (OOO)
2015/02/12 18:00:26
Wouldn't the BspTree consume the entire list? If s
awoloszyn
2015/02/23 22:28:25
Actually it does make sure the list is empty. Loop
| |
378 } | |
379 | |
333 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, | 380 void DirectRenderer::DrawRenderPass(DrawingFrame* frame, |
334 const RenderPass* render_pass) { | 381 const RenderPass* render_pass) { |
335 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); | 382 TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass"); |
336 if (!UseRenderPass(frame, render_pass)) | 383 if (!UseRenderPass(frame, render_pass)) |
337 return; | 384 return; |
338 | 385 |
339 bool using_scissor_as_optimization = Capabilities().using_partial_swap; | 386 bool using_scissor_as_optimization = Capabilities().using_partial_swap; |
340 gfx::Rect render_pass_scissor; | 387 gfx::Rect render_pass_scissor; |
341 bool draw_rect_covers_full_surface = true; | 388 bool draw_rect_covers_full_surface = true; |
342 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... | |
362 | 409 |
363 bool has_external_stencil_test = | 410 bool has_external_stencil_test = |
364 output_surface_->HasExternalStencilTest() && | 411 output_surface_->HasExternalStencilTest() && |
365 frame->current_render_pass == frame->root_render_pass; | 412 frame->current_render_pass == frame->root_render_pass; |
366 | 413 |
367 DiscardPixels(has_external_stencil_test, draw_rect_covers_full_surface); | 414 DiscardPixels(has_external_stencil_test, draw_rect_covers_full_surface); |
368 ClearFramebuffer(frame, has_external_stencil_test); | 415 ClearFramebuffer(frame, has_external_stencil_test); |
369 } | 416 } |
370 | 417 |
371 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; | |
enne (OOO)
2015/02/12 18:00:26
Can you give this a better name? polygon_count? Or
awoloszyn
2015/02/23 22:28:25
Done.
| |
422 int last_context_id = 0; | |
enne (OOO)
2015/02/12 18:00:26
Please call this last_sorting_context_id. I know
awoloszyn
2015/02/23 22:28:26
Done.
| |
372 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); | 423 for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); |
373 ++it) { | 424 ++it) { |
374 const DrawQuad& quad = **it; | 425 const DrawQuad& quad = **it; |
375 bool should_skip_quad = false; | 426 gfx::QuadF send_quad(quad.visible_rect); |
427 gfx::Transform quad_transform = quad.quadTransform(); | |
enne (OOO)
2015/02/12 18:00:26
Maybe no need for this temporary, since it's only
awoloszyn
2015/02/23 22:28:26
Done.
| |
376 | 428 |
377 if (using_scissor_as_optimization) { | 429 if (using_scissor_as_optimization) { |
378 SetScissorStateForQuadWithRenderPassScissor( | 430 if (ShouldSkipQuad(quad, render_pass_scissor)) { |
379 frame, quad, render_pass_scissor, &should_skip_quad); | 431 continue; |
432 } | |
433 } | |
434 if (last_context_id != quad.shared_quad_state->sorting_context_id) { | |
435 last_context_id = quad.shared_quad_state->sorting_context_id; | |
436 FlushPolygons(&poly_list, frame, render_pass_scissor, | |
437 using_scissor_as_optimization); | |
438 } | |
439 | |
440 // This layer is in a 3D sorting context so we add it to the list of | |
441 // polygons to go into the BSP tree. | |
442 if (quad.shared_quad_state->sorting_context_id != 0) { | |
443 scoped_ptr<DrawPolygon> new_polygon( | |
444 new DrawPolygon(*it, quad.visible_rect, quad_transform, count++)); | |
445 if (new_polygon->points().size() > 2u) { | |
446 poly_list.push_back(new_polygon.Pass()); | |
447 } | |
448 continue; | |
449 } | |
450 | |
451 // We are not in a 3d sorting context, so we should draw the quad normally. | |
452 if (using_scissor_as_optimization) { | |
453 SetScissorStateForQuadWithRenderPassScissor(frame, quad, | |
454 render_pass_scissor); | |
380 } else { | 455 } else { |
381 SetScissorStateForQuad(frame, quad); | 456 SetScissorStateForQuad(frame, quad); |
382 } | 457 } |
383 | 458 |
384 if (!should_skip_quad) | 459 DoDrawQuad(frame, &quad, NULL); |
enne (OOO)
2015/02/12 18:00:26
NULL => nullptr
awoloszyn
2015/02/23 22:28:26
Done.
| |
385 DoDrawQuad(frame, &quad); | |
386 } | 460 } |
461 FlushPolygons(&poly_list, frame, render_pass_scissor, | |
enne (OOO)
2015/02/12 18:00:26
Maybe this should go in FinishDrawingQuadList with
awoloszyn
2015/02/23 22:28:26
I worried about passing the poly_list, frame, rend
enne (OOO)
2015/02/23 23:51:35
Ok, sounds good!
| |
462 using_scissor_as_optimization); | |
387 FinishDrawingQuadList(); | 463 FinishDrawingQuadList(); |
388 } | 464 } |
389 | 465 |
390 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, | 466 bool DirectRenderer::UseRenderPass(DrawingFrame* frame, |
391 const RenderPass* render_pass) { | 467 const RenderPass* render_pass) { |
392 frame->current_render_pass = render_pass; | 468 frame->current_render_pass = render_pass; |
393 frame->current_texture = NULL; | 469 frame->current_texture = NULL; |
394 | 470 |
395 if (render_pass == frame->root_render_pass) { | 471 if (render_pass == frame->root_render_pass) { |
396 BindFramebufferToOutputSurface(frame); | 472 BindFramebufferToOutputSurface(frame); |
(...skipping 22 matching lines...) Expand all Loading... | |
419 ScopedResource* texture = render_pass_textures_.get(id); | 495 ScopedResource* texture = render_pass_textures_.get(id); |
420 return texture && texture->id(); | 496 return texture && texture->id(); |
421 } | 497 } |
422 | 498 |
423 // static | 499 // static |
424 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { | 500 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { |
425 return render_pass->output_rect.size(); | 501 return render_pass->output_rect.size(); |
426 } | 502 } |
427 | 503 |
428 } // namespace cc | 504 } // namespace cc |
OLD | NEW |