summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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