summaryrefslogtreecommitdiffstats
path: root/cc/output
diff options
context:
space:
mode:
authoraelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-05 00:43:28 +0000
committeraelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-05 00:43:28 +0000
commit54af0352fb8c3b48b0f379ea1c48006aa1c34615 (patch)
tree8c00bd00f8cde9adbfd90db018205cf2e669d666 /cc/output
parent576748e8df1fdb8a21958671fe860946f12c82f5 (diff)
downloadchromium_src-54af0352fb8c3b48b0f379ea1c48006aa1c34615.zip
chromium_src-54af0352fb8c3b48b0f379ea1c48006aa1c34615.tar.gz
chromium_src-54af0352fb8c3b48b0f379ea1c48006aa1c34615.tar.bz2
Fix UpdateTilePriorities viewport in Android WebView.
This patch fixes the tile management viewport to be the on-screen-visible rect for the last hardware draw. There are two problems I needed to solve: 1) Suppress UpdateTilePriorities from happening when the last draw was a software draw, which is specified by the new "viewport_valid_for_tile_management" bool. 2) In some cases, the clip rect is smaller than the WebView's visible viewport -- for example when the Android Browser progress bar is forcing redraws, the clip is only a small area at the top of the screen. I switched to using the visible viewport for UpdateDrawProperties + glViewport, and introduce a separate "DeviceClip" to override glScissor. (It's necessary to make the change at this level, rather than directly plumbing the visible viewport to UpdateTilePriorities, because UpdateTilePriorities also makes use of outputs from the draw properties calculation.) I also cleaned up all uses of device_viewport_size() to call DrawViewportSize() instead, with the sole exception of UnscaledScrollableViewportSize() which should continue to use the main-thread device_viewport_size_ in all cases (because that's the viewport for scrolling, not drawing). New tests: PictureLayerImplTest.SuppressUpdateTilePriorities, ExternalStencilPixelTest.DeviceClip NOTRY=true BUG=232844 Review URL: https://chromiumcodereview.appspot.com/23171014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221321 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/output')
-rw-r--r--cc/output/delegating_renderer_unittest.cc5
-rw-r--r--cc/output/direct_renderer.cc43
-rw-r--r--cc/output/direct_renderer.h4
-rw-r--r--cc/output/gl_renderer_unittest.cc3
-rw-r--r--cc/output/output_surface.cc7
-rw-r--r--cc/output/output_surface.h4
-rw-r--r--cc/output/output_surface_client.h4
-rw-r--r--cc/output/renderer.h7
-rw-r--r--cc/output/renderer_pixeltest.cc25
-rw-r--r--cc/output/software_renderer_unittest.cc3
10 files changed, 88 insertions, 17 deletions
diff --git a/cc/output/delegating_renderer_unittest.cc b/cc/output/delegating_renderer_unittest.cc
index b1e7c77..ffa7e4f 100644
--- a/cc/output/delegating_renderer_unittest.cc
+++ b/cc/output/delegating_renderer_unittest.cc
@@ -66,9 +66,8 @@ class DelegatingRendererTestDraw : public DelegatingRendererTest {
DelegatedFrameData* last_frame_data = last_frame.delegated_frame_data.get();
ASSERT_TRUE(last_frame.delegated_frame_data);
EXPECT_FALSE(last_frame.gl_frame_data);
- EXPECT_EQ(
- gfx::Rect(host_impl->device_viewport_size()).ToString(),
- last_frame_data->render_pass_list.back()->output_rect.ToString());
+ EXPECT_EQ(host_impl->DeviceViewport().ToString(),
+ last_frame_data->render_pass_list.back()->output_rect.ToString());
EXPECT_EQ(0.5f, last_frame.metadata.min_page_scale_factor);
EXPECT_EQ(4.f, last_frame.metadata.max_page_scale_factor);
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc
index 87eefba..15f8501 100644
--- a/cc/output/direct_renderer.cc
+++ b/cc/output/direct_renderer.cc
@@ -260,14 +260,33 @@ gfx::RectF DirectRenderer::ComputeScissorRectForRenderPass(
return render_pass_scissor;
}
+bool DirectRenderer::NeedDeviceClip(const DrawingFrame* frame) const {
+ if (frame->current_render_pass != frame->root_render_pass)
+ return false;
+
+ return !client_->DeviceClip().Contains(client_->DeviceViewport());
+}
+
+gfx::Rect DirectRenderer::DeviceClipRect(const DrawingFrame* frame) const {
+ gfx::Rect device_clip_rect = client_->DeviceClip();
+ if (FlippedFramebuffer())
+ device_clip_rect.set_y(current_surface_size_.height() -
+ device_clip_rect.bottom());
+ return device_clip_rect;
+}
+
void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame,
const DrawQuad& quad) {
if (quad.isClipped()) {
- gfx::RectF quad_scissor_rect = quad.clipRect();
- SetScissorTestRect(MoveFromDrawToWindowSpace(quad_scissor_rect));
- } else {
- EnsureScissorTestDisabled();
+ SetScissorTestRectInDrawSpace(frame, quad.clipRect());
+ return;
+ }
+ if (NeedDeviceClip(frame)) {
+ SetScissorTestRect(DeviceClipRect(frame));
+ return;
}
+
+ EnsureScissorTestDisabled();
}
void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor(
@@ -286,7 +305,15 @@ void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor(
}
*should_skip_quad = false;
- SetScissorTestRect(MoveFromDrawToWindowSpace(quad_scissor_rect));
+ SetScissorTestRectInDrawSpace(frame, quad_scissor_rect);
+}
+
+void DirectRenderer::SetScissorTestRectInDrawSpace(const DrawingFrame* frame,
+ gfx::RectF draw_space_rect) {
+ gfx::Rect window_space_rect = MoveFromDrawToWindowSpace(draw_space_rect);
+ if (NeedDeviceClip(frame))
+ window_space_rect.Intersect(DeviceClipRect(frame));
+ SetScissorTestRect(window_space_rect);
}
void DirectRenderer::FinishDrawingQuadList() {}
@@ -303,12 +330,14 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
if (using_scissor_as_optimization) {
render_pass_scissor = ComputeScissorRectForRenderPass(frame);
- SetScissorTestRect(MoveFromDrawToWindowSpace(render_pass_scissor));
+ SetScissorTestRectInDrawSpace(frame, render_pass_scissor);
}
if (frame->current_render_pass != frame->root_render_pass ||
client_->ShouldClearRootRenderPass()) {
- if (!using_scissor_as_optimization)
+ if (NeedDeviceClip(frame))
+ SetScissorTestRect(DeviceClipRect(frame));
+ else if (!using_scissor_as_optimization)
EnsureScissorTestDisabled();
ClearFramebuffer(frame);
}
diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h
index 504eaef..3937619 100644
--- a/cc/output/direct_renderer.h
+++ b/cc/output/direct_renderer.h
@@ -89,6 +89,8 @@ class CC_EXPORT DirectRenderer : public Renderer {
gfx::Size surface_size);
gfx::Rect MoveFromDrawToWindowSpace(const gfx::RectF& draw_rect) const;
+ bool NeedDeviceClip(const DrawingFrame* frame) const;
+ gfx::Rect DeviceClipRect(const DrawingFrame* frame) const;
static gfx::RectF ComputeScissorRectForRenderPass(const DrawingFrame* frame);
void SetScissorStateForQuad(const DrawingFrame* frame, const DrawQuad& quad);
void SetScissorStateForQuadWithRenderPassScissor(
@@ -96,6 +98,8 @@ class CC_EXPORT DirectRenderer : public Renderer {
const DrawQuad& quad,
const gfx::RectF& render_pass_scissor,
bool* should_skip_quad);
+ void SetScissorTestRectInDrawSpace(const DrawingFrame* frame,
+ gfx::RectF draw_space_rect);
static gfx::Size RenderPassTextureSize(const RenderPass* render_pass);
static GLenum RenderPassTextureFormat(const RenderPass* render_pass);
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index c12bbfe..0e153c1 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -158,6 +158,9 @@ class FakeRendererClient : public RendererClient {
static gfx::Size fake_size(1, 1);
return gfx::Rect(fake_size);
}
+ virtual gfx::Rect DeviceClip() const OVERRIDE {
+ return DeviceViewport();
+ }
virtual float DeviceScaleFactor() const OVERRIDE {
return scale_factor_;
}
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index 19683b2..bd2e8c1 100644
--- a/cc/output/output_surface.cc
+++ b/cc/output/output_surface.cc
@@ -224,8 +224,11 @@ void OutputSurface::SetExternalStencilTest(bool enabled) {
}
void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
- gfx::Rect viewport) {
- client_->SetExternalDrawConstraints(transform, viewport);
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) {
+ client_->SetExternalDrawConstraints(
+ transform, viewport, clip, valid_for_tile_management);
}
OutputSurface::~OutputSurface() {
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
index a94d41ef..84d128a 100644
--- a/cc/output/output_surface.h
+++ b/cc/output/output_surface.h
@@ -168,7 +168,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
void DidLoseOutputSurface();
void SetExternalStencilTest(bool enabled);
void SetExternalDrawConstraints(const gfx::Transform& transform,
- gfx::Rect viewport);
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management);
// virtual for testing.
virtual base::TimeDelta AlternateRetroactiveBeginFramePeriod();
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h
index 4d17622..7b59513 100644
--- a/cc/output/output_surface_client.h
+++ b/cc/output/output_surface_client.h
@@ -36,7 +36,9 @@ class CC_EXPORT OutputSurfaceClient {
virtual void DidLoseOutputSurface() = 0;
virtual void SetExternalStencilTest(bool enabled) = 0;
virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
- gfx::Rect viewport) = 0;
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) = 0;
virtual void SetDiscardBackBufferWhenNotVisible(bool discard) = 0;
virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0;
// If set, |callback| will be called subsequent to each new tree activation,
diff --git a/cc/output/renderer.h b/cc/output/renderer.h
index 9619852..7624a5b 100644
--- a/cc/output/renderer.h
+++ b/cc/output/renderer.h
@@ -18,10 +18,11 @@ class ScopedResource;
class CC_EXPORT RendererClient {
public:
- // Draw viewport in non-y-flipped window space. Note that while a draw is in
- // progress, this is guaranteed to be contained within the output surface
- // size.
+ // These return the draw viewport and clip in non-y-flipped window space.
+ // Note that while a draw is in progress, these are guaranteed to be
+ // contained within the output surface size.
virtual gfx::Rect DeviceViewport() const = 0;
+ virtual gfx::Rect DeviceClip() const = 0;
virtual float DeviceScaleFactor() const = 0;
virtual const LayerTreeSettings& Settings() const = 0;
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index e8d1323..cd74e50 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -1149,6 +1149,31 @@ TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
ExactPixelComparator(true)));
}
+TEST_F(ExternalStencilPixelTest, DeviceClip) {
+ ClearBackgroundToGreen();
+ gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
+ this->ForceDeviceClip(clip_rect);
+
+ // Draw a blue quad that covers the entire device viewport. It should be
+ // clipped to the bottom right corner by the device clip.
+ gfx::Rect rect(this->device_viewport_size_);
+ RenderPass::Id id(1, 1);
+ scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+ scoped_ptr<SharedQuadState> blue_shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), rect);
+ scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
+ blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false);
+ pass->quad_list.push_back(blue.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list,
+ PixelTest::NoOffscreenContext,
+ base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
+ ExactPixelComparator(true)));
+}
+
// Software renderer does not support anti-aliased edges.
TEST_F(GLRendererPixelTest, AntiAliasing) {
gfx::Rect rect(this->device_viewport_size_);
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc
index ba1a0da..6125fb6 100644
--- a/cc/output/software_renderer_unittest.cc
+++ b/cc/output/software_renderer_unittest.cc
@@ -58,6 +58,9 @@ class SoftwareRendererTest : public testing::Test, public RendererClient {
virtual gfx::Rect DeviceViewport() const OVERRIDE {
return viewport_;
}
+ virtual gfx::Rect DeviceClip() const OVERRIDE {
+ return DeviceViewport();
+ }
virtual float DeviceScaleFactor() const OVERRIDE {
return 1.f;
}