summaryrefslogtreecommitdiffstats
path: root/cc/output
diff options
context:
space:
mode:
authorwatk <watk@chromium.org>2015-12-03 19:48:59 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-04 03:49:55 +0000
commitc7589a8de1e21cc5a02279ddffe945af1409a655 (patch)
tree3706075b9e62e14e4bdbd22652b4fadfbd2719f3 /cc/output
parent37110bca82143bc7067750a49a37ac5fcaecf892 (diff)
downloadchromium_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.cc18
-rw-r--r--cc/output/gl_renderer.cc13
-rw-r--r--cc/output/overlay_unittest.cc36
-rw-r--r--cc/output/renderer.cc4
-rw-r--r--cc/output/renderer.h3
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;