diff options
author | watk <watk@chromium.org> | 2015-12-03 19:48:59 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-04 03:49:55 +0000 |
commit | c7589a8de1e21cc5a02279ddffe945af1409a655 (patch) | |
tree | 3706075b9e62e14e4bdbd22652b4fadfbd2719f3 /cc/output | |
parent | 37110bca82143bc7067750a49a37ac5fcaecf892 (diff) | |
download | chromium_src-c7589a8de1e21cc5a02279ddffe945af1409a655.zip chromium_src-c7589a8de1e21cc5a02279ddffe945af1409a655.tar.gz chromium_src-c7589a8de1e21cc5a02279ddffe945af1409a655.tar.bz2 |
Reland: DirectRenderer allows empty swap rects for CommitOverlayPlanes
Previously DirectRenderer would expand the damage rect to the full
output when partial swap buffers was not supported, because it had to
swap the whole buffer. Now, with the availability of CommitOverlayPlanes
it's possible that the surface has capability "allow_empty_swap", which
means swapping an empty rect is valid regardless of whether partial
swap is available. The surface is responsible for translating an empty
swap rect into a call to CommitOverlayPlanes.
BUG=533630
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1489153002
Cr-Commit-Position: refs/heads/master@{#363106}
Diffstat (limited to 'cc/output')
-rw-r--r-- | cc/output/direct_renderer.cc | 18 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 13 | ||||
-rw-r--r-- | cc/output/overlay_unittest.cc | 36 | ||||
-rw-r--r-- | cc/output/renderer.cc | 4 | ||||
-rw-r--r-- | cc/output/renderer.h | 3 |
5 files changed, 61 insertions, 13 deletions
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc index 4acd9c1..600805a 100644 --- a/cc/output/direct_renderer.cc +++ b/cc/output/direct_renderer.cc @@ -205,9 +205,7 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, DrawingFrame frame; frame.render_passes_in_draw_order = render_passes_in_draw_order; frame.root_render_pass = root_render_pass; - frame.root_damage_rect = Capabilities().using_partial_swap - ? root_render_pass->damage_rect - : root_render_pass->output_rect; + frame.root_damage_rect = root_render_pass->damage_rect; frame.root_damage_rect.Union(overlay_processor_->GetAndResetOverlayDamage()); frame.root_damage_rect.Intersect(gfx::Rect(device_viewport_rect.size())); frame.device_viewport_rect = device_viewport_rect; @@ -226,8 +224,7 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, if (output_surface_->IsDisplayedAsOverlayPlane()) { // Create the overlay candidate for the output surface, and mark it as - // always - // handled. + // always handled. OverlayCandidate output_surface_plane; output_surface_plane.display_rect = gfx::RectF(root_render_pass->output_rect); @@ -254,9 +251,18 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, &frame.ca_layer_overlay_list, &frame.root_damage_rect); } + // The damage rect might be empty now, but if empty swap isn't allowed we + // still have to draw. + bool should_draw = has_copy_requests || !frame.root_damage_rect.IsEmpty() || + !Capabilities().allow_empty_swap; + // If we have to draw but don't support partial swap the whole output should + // be considered damaged. + if (should_draw && !Capabilities().using_partial_swap) + frame.root_damage_rect = root_render_pass->output_rect; + // If all damage is being drawn with overlays or CALayers then skip drawing // the render passes. - if (frame.root_damage_rect.IsEmpty() && !has_copy_requests) { + if (!should_draw) { BindFramebufferToOutputSurface(&frame); } else { for (const auto& pass : *render_passes_in_draw_order) { diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index ea8031e..5c30003 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -348,6 +348,8 @@ GLRenderer::GLRenderer(RendererClient* client, capabilities_.using_partial_swap = settings_->partial_swap_enabled && context_caps.gpu.post_sub_buffer; + capabilities_.allow_empty_swap = capabilities_.using_partial_swap || + context_caps.gpu.commit_overlay_planes; DCHECK(!context_caps.gpu.iosurface || context_caps.gpu.texture_rectangle); @@ -2618,11 +2620,14 @@ void GLRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) { gfx::Rect(swap_buffer_rect_.x(), FlippedRootFramebuffer() ? flipped_y_pos_of_rect_bottom : swap_buffer_rect_.y(), - swap_buffer_rect_.width(), - swap_buffer_rect_.height()); + swap_buffer_rect_.width(), swap_buffer_rect_.height()); } else { - compositor_frame.gl_frame_data->sub_buffer_rect = - gfx::Rect(output_surface_->SurfaceSize()); + // Expand the swap rect to the full surface unless it's empty, and empty + // swap is allowed. + if (!swap_buffer_rect_.IsEmpty() || !capabilities_.allow_empty_swap) { + swap_buffer_rect_ = gfx::Rect(surface_size); + } + compositor_frame.gl_frame_data->sub_buffer_rect = swap_buffer_rect_; } output_surface_->SwapBuffers(&compositor_frame); diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index 6ee0ac5..5d1b05f 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc @@ -23,6 +23,7 @@ #include "cc/test/geometry_test_utils.h" #include "cc/test/test_context_provider.h" #include "cc/test/test_shared_bitmap_manager.h" +#include "cc/test/test_web_graphics_context_3d.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -1744,7 +1745,40 @@ TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) { Mock::VerifyAndClearExpectations(&scheduler_); } -TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawn) { +// GLRenderer skips drawing occluded quads when partial swap is enabled. +TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenPartialSwapEnabled) { + provider_->TestContext3d()->set_have_post_sub_buffer(true); + settings_.partial_swap_enabled = true; + bool use_validator = true; + Init(use_validator); + renderer_->set_expect_overlays(true); + gfx::Rect viewport_rect(16, 16); + + scoped_ptr<RenderPass> pass = CreateRenderPass(); + + CreateFullscreenCandidateQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get()); + CreateFullscreenOpaqueQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get()); + CreateFullscreenOpaqueQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get()); + + RenderPassList pass_list; + pass_list.push_back(std::move(pass)); + + output_surface_->set_is_displayed_as_overlay_plane(true); + EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(0); + EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2); + renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false); + SwapBuffers(); + Mock::VerifyAndClearExpectations(renderer_.get()); + Mock::VerifyAndClearExpectations(&scheduler_); +} + +// GLRenderer skips drawing occluded quads when empty swap is enabled. +TEST_F(GLRendererWithOverlaysTest, OccludedQuadNotDrawnWhenEmptySwapAllowed) { + provider_->TestContext3d()->set_have_commit_overlay_planes(true); bool use_validator = true; Init(use_validator); renderer_->set_expect_overlays(true); diff --git a/cc/output/renderer.cc b/cc/output/renderer.cc index 7fe0ffb..a0812c6 100644 --- a/cc/output/renderer.cc +++ b/cc/output/renderer.cc @@ -26,12 +26,12 @@ RendererCapabilitiesImpl::RendererCapabilitiesImpl() max_texture_size(0), using_shared_memory_resources(false), using_partial_swap(false), + allow_empty_swap(false), using_egl_image(false), using_image(false), using_discard_framebuffer(false), allow_rasterize_on_demand(false), - max_msaa_samples(0) { -} + max_msaa_samples(0) {} RendererCapabilitiesImpl::~RendererCapabilitiesImpl() {} diff --git a/cc/output/renderer.h b/cc/output/renderer.h index 82b3ae3..f91b039 100644 --- a/cc/output/renderer.h +++ b/cc/output/renderer.h @@ -34,6 +34,9 @@ struct RendererCapabilitiesImpl { // Capabilities used on compositor thread only. bool using_partial_swap; + // Whether it's valid to SwapBuffers with an empty rect. Trivially true when + // |using_partial_swap|. + bool allow_empty_swap; bool using_egl_image; bool using_image; bool using_discard_framebuffer; |