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> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/auto_reset.h" | 13 #include "base/auto_reset.h" |
14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
15 #include "base/numerics/safe_conversions.h" | 15 #include "base/numerics/safe_conversions.h" |
16 #include "base/trace_event/trace_event.h" | 16 #include "base/trace_event/trace_event.h" |
17 #include "cc/base/math_util.h" | 17 #include "cc/base/math_util.h" |
18 #include "cc/output/bsp_tree.h" | 18 #include "cc/output/bsp_tree.h" |
19 #include "cc/output/bsp_walk_action.h" | 19 #include "cc/output/bsp_walk_action.h" |
20 #include "cc/output/copy_output_request.h" | 20 #include "cc/output/copy_output_request.h" |
21 #include "cc/output/renderer_settings.h" | 21 #include "cc/output/renderer_settings.h" |
22 #include "cc/quads/draw_quad.h" | 22 #include "cc/quads/draw_quad.h" |
23 #include "cc/resources/scoped_resource.h" | 23 #include "cc/resources/scoped_resource.h" |
24 #include "ui/gfx/geometry/quad_f.h" | 24 #include "ui/gfx/geometry/quad_f.h" |
25 #include "ui/gfx/geometry/rect_conversions.h" | 25 #include "ui/gfx/geometry/rect_conversions.h" |
26 #include "ui/gfx/transform.h" | 26 #include "ui/gfx/transform.h" |
27 | 27 |
| 28 namespace { |
| 29 |
28 static gfx::Transform OrthoProjectionMatrix(float left, | 30 static gfx::Transform OrthoProjectionMatrix(float left, |
29 float right, | 31 float right, |
30 float bottom, | 32 float bottom, |
31 float top) { | 33 float top) { |
32 // Use the standard formula to map the clipping frustum to the cube from | 34 // Use the standard formula to map the clipping frustum to the cube from |
33 // [-1, -1, -1] to [1, 1, 1]. | 35 // [-1, -1, -1] to [1, 1, 1]. |
34 float delta_x = right - left; | 36 float delta_x = right - left; |
35 float delta_y = top - bottom; | 37 float delta_y = top - bottom; |
36 gfx::Transform proj; | 38 gfx::Transform proj; |
37 if (!delta_x || !delta_y) | 39 if (!delta_x || !delta_y) |
(...skipping 17 matching lines...) Expand all Loading... |
55 canvas.Translate3d(x, y, 0); | 57 canvas.Translate3d(x, y, 0); |
56 canvas.Scale3d(width, height, 0); | 58 canvas.Scale3d(width, height, 0); |
57 | 59 |
58 // Map from ([-1, -1] to [1, 1]) -> ([0, 0] to [1, 1]) | 60 // Map from ([-1, -1] to [1, 1]) -> ([0, 0] to [1, 1]) |
59 canvas.Translate3d(0.5, 0.5, 0.5); | 61 canvas.Translate3d(0.5, 0.5, 0.5); |
60 canvas.Scale3d(0.5, 0.5, 0.5); | 62 canvas.Scale3d(0.5, 0.5, 0.5); |
61 | 63 |
62 return canvas; | 64 return canvas; |
63 } | 65 } |
64 | 66 |
| 67 // Switching between enabling DC layers and not is expensive, so only |
| 68 // switch away after a large number of frames not needing DC layers have |
| 69 // been produced. |
| 70 constexpr int kNumberOfFramesBeforeDisablingDCLayers = 60; |
| 71 |
| 72 } // namespace |
| 73 |
65 namespace cc { | 74 namespace cc { |
66 | 75 |
67 DirectRenderer::DrawingFrame::DrawingFrame() = default; | 76 DirectRenderer::DrawingFrame::DrawingFrame() = default; |
68 DirectRenderer::DrawingFrame::~DrawingFrame() = default; | 77 DirectRenderer::DrawingFrame::~DrawingFrame() = default; |
69 | 78 |
70 DirectRenderer::DirectRenderer(const RendererSettings* settings, | 79 DirectRenderer::DirectRenderer(const RendererSettings* settings, |
71 OutputSurface* output_surface, | 80 OutputSurface* output_surface, |
72 ResourceProvider* resource_provider) | 81 ResourceProvider* resource_provider) |
73 : settings_(settings), | 82 : settings_(settings), |
74 output_surface_(output_surface), | 83 output_surface_(output_surface), |
75 resource_provider_(resource_provider), | 84 resource_provider_(resource_provider), |
76 overlay_processor_(new OverlayProcessor(output_surface)) {} | 85 overlay_processor_(new OverlayProcessor(output_surface)) {} |
77 | 86 |
78 DirectRenderer::~DirectRenderer() = default; | 87 DirectRenderer::~DirectRenderer() = default; |
79 | 88 |
80 void DirectRenderer::Initialize() { | 89 void DirectRenderer::Initialize() { |
81 overlay_processor_->Initialize(); | 90 overlay_processor_->Initialize(); |
82 | 91 |
83 auto* context_provider = output_surface_->context_provider(); | 92 auto* context_provider = output_surface_->context_provider(); |
84 | 93 |
85 use_partial_swap_ = settings_->partial_swap_enabled && CanPartialSwap(); | 94 use_partial_swap_ = settings_->partial_swap_enabled && CanPartialSwap(); |
86 allow_empty_swap_ = use_partial_swap_; | 95 allow_empty_swap_ = use_partial_swap_; |
87 if (context_provider) { | 96 if (context_provider) { |
88 if (context_provider->ContextCapabilities().commit_overlay_planes) | 97 if (context_provider->ContextCapabilities().commit_overlay_planes) |
89 allow_empty_swap_ = true; | 98 allow_empty_swap_ = true; |
90 if (context_provider->ContextCapabilities().set_draw_rectangle) | 99 if (context_provider->ContextCapabilities().dc_layers) |
91 use_set_draw_rectangle_ = true; | 100 supports_dc_layers_ = true; |
92 } | 101 } |
93 | 102 |
94 initialized_ = true; | 103 initialized_ = true; |
95 } | 104 } |
96 | 105 |
97 // static | 106 // static |
98 gfx::RectF DirectRenderer::QuadVertexRect() { | 107 gfx::RectF DirectRenderer::QuadVertexRect() { |
99 return gfx::RectF(-0.5f, -0.5f, 1.f, 1.f); | 108 return gfx::RectF(-0.5f, -0.5f, 1.f, 1.f); |
100 } | 109 } |
101 | 110 |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 | 316 |
308 // Attempt to replace some or all of the quads of the root render pass with | 317 // Attempt to replace some or all of the quads of the root render pass with |
309 // overlays. | 318 // overlays. |
310 overlay_processor_->ProcessForOverlays( | 319 overlay_processor_->ProcessForOverlays( |
311 resource_provider_, root_render_pass, render_pass_filters_, | 320 resource_provider_, root_render_pass, render_pass_filters_, |
312 render_pass_background_filters_, ¤t_frame()->overlay_list, | 321 render_pass_background_filters_, ¤t_frame()->overlay_list, |
313 ¤t_frame()->ca_layer_overlay_list, | 322 ¤t_frame()->ca_layer_overlay_list, |
314 ¤t_frame()->dc_layer_overlay_list, | 323 ¤t_frame()->dc_layer_overlay_list, |
315 ¤t_frame()->root_damage_rect, | 324 ¤t_frame()->root_damage_rect, |
316 ¤t_frame()->root_content_bounds); | 325 ¤t_frame()->root_content_bounds); |
| 326 bool was_using_dc_layers = using_dc_layers_; |
| 327 if (!current_frame()->dc_layer_overlay_list.empty()) { |
| 328 DCHECK(supports_dc_layers_); |
| 329 using_dc_layers_ = true; |
| 330 frames_since_using_dc_layers_ = 0; |
| 331 } else if (++frames_since_using_dc_layers_ >= |
| 332 kNumberOfFramesBeforeDisablingDCLayers) { |
| 333 using_dc_layers_ = false; |
| 334 } |
| 335 if (was_using_dc_layers != using_dc_layers_) { |
| 336 current_frame()->root_damage_rect = |
| 337 current_frame()->root_render_pass->output_rect; |
| 338 } |
317 | 339 |
318 // We can skip all drawing if the damage rect is now empty. | 340 // We can skip all drawing if the damage rect is now empty. |
319 bool skip_drawing_root_render_pass = | 341 bool skip_drawing_root_render_pass = |
320 current_frame()->root_damage_rect.IsEmpty() && allow_empty_swap_; | 342 current_frame()->root_damage_rect.IsEmpty() && allow_empty_swap_; |
321 | 343 |
322 // If we have to draw but don't support partial swap, the whole output should | 344 // If we have to draw but don't support partial swap, the whole output should |
323 // be considered damaged. | 345 // be considered damaged. |
324 if (!skip_drawing_root_render_pass && !use_partial_swap_) | 346 if (!skip_drawing_root_render_pass && !use_partial_swap_) |
325 current_frame()->root_damage_rect = root_render_pass->output_rect; | 347 current_frame()->root_damage_rect = root_render_pass->output_rect; |
326 | 348 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 } | 538 } |
517 | 539 |
518 bool is_root_render_pass = | 540 bool is_root_render_pass = |
519 current_frame()->current_render_pass == current_frame()->root_render_pass; | 541 current_frame()->current_render_pass == current_frame()->root_render_pass; |
520 | 542 |
521 // The SetDrawRectangleCHROMIUM spec requires that the scissor bit is always | 543 // The SetDrawRectangleCHROMIUM spec requires that the scissor bit is always |
522 // set on the root framebuffer or else the rendering may modify something | 544 // set on the root framebuffer or else the rendering may modify something |
523 // outside the damage rectangle, even if the damage rectangle is the size of | 545 // outside the damage rectangle, even if the damage rectangle is the size of |
524 // the full backbuffer. | 546 // the full backbuffer. |
525 bool render_pass_is_clipped = | 547 bool render_pass_is_clipped = |
526 (use_set_draw_rectangle_ && is_root_render_pass) || | 548 (supports_dc_layers_ && is_root_render_pass) || |
527 !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space); | 549 !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space); |
528 bool has_external_stencil_test = | 550 bool has_external_stencil_test = |
529 is_root_render_pass && output_surface_->HasExternalStencilTest(); | 551 is_root_render_pass && output_surface_->HasExternalStencilTest(); |
530 bool should_clear_surface = | 552 bool should_clear_surface = |
531 !has_external_stencil_test && | 553 !has_external_stencil_test && |
532 (!is_root_render_pass || settings_->should_clear_root_render_pass); | 554 (!is_root_render_pass || settings_->should_clear_root_render_pass); |
533 | 555 |
534 // If |has_external_stencil_test| we can't discard or clear. Make sure we | 556 // If |has_external_stencil_test| we can't discard or clear. Make sure we |
535 // don't need to. | 557 // don't need to. |
536 DCHECK(!has_external_stencil_test || | 558 DCHECK(!has_external_stencil_test || |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 render_pass_is_clipped); | 612 render_pass_is_clipped); |
591 FinishDrawingQuadList(); | 613 FinishDrawingQuadList(); |
592 } | 614 } |
593 | 615 |
594 bool DirectRenderer::UseRenderPass(const RenderPass* render_pass) { | 616 bool DirectRenderer::UseRenderPass(const RenderPass* render_pass) { |
595 current_frame()->current_render_pass = render_pass; | 617 current_frame()->current_render_pass = render_pass; |
596 current_frame()->current_texture = nullptr; | 618 current_frame()->current_texture = nullptr; |
597 if (render_pass == current_frame()->root_render_pass) { | 619 if (render_pass == current_frame()->root_render_pass) { |
598 BindFramebufferToOutputSurface(); | 620 BindFramebufferToOutputSurface(); |
599 | 621 |
600 if (use_set_draw_rectangle_) | 622 if (supports_dc_layers_) { |
| 623 SetEnableDCLayers(using_dc_layers_); |
601 output_surface_->SetDrawRectangle(current_frame()->root_damage_rect); | 624 output_surface_->SetDrawRectangle(current_frame()->root_damage_rect); |
| 625 } |
602 InitializeViewport(current_frame(), render_pass->output_rect, | 626 InitializeViewport(current_frame(), render_pass->output_rect, |
603 gfx::Rect(current_frame()->device_viewport_size), | 627 gfx::Rect(current_frame()->device_viewport_size), |
604 current_frame()->device_viewport_size); | 628 current_frame()->device_viewport_size); |
605 return true; | 629 return true; |
606 } | 630 } |
607 | 631 |
608 ScopedResource* texture = render_pass_textures_[render_pass->id].get(); | 632 ScopedResource* texture = render_pass_textures_[render_pass->id].get(); |
609 DCHECK(texture); | 633 DCHECK(texture); |
610 | 634 |
611 gfx::Size size = RenderPassTextureSize(render_pass); | 635 gfx::Size size = RenderPassTextureSize(render_pass); |
(...skipping 25 matching lines...) Expand all Loading... |
637 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { | 661 gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) { |
638 return render_pass->output_rect.size(); | 662 return render_pass->output_rect.size(); |
639 } | 663 } |
640 | 664 |
641 void DirectRenderer::SetCurrentFrameForTesting(const DrawingFrame& frame) { | 665 void DirectRenderer::SetCurrentFrameForTesting(const DrawingFrame& frame) { |
642 current_frame_valid_ = true; | 666 current_frame_valid_ = true; |
643 current_frame_ = frame; | 667 current_frame_ = frame; |
644 } | 668 } |
645 | 669 |
646 } // namespace cc | 670 } // namespace cc |
OLD | NEW |