summaryrefslogtreecommitdiffstats
path: root/cc/output
diff options
context:
space:
mode:
authorwatk <watk@chromium.org>2015-12-02 14:54:25 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-02 23:04:32 +0000
commit581da2687c9e3031d07f2e0c28e32283b9b3e770 (patch)
treec29f45377b0db9497a892078aa3d6385d355baa6 /cc/output
parent3ab0ae432ebb0990c783ad8b7216c8f20a9031c7 (diff)
downloadchromium_src-581da2687c9e3031d07f2e0c28e32283b9b3e770.zip
chromium_src-581da2687c9e3031d07f2e0c28e32283b9b3e770.tar.gz
chromium_src-581da2687c9e3031d07f2e0c28e32283b9b3e770.tar.bz2
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@{#362812}
Diffstat (limited to 'cc/output')
-rw-r--r--cc/output/direct_renderer.cc18
-rw-r--r--cc/output/gl_renderer.cc13
-rw-r--r--cc/output/overlay_unittest.cc36
-rw-r--r--cc/output/renderer.h3
4 files changed, 59 insertions, 11 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.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;