summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--android_webview/browser/in_process_view_renderer.cc9
-rw-r--r--cc/debug/overdraw_metrics.cc14
-rw-r--r--cc/layers/picture_layer_impl.cc18
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc45
-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
-rw-r--r--cc/test/fake_layer_tree_host_impl.cc11
-rw-r--r--cc/test/fake_layer_tree_host_impl.h5
-rw-r--r--cc/test/fake_output_surface_client.h7
-rw-r--r--cc/test/pixel_test.cc21
-rw-r--r--cc/test/pixel_test.h1
-rw-r--r--cc/test/pixel_test_output_surface.cc6
-rw-r--r--cc/test/pixel_test_output_surface.h4
-rw-r--r--cc/trees/layer_tree_host_impl.cc35
-rw-r--r--cc/trees/layer_tree_host_impl.h55
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc5
-rw-r--r--cc/trees/layer_tree_host_unittest.cc4
-rw-r--r--cc/trees/layer_tree_impl.cc23
-rw-r--r--cc/trees/layer_tree_impl.h3
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.cc7
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.h3
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.cc42
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.h11
-rw-r--r--content/public/browser/android/synchronous_compositor.h5
32 files changed, 348 insertions, 91 deletions
diff --git a/android_webview/browser/in_process_view_renderer.cc b/android_webview/browser/in_process_view_renderer.cc
index bcf2ca4..7964cfd 100644
--- a/android_webview/browser/in_process_view_renderer.cc
+++ b/android_webview/browser/in_process_view_renderer.cc
@@ -387,15 +387,20 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) {
// Assume we always draw the full visible rect if we are drawing into a layer.
bool drew_full_visible_rect = true;
+ gfx::Rect viewport_rect;
if (!draw_info->is_layer) {
- clip_rect.Intersect(cached_global_visible_rect_);
- drew_full_visible_rect = clip_rect.Contains(cached_global_visible_rect_);
+ viewport_rect = cached_global_visible_rect_;
+ clip_rect.Intersect(viewport_rect);
+ drew_full_visible_rect = clip_rect.Contains(viewport_rect);
+ } else {
+ viewport_rect = clip_rect;
}
block_invalidates_ = true;
// TODO(joth): Check return value.
compositor_->DemandDrawHw(gfx::Size(draw_info->width, draw_info->height),
transform,
+ viewport_rect,
clip_rect,
state_restore.stencil_enabled());
block_invalidates_ = false;
diff --git a/cc/debug/overdraw_metrics.cc b/cc/debug/overdraw_metrics.cc
index 5b19370..a14284d 100644
--- a/cc/debug/overdraw_metrics.cc
+++ b/cc/debug/overdraw_metrics.cc
@@ -147,11 +147,11 @@ void OverdrawMetrics::RecordMetrics(
}
}
-static gfx::Size DeviceViewportSize(const LayerTreeHost* host) {
+static gfx::Size DrawViewportSize(const LayerTreeHost* host) {
return host->device_viewport_size();
}
-static gfx::Size DeviceViewportSize(const LayerTreeHostImpl* host_impl) {
- return host_impl->device_viewport_size();
+static gfx::Size DrawViewportSize(const LayerTreeHostImpl* host_impl) {
+ return host_impl->DrawViewportSize();
}
template <typename LayerTreeHostType>
@@ -160,13 +160,13 @@ void OverdrawMetrics::RecordMetricsInternal(
const LayerTreeHostType* layer_tree_host) const {
// This gives approximately 10x the percentage of pixels to fill the viewport
// once.
- float normalization = 1000.f / (DeviceViewportSize(layer_tree_host).width() *
- DeviceViewportSize(layer_tree_host).height());
+ float normalization = 1000.f / (DrawViewportSize(layer_tree_host).width() *
+ DrawViewportSize(layer_tree_host).height());
// This gives approximately 100x the percentage of tiles to fill the viewport
// once, if all tiles were 256x256.
float tile_normalization =
- 10000.f / (DeviceViewportSize(layer_tree_host).width() / 256.f *
- DeviceViewportSize(layer_tree_host).height() / 256.f);
+ 10000.f / (DrawViewportSize(layer_tree_host).width() / 256.f *
+ DrawViewportSize(layer_tree_host).height() / 256.f);
// This gives approximately 10x the percentage of bytes to fill the viewport
// once, assuming 4 bytes per pixel.
float byte_normalization = normalization / 4;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 82eef41..7575e2f 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -293,6 +293,12 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
void PictureLayerImpl::UpdateTilePriorities() {
DCHECK(!needs_post_commit_initialization_);
+ if (!layer_tree_impl()->device_viewport_valid_for_tile_management()) {
+ for (size_t i = 0; i < tilings_->num_tilings(); ++i)
+ DCHECK(tilings_->tiling_at(i)->has_ever_been_updated());
+ return;
+ }
+
if (!tilings_->num_tilings())
return;
@@ -318,12 +324,13 @@ void PictureLayerImpl::UpdateTilePriorities() {
gfx::Transform current_screen_space_transform = screen_space_transform();
+ gfx::Size viewport_size = layer_tree_impl()->DrawViewportSize();
gfx::Rect viewport_in_content_space;
gfx::Transform screen_to_layer(gfx::Transform::kSkipInitialization);
if (screen_space_transform().GetInverse(&screen_to_layer)) {
- gfx::Rect device_viewport(layer_tree_impl()->device_viewport_size());
- viewport_in_content_space = gfx::ToEnclosingRect(
- MathUtil::ProjectClippedRect(screen_to_layer, device_viewport));
+ viewport_in_content_space =
+ gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
+ screen_to_layer, gfx::Rect(viewport_size)));
}
WhichTree tree =
@@ -332,7 +339,7 @@ void PictureLayerImpl::UpdateTilePriorities() {
layer_tree_impl()->settings().max_tiles_for_interest_area;
tilings_->UpdateTilePriorities(
tree,
- layer_tree_impl()->device_viewport_size(),
+ viewport_size,
viewport_in_content_space,
visible_content_rect(),
last_bounds_,
@@ -798,6 +805,9 @@ void PictureLayerImpl::ManageTilings(bool animating_transform_to_screen) {
if (!change_target_tiling)
return;
+ if (!layer_tree_impl()->device_viewport_valid_for_tile_management())
+ return;
+
raster_page_scale_ = ideal_page_scale_;
raster_device_scale_ = ideal_device_scale_;
raster_source_scale_ = ideal_source_scale_;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 09c438d..a64b9d6 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -241,6 +241,51 @@ TEST_F(PictureLayerImplTest, CloneNoInvalidation) {
VerifyAllTilesExistAndHavePile(tilings->tiling_at(i), active_pile.get());
}
+TEST_F(PictureLayerImplTest, SuppressUpdateTilePriorities) {
+ base::TimeTicks time_ticks;
+ host_impl_.SetCurrentFrameTimeTicks(time_ticks);
+
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(400, 400);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTrees(pending_pile, active_pile);
+
+ Region invalidation;
+ AddDefaultTilingsWithInvalidation(invalidation);
+ EXPECT_TRUE(host_impl_.manage_tiles_needed());
+ active_layer_->UpdateTilePriorities();
+ host_impl_.ManageTiles();
+ EXPECT_FALSE(host_impl_.manage_tiles_needed());
+
+ time_ticks += base::TimeDelta::FromMilliseconds(200);
+ host_impl_.SetCurrentFrameTimeTicks(time_ticks);
+
+ // Setting this boolean should cause an early out in UpdateTilePriorities.
+ bool valid_for_tile_management = false;
+ host_impl_.SetExternalDrawConstraints(gfx::Transform(),
+ gfx::Rect(layer_bounds),
+ gfx::Rect(layer_bounds),
+ valid_for_tile_management);
+ active_layer_->UpdateTilePriorities();
+ EXPECT_FALSE(host_impl_.manage_tiles_needed());
+
+ time_ticks += base::TimeDelta::FromMilliseconds(200);
+ host_impl_.SetCurrentFrameTimeTicks(time_ticks);
+
+ valid_for_tile_management = true;
+ host_impl_.SetExternalDrawConstraints(gfx::Transform(),
+ gfx::Rect(layer_bounds),
+ gfx::Rect(layer_bounds),
+ valid_for_tile_management);
+ active_layer_->UpdateTilePriorities();
+ EXPECT_TRUE(host_impl_.manage_tiles_needed());
+}
+
TEST_F(PictureLayerImplTest, ClonePartialInvalidation) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
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;
}
diff --git a/cc/test/fake_layer_tree_host_impl.cc b/cc/test/fake_layer_tree_host_impl.cc
index cc07041..c1a7326 100644
--- a/cc/test/fake_layer_tree_host_impl.cc
+++ b/cc/test/fake_layer_tree_host_impl.cc
@@ -36,4 +36,15 @@ void FakeLayerTreeHostImpl::CreatePendingTree() {
1.f, 1.f / arbitrary_large_page_scale, arbitrary_large_page_scale);
}
+base::TimeTicks FakeLayerTreeHostImpl::CurrentFrameTimeTicks() {
+ if (current_frame_time_ticks_.is_null())
+ return LayerTreeHostImpl::CurrentFrameTimeTicks();
+ return current_frame_time_ticks_;
+}
+
+void FakeLayerTreeHostImpl::SetCurrentFrameTimeTicks(
+ base::TimeTicks current_frame_time_ticks) {
+ current_frame_time_ticks_ = current_frame_time_ticks;
+}
+
} // namespace cc
diff --git a/cc/test/fake_layer_tree_host_impl.h b/cc/test/fake_layer_tree_host_impl.h
index da6ec41..b652a91 100644
--- a/cc/test/fake_layer_tree_host_impl.h
+++ b/cc/test/fake_layer_tree_host_impl.h
@@ -26,9 +26,14 @@ class FakeLayerTreeHostImpl : public LayerTreeHostImpl {
virtual void CreatePendingTree() OVERRIDE;
+ virtual base::TimeTicks CurrentFrameTimeTicks() OVERRIDE;
+ void SetCurrentFrameTimeTicks(base::TimeTicks current_frame_time_ticks);
+
using LayerTreeHostImpl::ActivatePendingTree;
+ using LayerTreeHostImpl::manage_tiles_needed;
private:
+ base::TimeTicks current_frame_time_ticks_;
FakeLayerTreeHostImplClient client_;
FakeRenderingStatsInstrumentation stats_instrumentation_;
};
diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h
index 5a824e7..24c8c74 100644
--- a/cc/test/fake_output_surface_client.h
+++ b/cc/test/fake_output_surface_client.h
@@ -27,8 +27,11 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {}
virtual void DidLoseOutputSurface() OVERRIDE;
- virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
- gfx::Rect viewport) OVERRIDE {}
+ virtual void SetExternalDrawConstraints(
+ const gfx::Transform& transform,
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) OVERRIDE {}
virtual void SetExternalStencilTest(bool enable) OVERRIDE {}
virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE;
virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE;
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 73c4437..8801596 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -28,12 +28,17 @@ class PixelTest::PixelTestRendererClient
: public RendererClient, public OutputSurfaceClient {
public:
explicit PixelTestRendererClient(gfx::Rect device_viewport)
- : device_viewport_(device_viewport), stencil_enabled_(false) {}
+ : device_viewport_(device_viewport),
+ device_clip_(device_viewport),
+ stencil_enabled_(false) {}
// RendererClient implementation.
virtual gfx::Rect DeviceViewport() const OVERRIDE {
return device_viewport_;
}
+ virtual gfx::Rect DeviceClip() const OVERRIDE {
+ return device_clip_;
+ }
virtual float DeviceScaleFactor() const OVERRIDE {
return 1.f;
}
@@ -64,9 +69,13 @@ class PixelTest::PixelTestRendererClient
virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {}
virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {}
virtual void DidLoseOutputSurface() OVERRIDE {}
- virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
- gfx::Rect viewport) OVERRIDE {
+ virtual void SetExternalDrawConstraints(
+ const gfx::Transform& transform,
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) OVERRIDE {
device_viewport_ = viewport;
+ device_clip_ = clip;
}
virtual void SetExternalStencilTest(bool enable) OVERRIDE {
stencil_enabled_ = enable;
@@ -77,6 +86,7 @@ class PixelTest::PixelTestRendererClient
private:
gfx::Rect device_viewport_;
+ gfx::Rect device_clip_;
bool stencil_enabled_;
LayerTreeSettings settings_;
};
@@ -188,6 +198,11 @@ void PixelTest::ForceExpandedViewport(gfx::Size surface_expansion,
}
}
+void PixelTest::ForceDeviceClip(gfx::Rect clip) {
+ static_cast<PixelTestOutputSurface*>(output_surface_.get())
+ ->set_device_clip(clip);
+}
+
void PixelTest::EnableExternalStencilTest() {
fake_client_->SetExternalStencilTest(true);
}
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
index e3476bf..86a8112 100644
--- a/cc/test/pixel_test.h
+++ b/cc/test/pixel_test.h
@@ -55,6 +55,7 @@ class PixelTest : public testing::Test {
void ForceExpandedViewport(gfx::Size surface_expansion,
gfx::Vector2d viewport_offset);
+ void ForceDeviceClip(gfx::Rect clip);
void EnableExternalStencilTest();
private:
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc
index 9a4d66a..ffc3d26c 100644
--- a/cc/test/pixel_test_output_surface.cc
+++ b/cc/test/pixel_test_output_surface.cc
@@ -15,7 +15,11 @@ void PixelTestOutputSurface::Reshape(gfx::Size size, float scale_factor) {
OutputSurface::Reshape(expanded_size, scale_factor);
gfx::Rect offset_viewport = gfx::Rect(size) + viewport_offset_;
- SetExternalDrawConstraints(gfx::Transform(), offset_viewport);
+ gfx::Rect offset_clip = device_clip_.IsEmpty()
+ ? offset_viewport
+ : device_clip_ + viewport_offset_;
+ SetExternalDrawConstraints(
+ gfx::Transform(), offset_viewport, offset_clip, true);
}
} // namespace cc
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h
index e9052fe..bb6fdfc 100644
--- a/cc/test/pixel_test_output_surface.h
+++ b/cc/test/pixel_test_output_surface.h
@@ -26,10 +26,14 @@ class PixelTestOutputSurface : public OutputSurface {
void set_viewport_offset(gfx::Vector2d viewport_offset) {
viewport_offset_ = viewport_offset;
}
+ void set_device_clip(gfx::Rect device_clip) {
+ device_clip_ = device_clip;
+ }
private:
gfx::Size surface_expansion_size_;
gfx::Vector2d viewport_offset_;
+ gfx::Rect device_clip_;
};
} // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index e55ba64..d9cc1fe 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -197,6 +197,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
device_scale_factor_(1.f),
overhang_ui_resource_id_(0),
overdraw_bottom_height_(0.f),
+ device_viewport_valid_for_tile_management_(true),
external_stencil_test_enabled_(false),
animation_registrar_(AnimationRegistrar::Create()),
rendering_stats_instrumentation_(rendering_stats_instrumentation),
@@ -293,7 +294,7 @@ bool LayerTreeHostImpl::CanDraw() const {
if (output_surface_->capabilities().draw_and_swap_full_viewport_every_frame)
return true;
- if (device_viewport_size_.IsEmpty()) {
+ if (DrawViewportSize().IsEmpty()) {
TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
TRACE_EVENT_SCOPE_THREAD);
return false;
@@ -328,6 +329,9 @@ void LayerTreeHostImpl::ManageTiles() {
return;
if (!manage_tiles_needed_)
return;
+ if (!device_viewport_valid_for_tile_management_)
+ return;
+
manage_tiles_needed_ = false;
tile_manager_->ManageTiles();
@@ -355,7 +359,7 @@ void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset,
gfx::Vector2dF scroll_total =
RootScrollLayer()->scroll_offset() + RootScrollLayer()->ScrollDelta();
gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize();
- gfx::SizeF viewport_size = VisibleViewportSize();
+ gfx::SizeF viewport_size = UnscaledScrollableViewportSize();
double start_time_seconds = (start_time - base::TimeTicks()).InSecondsF();
@@ -1187,9 +1191,13 @@ void LayerTreeHostImpl::SetManagedMemoryPolicy(
void LayerTreeHostImpl::SetExternalDrawConstraints(
const gfx::Transform& transform,
- gfx::Rect viewport) {
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) {
external_transform_ = transform;
external_viewport_ = viewport;
+ external_clip_ = clip;
+ device_viewport_valid_for_tile_management_ = valid_for_tile_management;
}
void LayerTreeHostImpl::SetExternalStencilTest(bool enabled) {
@@ -1390,7 +1398,7 @@ float LayerTreeHostImpl::DeviceScaleFactor() const {
return device_scale_factor_;
}
-gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
+gfx::SizeF LayerTreeHostImpl::UnscaledScrollableViewportSize() const {
// The container layer bounds should be used if non-overlay scrollbars may
// exist since it adjusts for them.
LayerImpl* container_layer = active_tree_->RootContainerLayer();
@@ -1401,7 +1409,7 @@ gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
}
gfx::SizeF dip_size =
- gfx::ScaleSize(device_viewport_size(), 1.f / device_scale_factor());
+ gfx::ScaleSize(device_viewport_size_, 1.f / device_scale_factor());
float top_offset =
top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f;
@@ -1796,7 +1804,7 @@ void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size) {
if (device_viewport_size == device_viewport_size_)
return;
- if (pending_tree_ && device_viewport_size_ != device_viewport_size)
+ if (pending_tree_)
active_tree_->SetViewportSizeInvalid();
device_viewport_size_ = device_viewport_size;
@@ -1838,6 +1846,10 @@ void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
SetFullRootLayerDamage();
}
+gfx::Size LayerTreeHostImpl::DrawViewportSize() const {
+ return DeviceViewport().size();
+}
+
gfx::Rect LayerTreeHostImpl::DeviceViewport() const {
if (external_viewport_.IsEmpty())
return gfx::Rect(device_viewport_size_);
@@ -1845,7 +1857,14 @@ gfx::Rect LayerTreeHostImpl::DeviceViewport() const {
return external_viewport_;
}
-const gfx::Transform& LayerTreeHostImpl::DeviceTransform() const {
+gfx::Rect LayerTreeHostImpl::DeviceClip() const {
+ if (external_clip_.IsEmpty())
+ return DeviceViewport();
+
+ return external_clip_;
+}
+
+const gfx::Transform& LayerTreeHostImpl::DrawTransform() const {
return external_transform_;
}
@@ -2298,7 +2317,7 @@ scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
}
void LayerTreeHostImpl::SetFullRootLayerDamage() {
- SetViewportDamage(gfx::Rect(device_viewport_size_));
+ SetViewportDamage(gfx::Rect(DrawViewportSize()));
}
void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 520ec7f..280eb5e 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -174,10 +174,6 @@ class CC_EXPORT LayerTreeHostImpl
const LayerTreeSettings& settings() const { return settings_; }
- // Returns the currently visible viewport size in DIP. This value excludes
- // the URL bar and non-overlay scrollbars.
- gfx::SizeF VisibleViewportSize() const;
-
// Evict all textures by enforcing a memory policy with an allocation of 0.
void EvictTexturesForTesting();
@@ -186,8 +182,26 @@ class CC_EXPORT LayerTreeHostImpl
// immediately if any notifications had been blocked while blocking.
virtual void BlockNotifyReadyToActivateForTesting(bool block);
+ bool device_viewport_valid_for_tile_management() const {
+ return device_viewport_valid_for_tile_management_;
+ }
+
+ // Viewport size in draw space: this size is in physical pixels and is used
+ // for draw properties, tilings, quads and render passes.
+ gfx::Size DrawViewportSize() const;
+
+ // Viewport size for scrolling and fixed-position compensation. This value
+ // excludes the URL bar and non-overlay scrollbars and is in DIP (and
+ // invariant relative to page scale).
+ gfx::SizeF UnscaledScrollableViewportSize() const;
+
// RendererClient implementation
+
+ // Viewport rectangle and clip in nonflipped window space. These rects
+ // should only be used by Renderer subclasses to populate glViewport/glClip
+ // and their software-mode equivalents.
virtual gfx::Rect DeviceViewport() const OVERRIDE;
+ virtual gfx::Rect DeviceClip() const OVERRIDE;
private:
virtual float DeviceScaleFactor() const OVERRIDE;
virtual const LayerTreeSettings& Settings() const OVERRIDE;
@@ -208,8 +222,11 @@ class CC_EXPORT LayerTreeHostImpl
virtual void ReleaseGL() OVERRIDE;
virtual void SetNeedsRedrawRect(gfx::Rect rect) OVERRIDE;
virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE;
- virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
- gfx::Rect viewport) OVERRIDE;
+ virtual void SetExternalDrawConstraints(
+ const gfx::Transform& transform,
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) OVERRIDE;
virtual void SetExternalStencilTest(bool enabled) OVERRIDE;
virtual void DidLoseOutputSurface() OVERRIDE;
virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE;
@@ -273,7 +290,6 @@ class CC_EXPORT LayerTreeHostImpl
size_t memory_allocation_limit_bytes() const;
void SetViewportSize(gfx::Size device_viewport_size);
- gfx::Size device_viewport_size() const { return device_viewport_size_; }
void SetOverdrawBottomHeight(float overdraw_bottom_height);
float overdraw_bottom_height() const { return overdraw_bottom_height_; }
@@ -284,7 +300,7 @@ class CC_EXPORT LayerTreeHostImpl
void SetDeviceScaleFactor(float device_scale_factor);
float device_scale_factor() const { return device_scale_factor_; }
- const gfx::Transform& DeviceTransform() const;
+ const gfx::Transform& DrawTransform() const;
scoped_ptr<ScrollAndScaleSet> ProcessScrollDeltas();
@@ -378,7 +394,7 @@ class CC_EXPORT LayerTreeHostImpl
void SetTreePriority(TreePriority priority);
void ResetCurrentFrameTimeForNextFrame();
- base::TimeTicks CurrentFrameTimeTicks();
+ virtual base::TimeTicks CurrentFrameTimeTicks();
base::Time CurrentFrameTime();
virtual base::TimeTicks CurrentPhysicalTimeTicks() const;
@@ -415,6 +431,8 @@ class CC_EXPORT LayerTreeHostImpl
return animation_registrar_->active_animation_controllers();
}
+ bool manage_tiles_needed() const { return manage_tiles_needed_; }
+
LayerTreeHostImplClient* client_;
Proxy* proxy_;
@@ -535,7 +553,10 @@ class CC_EXPORT LayerTreeHostImpl
size_t last_sent_memory_use_bytes_;
bool zero_budget_;
- // Viewport size passed in from the main thread, in physical pixels.
+ // Viewport size passed in from the main thread, in physical pixels. This
+ // value is the default size for all concepts of physical viewport (draw
+ // viewport, scrolling viewport and device viewport), but it can be
+ // overridden.
gfx::Size device_viewport_size_;
// Conversion factor from CSS pixels to physical pixels when
@@ -552,12 +573,18 @@ class CC_EXPORT LayerTreeHostImpl
// the page when the keyboard is up.
float overdraw_bottom_height_;
- // Optional top-level constraints that can be set by the OutputSurface. The
- // external_viewport_'s size takes precedence over device_viewport_size_ for
- // DrawQuad generation and Renderer; however, device_viewport_size_ is still
- // used for scrollable size.
+ // Optional top-level constraints that can be set by the OutputSurface.
+ // - external_transform_ applies a transform above the root layer
+ // - external_viewport_ is used DrawProperties, tile management and
+ // glViewport/window projection matrix.
+ // - external_clip_ specifies a top-level clip rect
+ // - external_stencil_test_enabled_ tells CC to respect existing stencil bits
+ // (When these are specified, device_viewport_size_ remains used only for
+ // scrollable size.)
gfx::Transform external_transform_;
gfx::Rect external_viewport_;
+ gfx::Rect external_clip_;
+ bool device_viewport_valid_for_tile_management_;
bool external_stencil_test_enabled_;
gfx::Rect viewport_damage_rect_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 911b4ea..1e73b31 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -5006,6 +5006,9 @@ class TestRenderer : public GLRenderer, public RendererClient {
virtual gfx::Rect DeviceViewport() const OVERRIDE {
return gfx::Rect(viewport_size_);
}
+ virtual gfx::Rect DeviceClip() const OVERRIDE {
+ return DeviceViewport();
+ }
virtual float DeviceScaleFactor() const OVERRIDE {
return 1.f;
}
@@ -5441,7 +5444,7 @@ TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>());
// Draw a frame. In the first frame, the entire viewport should be damaged.
- gfx::Rect full_frame_damage = gfx::Rect(host_impl_->device_viewport_size());
+ gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
DrawFrameAndTestDamage(full_frame_damage);
// The second frame has damage that doesn't touch the child layer. Its quads
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 0102a10..1390118 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -684,7 +684,7 @@ class LayerTreeHostTestCommit : public LayerTreeHostTest {
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- EXPECT_EQ(gfx::Size(20, 20), impl->device_viewport_size());
+ EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
EndTest();
@@ -1036,7 +1036,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
// Device viewport is scaled.
- EXPECT_EQ(gfx::Size(60, 60), impl->device_viewport_size());
+ EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
LayerImpl* root = impl->active_tree()->root_layer();
LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 52a539b..0d4fbf9 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -207,7 +207,7 @@ void LayerTreeImpl::SetPageScaleDelta(float delta) {
}
gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
- return gfx::ScaleSize(layer_tree_host_impl_->VisibleViewportSize(),
+ return gfx::ScaleSize(layer_tree_host_impl_->UnscaledScrollableViewportSize(),
1.0f / total_page_scale_factor());
}
@@ -272,8 +272,9 @@ void LayerTreeImpl::UpdateSolidColorScrollbars() {
ScrollableViewportSize());
float vertical_adjust = 0.0f;
if (RootContainerLayer())
- vertical_adjust = layer_tree_host_impl_->VisibleViewportSize().height() -
- RootContainerLayer()->bounds().height();
+ vertical_adjust =
+ layer_tree_host_impl_->UnscaledScrollableViewportSize().height() -
+ RootContainerLayer()->bounds().height();
if (ScrollbarLayerImplBase* horiz =
root_scroll->horizontal_scrollbar_layer()) {
horiz->SetVerticalAdjust(vertical_adjust);
@@ -317,8 +318,8 @@ void LayerTreeImpl::UpdateDrawProperties() {
source_frame_number_);
LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
root_layer(),
- layer_tree_host_impl_->DeviceViewport().size(),
- layer_tree_host_impl_->DeviceTransform(),
+ DrawViewportSize(),
+ layer_tree_host_impl_->DrawTransform(),
device_scale_factor(),
total_page_scale_factor(),
root_scroll_layer_ ? root_scroll_layer_->parent() : NULL,
@@ -454,6 +455,10 @@ MemoryHistory* LayerTreeImpl::memory_history() const {
return layer_tree_host_impl_->memory_history();
}
+bool LayerTreeImpl::device_viewport_valid_for_tile_management() const {
+ return layer_tree_host_impl_->device_viewport_valid_for_tile_management();
+}
+
bool LayerTreeImpl::IsActiveTree() const {
return layer_tree_host_impl_->active_tree() == this;
}
@@ -504,6 +509,10 @@ void LayerTreeImpl::SetNeedsCommit() {
layer_tree_host_impl_->SetNeedsCommit();
}
+gfx::Size LayerTreeImpl::DrawViewportSize() const {
+ return layer_tree_host_impl_->DrawViewportSize();
+}
+
void LayerTreeImpl::SetNeedsRedraw() {
layer_tree_host_impl_->SetNeedsRedraw();
}
@@ -516,10 +525,6 @@ float LayerTreeImpl::device_scale_factor() const {
return layer_tree_host_impl_->device_scale_factor();
}
-gfx::Size LayerTreeImpl::device_viewport_size() const {
- return layer_tree_host_impl_->device_viewport_size();
-}
-
DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
return layer_tree_host_impl_->debug_rect_history();
}
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 4dfc511..3b18693 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -66,6 +66,7 @@ class CC_EXPORT LayerTreeImpl {
FrameRateCounter* frame_rate_counter() const;
PaintTimeCounter* paint_time_counter() const;
MemoryHistory* memory_history() const;
+ bool device_viewport_valid_for_tile_management() const;
bool IsActiveTree() const;
bool IsPendingTree() const;
bool IsRecycleTree() const;
@@ -77,6 +78,7 @@ class CC_EXPORT LayerTreeImpl {
base::Time CurrentFrameTime() const;
base::TimeTicks CurrentPhysicalTimeTicks() const;
void SetNeedsCommit();
+ gfx::Size DrawViewportSize() const;
// Tree specific methods exposed to layer-impl tree.
// ---------------------------------------------------------------------------
@@ -86,7 +88,6 @@ class CC_EXPORT LayerTreeImpl {
// trivial accessors in a followup patch.
const LayerTreeDebugState& debug_state() const;
float device_scale_factor() const;
- gfx::Size device_viewport_size() const;
DebugRectHistory* debug_rect_history() const;
scoped_ptr<base::Value> AsValue() const;
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index 97bbfe9..b3a7b96 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -253,15 +253,16 @@ void SynchronousCompositorImpl::ReleaseHwDraw() {
}
bool SynchronousCompositorImpl::DemandDrawHw(
- gfx::Size view_size,
+ gfx::Size surface_size,
const gfx::Transform& transform,
- gfx::Rect damage_area,
+ gfx::Rect viewport,
+ gfx::Rect clip,
bool stencil_enabled) {
DCHECK(CalledOnValidThread());
DCHECK(output_surface_);
return output_surface_->DemandDrawHw(
- view_size, transform, damage_area, stencil_enabled);
+ surface_size, transform, viewport, clip, stencil_enabled);
}
bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) {
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index f0ea2c6..854c5eb 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -52,8 +52,9 @@ class SynchronousCompositorImpl
scoped_refptr<gfx::GLSurface> surface) OVERRIDE;
virtual void ReleaseHwDraw() OVERRIDE;
virtual bool DemandDrawHw(
- gfx::Size view_size,
+ gfx::Size surface_size,
const gfx::Transform& transform,
+ gfx::Rect viewport,
gfx::Rect clip,
bool stencil_enabled) OVERRIDE;
virtual bool DemandDrawSw(SkCanvas* canvas) OVERRIDE;
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
index 1919d73..40c8a3b 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -186,10 +186,9 @@ void SynchronousCompositorOutputSurface::SwapBuffers(
}
namespace {
-void AdjustTransformForClip(gfx::Transform* transform, gfx::Rect clip) {
- // The system-provided transform translates us from the screen origin to the
- // origin of the clip rect, but CC's draw origin starts at the clip.
- transform->matrix().postTranslate(-clip.x(), -clip.y(), 0);
+void AdjustTransform(gfx::Transform* transform, gfx::Rect viewport) {
+ // CC's draw origin starts at the viewport.
+ transform->matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
}
} // namespace
@@ -215,18 +214,16 @@ void SynchronousCompositorOutputSurface::ReleaseHwDraw() {
bool SynchronousCompositorOutputSurface::DemandDrawHw(
gfx::Size surface_size,
const gfx::Transform& transform,
+ gfx::Rect viewport,
gfx::Rect clip,
bool stencil_enabled) {
DCHECK(CalledOnValidThread());
DCHECK(HasClient());
DCHECK(context_provider_);
- gfx::Transform adjusted_transform = transform;
- AdjustTransformForClip(&adjusted_transform, clip);
surface_size_ = surface_size;
- SetExternalDrawConstraints(adjusted_transform, clip);
SetExternalStencilTest(stencil_enabled);
- InvokeComposite(clip.size());
+ InvokeComposite(transform, viewport, clip, true);
return did_swap_buffer_;
}
@@ -243,27 +240,46 @@ bool SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
gfx::Transform transform(gfx::Transform::kSkipInitialization);
transform.matrix() = canvas->getTotalMatrix(); // Converts 3x3 matrix to 4x4.
- AdjustTransformForClip(&transform, clip);
surface_size_ = gfx::Size(canvas->getDeviceSize().width(),
canvas->getDeviceSize().height());
- SetExternalDrawConstraints(transform, clip);
SetExternalStencilTest(false);
- InvokeComposite(clip.size());
+ InvokeComposite(transform, clip, clip, false);
return did_swap_buffer_;
}
void SynchronousCompositorOutputSurface::InvokeComposite(
- gfx::Size damage_size) {
+ const gfx::Transform& transform,
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management) {
DCHECK(!invoking_composite_);
base::AutoReset<bool> invoking_composite_resetter(&invoking_composite_, true);
did_swap_buffer_ = false;
- SetNeedsRedrawRect(gfx::Rect(damage_size));
+
+ gfx::Transform adjusted_transform = transform;
+ AdjustTransform(&adjusted_transform, viewport);
+ SetExternalDrawConstraints(
+ adjusted_transform, viewport, clip, valid_for_tile_management);
+ SetNeedsRedrawRect(gfx::Rect(viewport.size()));
+
if (needs_begin_frame_)
BeginFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor());
+ // After software draws (which might move the viewport arbitrarily), restore
+ // the previous hardware viewport to allow CC's tile manager to prioritize
+ // properly.
+ if (valid_for_tile_management) {
+ cached_hw_transform_ = adjusted_transform;
+ cached_hw_viewport_ = viewport;
+ cached_hw_clip_ = clip;
+ } else {
+ SetExternalDrawConstraints(
+ cached_hw_transform_, cached_hw_viewport_, cached_hw_clip_, true);
+ }
+
if (did_swap_buffer_)
OnSwapBuffersComplete(NULL);
}
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h
index 86f048b..d11651d 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.h
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h
@@ -11,6 +11,7 @@
#include "base/memory/scoped_ptr.h"
#include "cc/output/output_surface.h"
#include "content/public/browser/android/synchronous_compositor.h"
+#include "ui/gfx/transform.h"
namespace cc {
class ContextProvider;
@@ -67,6 +68,7 @@ class SynchronousCompositorOutputSurface
void ReleaseHwDraw();
bool DemandDrawHw(gfx::Size surface_size,
const gfx::Transform& transform,
+ gfx::Rect viewport,
gfx::Rect clip,
bool stencil_enabled);
bool DemandDrawSw(SkCanvas* canvas);
@@ -78,7 +80,10 @@ class SynchronousCompositorOutputSurface
// Private OutputSurface overrides.
virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE;
- void InvokeComposite(gfx::Size damage_size);
+ void InvokeComposite(const gfx::Transform& transform,
+ gfx::Rect viewport,
+ gfx::Rect clip,
+ bool valid_for_tile_management);
bool CalledOnValidThread() const;
SynchronousCompositorOutputSurfaceDelegate* GetDelegate();
@@ -87,6 +92,10 @@ class SynchronousCompositorOutputSurface
bool invoking_composite_;
bool did_swap_buffer_;
+ gfx::Transform cached_hw_transform_;
+ gfx::Rect cached_hw_viewport_;
+ gfx::Rect cached_hw_clip_;
+
// Only valid (non-NULL) during a DemandDrawSw() call.
SkCanvas* current_sw_canvas_;
diff --git a/content/public/browser/android/synchronous_compositor.h b/content/public/browser/android/synchronous_compositor.h
index f559b973..810daf2 100644
--- a/content/public/browser/android/synchronous_compositor.h
+++ b/content/public/browser/android/synchronous_compositor.h
@@ -55,9 +55,10 @@ class CONTENT_EXPORT SynchronousCompositor {
// then transformed through |transform|, and finally clipped to |view_size|
// and by the existing stencil buffer if any.
virtual bool DemandDrawHw(
- gfx::Size view_size,
+ gfx::Size surface_size,
const gfx::Transform& transform,
- gfx::Rect damage_area,
+ gfx::Rect viewport,
+ gfx::Rect clip,
bool stencil_enabled) = 0;
// "On demand" SW draw, into the supplied canvas (observing the transform