summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/layers/contents_scaling_layer_unittest.cc1
-rw-r--r--cc/layers/layer_iterator_unittest.cc3
-rw-r--r--cc/layers/layer_position_constraint_unittest.cc41
-rw-r--r--cc/layers/solid_color_layer_impl_unittest.cc1
-rw-r--r--cc/layers/tiled_layer_unittest.cc1
-rw-r--r--cc/output/direct_renderer.cc78
-rw-r--r--cc/output/direct_renderer.h31
-rw-r--r--cc/output/gl_renderer.cc62
-rw-r--r--cc/output/gl_renderer.h7
-rw-r--r--cc/output/gl_renderer_unittest.cc111
-rw-r--r--cc/output/output_surface.cc24
-rw-r--r--cc/output/output_surface.h3
-rw-r--r--cc/output/output_surface_client.h6
-rw-r--r--cc/output/output_surface_unittest.cc2
-rw-r--r--cc/output/renderer.h12
-rw-r--r--cc/output/renderer_pixeltest.cc13
-rw-r--r--cc/output/software_output_device.cc6
-rw-r--r--cc/output/software_renderer.cc27
-rw-r--r--cc/output/software_renderer.h7
-rw-r--r--cc/output/software_renderer_unittest.cc39
-rw-r--r--cc/test/fake_output_surface.h2
-rw-r--r--cc/test/pixel_test.cc76
-rw-r--r--cc/test/pixel_test.h85
-rw-r--r--cc/trees/damage_tracker_unittest.cc1
-rw-r--r--cc/trees/layer_tree_host.cc1
-rw-r--r--cc/trees/layer_tree_host_common.cc113
-rw-r--r--cc/trees/layer_tree_host_common.h2
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc168
-rw-r--r--cc/trees/layer_tree_host_impl.cc28
-rw-r--r--cc/trees/layer_tree_host_impl.h29
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc4
-rw-r--r--cc/trees/layer_tree_impl.cc3
-rw-r--r--cc/trees/occlusion_tracker_unittest.cc2
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.cc44
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.h4
-rw-r--r--content/renderer/gpu/mailbox_output_surface.cc16
-rw-r--r--content/renderer/gpu/mailbox_output_surface.h1
-rw-r--r--webkit/renderer/compositor_bindings/web_layer_impl_fixed_bounds_unittest.cc2
38 files changed, 776 insertions, 280 deletions
diff --git a/cc/layers/contents_scaling_layer_unittest.cc b/cc/layers/contents_scaling_layer_unittest.cc
index 08d9eb1..23f1376 100644
--- a/cc/layers/contents_scaling_layer_unittest.cc
+++ b/cc/layers/contents_scaling_layer_unittest.cc
@@ -41,6 +41,7 @@ void CalcDrawProps(Layer* root, float device_scale) {
LayerTreeHostCommon::CalculateDrawProperties(
root,
gfx::Size(500, 500),
+ gfx::Transform(),
device_scale,
1.f,
NULL,
diff --git a/cc/layers/layer_iterator_unittest.cc b/cc/layers/layer_iterator_unittest.cc
index e7cecfd..10526ba 100644
--- a/cc/layers/layer_iterator_unittest.cc
+++ b/cc/layers/layer_iterator_unittest.cc
@@ -141,6 +141,7 @@ TEST(LayerIteratorTest, SimpleTree) {
LayerList render_surface_layerList;
LayerTreeHostCommon::CalculateDrawProperties(root_layer.get(),
root_layer->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -189,6 +190,7 @@ TEST(LayerIteratorTest, ComplexTree) {
LayerList render_surface_layerList;
LayerTreeHostCommon::CalculateDrawProperties(root_layer.get(),
root_layer->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -252,6 +254,7 @@ TEST(LayerIteratorTest, ComplexTreeMultiSurface) {
LayerList render_surface_layerList;
LayerTreeHostCommon::CalculateDrawProperties(root_layer.get(),
root_layer->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc
index af1af4e..1e6084f 100644
--- a/cc/layers/layer_position_constraint_unittest.cc
+++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -50,6 +50,7 @@ void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
LayerTreeHostCommon::CalculateDrawProperties(
root_layer,
device_viewport_size,
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
page_scale_application_layer,
@@ -1034,8 +1035,7 @@ TEST_F(LayerPositionConstraintTest,
ScrollCompensationForFixedPositionLayerThatHasNoContainer) {
// This test checks scroll compensation when a fixed-position layer does not
// find any ancestor that is a "containerForFixedPositionLayers". In this
- // situation, the layer should be fixed to the viewport -- not the root_layer,
- // which may have transforms of its own.
+ // situation, the layer should be fixed to the root layer.
LayerImpl* child = root_->children()[0];
LayerImpl* grand_child = child->children()[0];
@@ -1051,46 +1051,43 @@ TEST_F(LayerPositionConstraintTest,
gfx::Transform identity_matrix;
- EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
+ EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, child->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z,
grand_child->draw_transform());
// Case 2: root scroll delta of 10, 10
root_->SetScrollDelta(gfx::Vector2d(10, 20));
ExecuteCalculateDrawProperties(root_.get());
- // The child is affected by scroll delta, but it is already implcitly
- // accounted for by the child's target surface (i.e. the root render surface).
- // The grand_child is not affected by the scroll delta, so its draw transform
- // needs to explicitly inverse-compensate for the scroll that's embedded in
- // the target surface.
- gfx::Transform expected_grand_child_transform;
- expected_grand_child_transform.PreconcatTransform(Inverse(rotation_by_z));
- // explicit cancelling out the scroll delta that gets embedded in the fixed
- // position layer's surface.
- expected_grand_child_transform.Translate(10.0, 20.0);
- expected_grand_child_transform.PreconcatTransform(rotation_by_z);
+ gfx::Transform expected_child_transform;
+ expected_child_transform.Translate(-10.0, -20.0);
+ expected_child_transform.PreconcatTransform(rotation_by_z);
- EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
+ child->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z,
grand_child->draw_transform());
-
// Case 3: fixed-container size delta of 20, 20
root_->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
ExecuteCalculateDrawProperties(root_.get());
// Top-left fixed-position layer should not be affected by container size.
- EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
+ child->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z,
grand_child->draw_transform());
// Case 4: Bottom-right fixed-position layer.
grand_child->SetPositionConstraint(fixed_to_bottom_right_);
ExecuteCalculateDrawProperties(root_.get());
- // Root layer is not the fixed-container anyway.
- EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
+ gfx::Transform expected_grand_child_transform;
+ expected_grand_child_transform.Translate(-20.0, 20.0);
+ expected_grand_child_transform.PreconcatTransform(rotation_by_z);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
+ child->draw_transform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
grand_child->draw_transform());
}
diff --git a/cc/layers/solid_color_layer_impl_unittest.cc b/cc/layers/solid_color_layer_impl_unittest.cc
index dcb4123..0ec7040 100644
--- a/cc/layers/solid_color_layer_impl_unittest.cc
+++ b/cc/layers/solid_color_layer_impl_unittest.cc
@@ -112,6 +112,7 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) {
LayerList render_surface_layer_list;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
gfx::Size(500, 500),
+ gfx::Transform(),
1.f,
1.f,
NULL,
diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc
index fe2ed5a..819a874 100644
--- a/cc/layers/tiled_layer_unittest.cc
+++ b/cc/layers/tiled_layer_unittest.cc
@@ -135,6 +135,7 @@ class TiledLayerTest : public testing::Test {
LayerTreeHostCommon::CalculateDrawProperties(
layer_tree_host_->root_layer(),
layer_tree_host_->device_viewport_size(),
+ gfx::Transform(),
layer_tree_host_->device_scale_factor(),
1.f, // page_scale_factor
NULL,
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc
index e2c17b8..76c5426 100644
--- a/cc/output/direct_renderer.cc
+++ b/cc/output/direct_renderer.cc
@@ -79,10 +79,15 @@ void DirectRenderer::QuadRectTransform(gfx::Transform* quad_rect_transform,
quad_rect_transform->Scale(quad_rect.width(), quad_rect.height());
}
-// static
-void DirectRenderer::InitializeMatrices(DrawingFrame* frame,
+void DirectRenderer::InitializeViewport(DrawingFrame* frame,
gfx::Rect draw_rect,
+ gfx::Rect viewport_rect,
+ gfx::Size surface_size,
bool flip_y) {
+ DCHECK_GE(viewport_rect.x(), 0);
+ DCHECK_GE(viewport_rect.y(), 0);
+ DCHECK_LE(viewport_rect.right(), surface_size.width());
+ DCHECK_LE(viewport_rect.bottom(), surface_size.height());
if (flip_y) {
frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(),
draw_rect.right(),
@@ -94,35 +99,38 @@ void DirectRenderer::InitializeMatrices(DrawingFrame* frame,
draw_rect.y(),
draw_rect.bottom());
}
- frame->window_matrix =
- window_matrix(0, 0, draw_rect.width(), draw_rect.height());
+
+ gfx::Rect window_rect = viewport_rect;
+ if (flip_y)
+ window_rect.set_y(surface_size.height() - viewport_rect.bottom());
+ frame->window_matrix = window_matrix(window_rect.x(),
+ window_rect.y(),
+ window_rect.width(),
+ window_rect.height());
+ SetDrawViewport(window_rect);
+
frame->flipped_y = flip_y;
+
+ current_draw_rect_ = draw_rect;
+ current_viewport_rect_ = viewport_rect;
+ current_surface_size_ = surface_size;
}
-// static
-gfx::Rect DirectRenderer::MoveScissorToWindowSpace(
- const DrawingFrame* frame, const gfx::RectF& scissor_rect) {
- gfx::Rect scissor_rect_in_canvas_space = gfx::ToEnclosingRect(scissor_rect);
- // The scissor coordinates must be supplied in viewport space so we need to
- // offset by the relative position of the top left corner of the current
- // render pass.
- gfx::Rect framebuffer_output_rect = frame->current_render_pass->output_rect;
- scissor_rect_in_canvas_space.set_x(
- scissor_rect_in_canvas_space.x() - framebuffer_output_rect.x());
- if (frame->flipped_y && !frame->current_texture) {
- scissor_rect_in_canvas_space.set_y(
- framebuffer_output_rect.height() -
- (scissor_rect_in_canvas_space.bottom() - framebuffer_output_rect.y()));
- } else {
- scissor_rect_in_canvas_space.set_y(
- scissor_rect_in_canvas_space.y() - framebuffer_output_rect.y());
- }
- return scissor_rect_in_canvas_space;
+gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace(
+ const gfx::RectF& draw_rect, bool flip_y) const {
+ gfx::Rect window_rect = gfx::ToEnclosingRect(draw_rect);
+ window_rect -= current_draw_rect_.OffsetFromOrigin();
+ window_rect += current_viewport_rect_.OffsetFromOrigin();
+ if (flip_y)
+ window_rect.set_y(current_surface_size_.height() - window_rect.bottom());
+ return window_rect;
}
DirectRenderer::DirectRenderer(RendererClient* client,
+ OutputSurface* output_surface,
ResourceProvider* resource_provider)
: Renderer(client),
+ output_surface_(output_surface),
resource_provider_(resource_provider) {}
DirectRenderer::~DirectRenderer() {}
@@ -197,7 +205,13 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order) {
frame.root_damage_rect =
Capabilities().using_partial_swap && client_->AllowPartialSwap() ?
root_render_pass->damage_rect : root_render_pass->output_rect;
- frame.root_damage_rect.Intersect(gfx::Rect(ViewportSize()));
+ frame.root_damage_rect.Intersect(gfx::Rect(client_->DeviceViewport().size()));
+
+ // Only reshape when we know we are going to draw. Otherwise, the reshape
+ // can leave the window at the wrong size if we never draw and the proper
+ // viewport size is never set.
+ output_surface_->Reshape(client_->DeviceViewport().size(),
+ client_->DeviceScaleFactor());
BeginDrawingFrame(&frame);
for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) {
@@ -245,7 +259,8 @@ void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame,
const DrawQuad& quad) {
if (quad.isClipped()) {
gfx::RectF quad_scissor_rect = quad.clipRect();
- SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect));
+ SetScissorTestRect(
+ MoveFromDrawToWindowSpace(quad_scissor_rect, frame->flipped_y));
} else {
EnsureScissorTestDisabled();
}
@@ -267,7 +282,8 @@ void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor(
}
*should_skip_quad = false;
- SetScissorTestRect(MoveScissorToWindowSpace(frame, quad_scissor_rect));
+ SetScissorTestRect(
+ MoveFromDrawToWindowSpace(quad_scissor_rect, frame->flipped_y));
}
void DirectRenderer::FinishDrawingQuadList() {}
@@ -284,7 +300,8 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
if (using_scissor_as_optimization) {
render_pass_scissor = ComputeScissorRectForRenderPass(frame);
- SetScissorTestRect(MoveScissorToWindowSpace(frame, render_pass_scissor));
+ SetScissorTestRect(
+ MoveFromDrawToWindowSpace(render_pass_scissor, frame->flipped_y));
}
if (frame->current_render_pass != frame->root_render_pass ||
@@ -327,8 +344,11 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame,
if (render_pass == frame->root_render_pass) {
BindFramebufferToOutputSurface(frame);
- InitializeMatrices(frame, render_pass->output_rect, FlippedFramebuffer());
- SetDrawViewportSize(render_pass->output_rect.size());
+ InitializeViewport(frame,
+ render_pass->output_rect,
+ client_->DeviceViewport(),
+ output_surface_->SurfaceSize(),
+ FlippedFramebuffer());
return true;
}
diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h
index 4baadee..864ce91 100644
--- a/cc/output/direct_renderer.h
+++ b/cc/output/direct_renderer.h
@@ -50,7 +50,9 @@ class CC_EXPORT DirectRenderer : public Renderer {
void SetEnlargePassTextureAmountForTesting(gfx::Vector2d amount);
protected:
- DirectRenderer(RendererClient* client, ResourceProvider* resource_provider);
+ DirectRenderer(RendererClient* client,
+ OutputSurface* output_surface,
+ ResourceProvider* resource_provider);
class CachedResource : public ScopedResource {
public:
@@ -78,11 +80,14 @@ class CC_EXPORT DirectRenderer : public Renderer {
static void QuadRectTransform(gfx::Transform* quad_rect_transform,
const gfx::Transform& quad_transform,
const gfx::RectF& quad_rect);
- static void InitializeMatrices(DrawingFrame* frame,
- gfx::Rect draw_rect,
- bool flip_y);
- static gfx::Rect MoveScissorToWindowSpace(const DrawingFrame* frame,
- const gfx::RectF& scissor_rect);
+ void InitializeViewport(DrawingFrame* frame,
+ gfx::Rect draw_rect,
+ gfx::Rect viewport_rect,
+ gfx::Size surface_size,
+ bool flip_y);
+ gfx::Rect MoveFromDrawToWindowSpace(const gfx::RectF& draw_rect,
+ bool flip_y) const;
+
static gfx::RectF ComputeScissorRectForRenderPass(const DrawingFrame* frame);
void SetScissorStateForQuad(const DrawingFrame* frame, const DrawQuad& quad);
void SetScissorStateForQuadWithRenderPassScissor(
@@ -100,8 +105,8 @@ class CC_EXPORT DirectRenderer : public Renderer {
virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) = 0;
virtual bool BindFramebufferToTexture(DrawingFrame* frame,
const ScopedResource* resource,
- gfx::Rect framebuffer_rect) = 0;
- virtual void SetDrawViewportSize(gfx::Size viewport_size) = 0;
+ gfx::Rect target_rect) = 0;
+ virtual void SetDrawViewport(gfx::Rect window_space_viewport) = 0;
virtual void SetScissorTestRect(gfx::Rect scissor_rect) = 0;
virtual void ClearFramebuffer(DrawingFrame* frame) = 0;
virtual void DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) = 0;
@@ -117,8 +122,18 @@ class CC_EXPORT DirectRenderer : public Renderer {
scoped_ptr<CopyOutputRequest> request) = 0;
ScopedPtrHashMap<RenderPass::Id, CachedResource> render_pass_textures_;
+ OutputSurface* output_surface_;
ResourceProvider* resource_provider_;
+ // For use in coordinate conversion, this stores the output rect, viewport
+ // rect (= unflipped version of glViewport rect), and the size of target
+ // framebuffer. During a draw, this stores the values for the current render
+ // pass; in between draws, they retain the values for the root render pass of
+ // the last draw.
+ gfx::Rect current_draw_rect_;
+ gfx::Rect current_viewport_rect_;
+ gfx::Size current_surface_size_;
+
private:
gfx::Vector2d enlarge_pass_texture_amount_;
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 4da3aab..4519af3 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -125,12 +125,10 @@ GLRenderer::GLRenderer(RendererClient* client,
OutputSurface* output_surface,
ResourceProvider* resource_provider,
int highp_threshold_min)
- : DirectRenderer(client, resource_provider),
+ : DirectRenderer(client, output_surface, resource_provider),
offscreen_framebuffer_id_(0),
shared_geometry_quad_(gfx::RectF(-0.5f, -0.5f, 1.0f, 1.0f)),
- output_surface_(output_surface),
context_(output_surface->context3d()),
- is_viewport_changed_(false),
is_backbuffer_discarded_(false),
discard_backbuffer_when_not_visible_(false),
is_using_bind_uniform_(false),
@@ -275,7 +273,6 @@ void GLRenderer::SendManagedMemoryStats(size_t bytes_visible,
void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); }
void GLRenderer::ViewportChanged() {
- is_viewport_changed_ = true;
ReinitializeGrCanvas();
}
@@ -305,18 +302,10 @@ void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) {
// FIXME: Remove this once backbuffer is automatically recreated on first use
EnsureBackbuffer();
- if (ViewportSize().IsEmpty())
+ if (client_->DeviceViewport().IsEmpty())
return;
TRACE_EVENT0("cc", "GLRenderer::DrawLayers");
- if (is_viewport_changed_) {
- // Only reshape when we know we are going to draw. Otherwise, the reshape
- // can leave the window at the wrong size if we never draw and the proper
- // viewport size is never set.
- is_viewport_changed_ = false;
- output_surface_->Reshape(gfx::Size(ViewportWidth(), ViewportHeight()),
- DeviceScaleFactor());
- }
MakeContextCurrent();
@@ -1503,7 +1492,7 @@ void GLRenderer::DrawPictureQuadDirectToBackbuffer(
sk_canvas_->clipRect(gfx::RectToSkRect(scissor_rect_),
SkRegion::kReplace_Op);
} else {
- sk_canvas_->clipRect(gfx::RectToSkRect(gfx::Rect(ViewportSize())),
+ sk_canvas_->clipRect(gfx::RectToSkRect(client_->DeviceViewport()),
SkRegion::kReplace_Op);
}
@@ -1970,9 +1959,10 @@ void GLRenderer::SwapBuffers(const ui::LatencyInfo& latency_info) {
if (capabilities_.using_partial_swap && client_->AllowPartialSwap()) {
// If supported, we can save significant bandwidth by only swapping the
// damaged/scissored region (clamped to the viewport)
- swap_buffer_rect_.Intersect(gfx::Rect(ViewportSize()));
+ swap_buffer_rect_.Intersect(client_->DeviceViewport());
int flipped_y_pos_of_rect_bottom =
- ViewportHeight() - swap_buffer_rect_.y() - swap_buffer_rect_.height();
+ client_->DeviceViewport().height() - swap_buffer_rect_.y() -
+ swap_buffer_rect_.height();
output_surface_->PostSubBuffer(gfx::Rect(swap_buffer_rect_.x(),
flipped_y_pos_of_rect_bottom,
swap_buffer_rect_.width(),
@@ -2126,8 +2116,9 @@ void GLRenderer::DoGetFramebufferPixels(
gfx::Rect rect,
bool flipped_y,
const AsyncGetFramebufferPixelsCleanupCallback& cleanup_callback) {
- DCHECK(rect.right() <= ViewportWidth());
- DCHECK(rect.bottom() <= ViewportHeight());
+ gfx::Rect window_rect = MoveFromDrawToWindowSpace(rect, flipped_y);
+ DCHECK_LE(window_rect.right(), current_surface_size_.width());
+ DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
bool is_async = !cleanup_callback.is_null();
@@ -2167,8 +2158,8 @@ void GLRenderer::DoGetFramebufferPixels(
GL_RGBA,
0,
0,
- current_framebuffer_size_.width(),
- current_framebuffer_size_.height(),
+ current_surface_size_.width(),
+ current_surface_size_.height(),
0));
temporary_fbo = context_->createFramebuffer();
// Attach this texture to an FBO, and perform the readback from that FBO.
@@ -2193,10 +2184,10 @@ void GLRenderer::DoGetFramebufferPixels(
GL_STREAM_READ));
GLC(context_,
- context_->readPixels(rect.x(),
- current_framebuffer_size_.height() - rect.bottom(),
- rect.width(),
- rect.height(),
+ context_->readPixels(window_rect.x(),
+ window_rect.y(),
+ window_rect.width(),
+ window_rect.height(),
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL));
@@ -2348,7 +2339,7 @@ void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
const ScopedResource* texture,
- gfx::Rect framebuffer_rect) {
+ gfx::Rect target_rect) {
DCHECK(texture->id());
current_framebuffer_lock_.reset();
@@ -2366,9 +2357,11 @@ bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
DCHECK(context_->checkFramebufferStatus(GL_FRAMEBUFFER) ==
GL_FRAMEBUFFER_COMPLETE || IsContextLost());
- InitializeMatrices(frame, framebuffer_rect, false);
- SetDrawViewportSize(framebuffer_rect.size());
-
+ InitializeViewport(frame,
+ target_rect,
+ gfx::Rect(target_rect.size()),
+ target_rect.size(),
+ false);
return true;
}
@@ -2389,10 +2382,11 @@ void GLRenderer::SetScissorTestRect(gfx::Rect scissor_rect) {
scissor_rect.height()));
}
-void GLRenderer::SetDrawViewportSize(gfx::Size viewport_size) {
- current_framebuffer_size_ = viewport_size;
- GLC(context_,
- context_->viewport(0, 0, viewport_size.width(), viewport_size.height()));
+void GLRenderer::SetDrawViewport(gfx::Rect window_space_viewport) {
+ GLC(context_, context_->viewport(window_space_viewport.x(),
+ window_space_viewport.y(),
+ window_space_viewport.width(),
+ window_space_viewport.height()));
}
bool GLRenderer::MakeContextCurrent() { return context_->makeContextCurrent(); }
@@ -2866,8 +2860,8 @@ void GLRenderer::ReinitializeGrCanvas() {
return;
GrBackendRenderTargetDesc desc;
- desc.fWidth = ViewportWidth();
- desc.fHeight = ViewportHeight();
+ desc.fWidth = client_->DeviceViewport().width();
+ desc.fHeight = client_->DeviceViewport().height();
desc.fConfig = kRGBA_8888_GrPixelConfig;
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fSampleCnt = 1;
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index 1c30d34..a45af22 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -104,8 +104,8 @@ class CC_EXPORT GLRenderer
virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) OVERRIDE;
virtual bool BindFramebufferToTexture(DrawingFrame* frame,
const ScopedResource* resource,
- gfx::Rect framebuffer_rect) OVERRIDE;
- virtual void SetDrawViewportSize(gfx::Size viewport_size) OVERRIDE;
+ gfx::Rect target_rect) OVERRIDE;
+ virtual void SetDrawViewport(gfx::Rect window_space_viewport) OVERRIDE;
virtual void SetScissorTestRect(gfx::Rect scissor_rect) OVERRIDE;
virtual void ClearFramebuffer(DrawingFrame* frame) OVERRIDE;
virtual void DoDrawQuad(DrawingFrame* frame, const class DrawQuad*) OVERRIDE;
@@ -399,7 +399,6 @@ class CC_EXPORT GLRenderer
scoped_ptr<SolidColorProgram> solid_color_program_;
scoped_ptr<SolidColorProgramAA> solid_color_program_aa_;
- OutputSurface* output_surface_;
WebKit::WebGraphicsContext3D* context_;
skia::RefPtr<GrContext> gr_context_;
@@ -407,7 +406,6 @@ class CC_EXPORT GLRenderer
gfx::Rect swap_buffer_rect_;
gfx::Rect scissor_rect_;
- bool is_viewport_changed_;
bool is_backbuffer_discarded_;
bool discard_backbuffer_when_not_visible_;
bool is_using_bind_uniform_;
@@ -423,7 +421,6 @@ class CC_EXPORT GLRenderer
ScopedPtrVector<PendingAsyncReadPixels> pending_async_read_pixels_;
scoped_ptr<ResourceProvider::ScopedWriteLockGL> current_framebuffer_lock_;
- gfx::Size current_framebuffer_size_;
scoped_refptr<ResourceProvider::Fence> last_swap_fence_;
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index 48a5951..0f901c5 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -153,8 +153,7 @@ class FakeRendererClient : public RendererClient {
memory_allocation_limit_bytes_(
PrioritizedResourceManager::DefaultMemoryAllocationLimit()),
viewport_size_(gfx::Size(1, 1)),
- scale_factor_(1.f),
- is_viewport_changed_(true) {
+ scale_factor_(1.f) {
root_layer_->CreateRenderSurface();
RenderPass::Id render_pass_id =
root_layer_->render_surface()->RenderPassId();
@@ -165,9 +164,9 @@ class FakeRendererClient : public RendererClient {
}
// RendererClient methods.
- virtual gfx::Size DeviceViewportSize() const OVERRIDE {
+ virtual gfx::Rect DeviceViewport() const OVERRIDE {
static gfx::Size fake_size(1, 1);
- return fake_size;
+ return gfx::Rect(fake_size);
}
virtual float DeviceScaleFactor() const OVERRIDE {
return scale_factor_;
@@ -209,10 +208,7 @@ class FakeRendererClient : public RendererClient {
gfx::Size viewport_size, float scale_factor) {
viewport_size_ = viewport_size;
scale_factor_ = scale_factor;
- is_viewport_changed_ = true;
}
- bool is_viewport_changed() const { return is_viewport_changed_; }
- void clear_viewport_changed() { is_viewport_changed_ = false; }
RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
RenderPassList* render_passes_in_draw_order() {
@@ -233,7 +229,6 @@ class FakeRendererClient : public RendererClient {
size_t memory_allocation_limit_bytes_;
gfx::Size viewport_size_;
float scale_factor_;
- bool is_viewport_changed_;
};
class FakeRendererGL : public GLRenderer {
@@ -1004,7 +999,7 @@ TEST(GLRendererTest2, ShouldClearRootRenderPass) {
&mock_client, output_surface.get(), resource_provider.get());
EXPECT_TRUE(renderer.Initialize());
- gfx::Rect viewport_rect(mock_client.DeviceViewportSize());
+ gfx::Rect viewport_rect(mock_client.DeviceViewport());
ScopedPtrVector<RenderPass>& render_passes =
*mock_client.render_passes_in_draw_order();
render_passes.clear();
@@ -1075,7 +1070,7 @@ TEST(GLRendererTest2, ScissorTestWhenClearing) {
EXPECT_TRUE(renderer.Initialize());
EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
- gfx::Rect viewport_rect(mock_client.DeviceViewportSize());
+ gfx::Rect viewport_rect(mock_client.DeviceViewport());
ScopedPtrVector<RenderPass>& render_passes =
*mock_client.render_passes_in_draw_order();
render_passes.clear();
@@ -1105,12 +1100,89 @@ TEST(GLRendererTest2, ScissorTestWhenClearing) {
renderer.DrawFrame(mock_client.render_passes_in_draw_order());
}
+class NonReshapableOutputSurface : public FakeOutputSurface {
+ public:
+ explicit NonReshapableOutputSurface(
+ scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
+ : FakeOutputSurface(context3d.Pass(), false) {}
+ virtual gfx::Size SurfaceSize() const OVERRIDE { return gfx::Size(500, 500); }
+};
+
+class OffsetViewportRendererClient : public FakeRendererClient {
+ public:
+ virtual gfx::Rect DeviceViewport() const OVERRIDE {
+ return gfx::Rect(10, 10, 100, 100);
+ }
+};
+
+class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
+ public:
+ FlippedScissorAndViewportContext()
+ : did_call_viewport_(false), did_call_scissor_(false) {}
+ virtual ~FlippedScissorAndViewportContext() {
+ EXPECT_TRUE(did_call_viewport_);
+ EXPECT_TRUE(did_call_scissor_);
+ }
+
+ virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
+ EXPECT_EQ(10, x);
+ EXPECT_EQ(390, y);
+ EXPECT_EQ(100, width);
+ EXPECT_EQ(100, height);
+ did_call_viewport_ = true;
+ }
+
+ virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
+ EXPECT_EQ(30, x);
+ EXPECT_EQ(450, y);
+ EXPECT_EQ(20, width);
+ EXPECT_EQ(20, height);
+ did_call_scissor_ = true;
+ }
+
+ private:
+ bool did_call_viewport_;
+ bool did_call_scissor_;
+};
+
+TEST(GLRendererTest2, ScissorAndViewportWithinNonreshapableSurface) {
+ // In Android WebView, the OutputSurface is unable to respect reshape() calls
+ // and maintains a fixed size. This test verifies that glViewport and
+ // glScissor's Y coordinate is flipped correctly in this environment, and that
+ // the glViewport can be at a nonzero origin within the surface.
+ OffsetViewportRendererClient mock_client;
+ scoped_ptr<OutputSurface> output_surface(make_scoped_ptr(
+ new NonReshapableOutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(
+ new FlippedScissorAndViewportContext))));
+ scoped_ptr<ResourceProvider> resource_provider(
+ ResourceProvider::Create(output_surface.get(), 0));
+ FakeRendererGL renderer(
+ &mock_client, output_surface.get(), resource_provider.get());
+ EXPECT_TRUE(renderer.Initialize());
+ EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
+
+ gfx::Rect viewport_rect(mock_client.DeviceViewport().size());
+ gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
+ ScopedPtrVector<RenderPass>& render_passes =
+ *mock_client.render_passes_in_draw_order();
+ render_passes.clear();
+
+ RenderPass::Id root_pass_id(1, 0);
+ TestRenderPass* root_pass = AddRenderPass(
+ &render_passes, root_pass_id, viewport_rect, gfx::Transform());
+ AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
+
+ renderer.DecideRenderPassAllocationsForFrame(
+ *mock_client.render_passes_in_draw_order());
+ renderer.DrawFrame(mock_client.render_passes_in_draw_order());
+}
+
// This test was never actually working as intended. Before adding
// ShaderCreatorMockGraphicsContext, all shader programs received the same
// program identifier from the TestWebGraphicsContext3D, so it always passed
// when checking which shader was used.
TEST_F(GLRendererShaderTest, DISABLED_DrawRenderPassQuadShaderPermutations) {
- gfx::Rect viewport_rect(mock_client_.DeviceViewportSize());
+ gfx::Rect viewport_rect(mock_client_.DeviceViewport());
ScopedPtrVector<RenderPass>* render_passes =
mock_client_.render_passes_in_draw_order();
@@ -1372,7 +1444,7 @@ TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
RenderPass::Id child_pass_id(2, 0);
TestRenderPass* child_pass;
- gfx::Rect viewport_rect(mock_client_.DeviceViewportSize());
+ gfx::Rect viewport_rect(mock_client_.DeviceViewport());
RenderPass::Id root_pass_id(1, 0);
TestRenderPass* root_pass;
@@ -1417,7 +1489,7 @@ TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
}
TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
- gfx::Rect viewport_rect(mock_client_.DeviceViewportSize());
+ gfx::Rect viewport_rect(mock_client_.DeviceViewport());
ScopedPtrVector<RenderPass>* render_passes =
mock_client_.render_passes_in_draw_order();
@@ -1474,7 +1546,9 @@ class MockOutputSurface : public OutputSurface {
public:
MockOutputSurface()
: OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D>(
- new StrictMock<OutputSurfaceMockContext>)) {}
+ new StrictMock<OutputSurfaceMockContext>)) {
+ surface_size_ = gfx::Size(100, 100);
+ }
virtual ~MockOutputSurface() {}
MOCK_METHOD1(SendFrameToParentCompositor, void(CompositorFrame* frame));
@@ -1497,7 +1571,7 @@ class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient {
void SwapBuffers() { renderer_.SwapBuffers(ui::LatencyInfo()); }
void DrawFrame() {
- gfx::Rect viewport_rect(DeviceViewportSize());
+ gfx::Rect viewport_rect(DeviceViewport());
ScopedPtrVector<RenderPass>* render_passes = render_passes_in_draw_order();
render_passes->clear();
@@ -1508,11 +1582,8 @@ class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient {
EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
- if (is_viewport_changed()) {
- EXPECT_CALL(output_surface_,
- Reshape(DeviceViewportSize(), DeviceScaleFactor())).Times(1);
- clear_viewport_changed();
- }
+ EXPECT_CALL(output_surface_,
+ Reshape(DeviceViewport().size(), DeviceScaleFactor())).Times(1);
EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index fe2b074..1be41892 100644
--- a/cc/output/output_surface.cc
+++ b/cc/output/output_surface.cc
@@ -46,14 +46,16 @@ OutputSurface::OutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
: client_(NULL),
context3d_(context3d.Pass()),
- has_gl_discard_backbuffer_(false) {
+ has_gl_discard_backbuffer_(false),
+ device_scale_factor_(-1) {
}
OutputSurface::OutputSurface(
scoped_ptr<cc::SoftwareOutputDevice> software_device)
: client_(NULL),
software_device_(software_device.Pass()),
- has_gl_discard_backbuffer_(false) {
+ has_gl_discard_backbuffer_(false),
+ device_scale_factor_(-1) {
}
OutputSurface::OutputSurface(
@@ -62,7 +64,8 @@ OutputSurface::OutputSurface(
: client_(NULL),
context3d_(context3d.Pass()),
software_device_(software_device.Pass()),
- has_gl_discard_backbuffer_(false) {
+ has_gl_discard_backbuffer_(false),
+ device_scale_factor_(-1) {
}
OutputSurface::~OutputSurface() {
@@ -112,8 +115,19 @@ void OutputSurface::DiscardBackbuffer() {
}
void OutputSurface::Reshape(gfx::Size size, float scale_factor) {
- DCHECK(context3d_);
- context3d_->reshapeWithScaleFactor(size.width(), size.height(), scale_factor);
+ if (size == surface_size_ && scale_factor == device_scale_factor_)
+ return;
+
+ surface_size_ = size;
+ device_scale_factor_ = scale_factor;
+ if (context3d_) {
+ context3d_->reshapeWithScaleFactor(
+ size.width(), size.height(), scale_factor);
+ }
+}
+
+gfx::Size OutputSurface::SurfaceSize() const {
+ return surface_size_;
}
void OutputSurface::BindFramebuffer() {
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
index d6f4b82..00877de 100644
--- a/cc/output/output_surface.h
+++ b/cc/output/output_surface.h
@@ -89,6 +89,7 @@ class CC_EXPORT OutputSurface {
virtual void DiscardBackbuffer();
virtual void Reshape(gfx::Size size, float scale_factor);
+ virtual gfx::Size SurfaceSize() const;
virtual void BindFramebuffer();
@@ -110,6 +111,8 @@ class CC_EXPORT OutputSurface {
scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
scoped_ptr<cc::SoftwareOutputDevice> software_device_;
bool has_gl_discard_backbuffer_;
+ gfx::Size surface_size_;
+ float device_scale_factor_;
scoped_ptr<OutputSurfaceCallbacks> callbacks_;
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h
index cbb3b8c..26edec8 100644
--- a/cc/output/output_surface_client.h
+++ b/cc/output/output_surface_client.h
@@ -9,6 +9,10 @@
#include "cc/base/cc_export.h"
#include "ui/gfx/rect.h"
+namespace gfx {
+class Transform;
+}
+
namespace cc {
class CompositorFrameAck;
@@ -23,6 +27,8 @@ class CC_EXPORT OutputSurfaceClient {
const CompositorFrameAck& ack) = 0;
virtual void OnSwapBuffersComplete() = 0;
virtual void DidLoseOutputSurface() = 0;
+ virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
+ gfx::Rect viewport) = 0;
protected:
virtual ~OutputSurfaceClient() {}
diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc
index a23ba93..d54afe2 100644
--- a/cc/output/output_surface_unittest.cc
+++ b/cc/output/output_surface_unittest.cc
@@ -36,6 +36,8 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
OVERRIDE {}
virtual void OnSwapBuffersComplete() OVERRIDE {}
virtual void DidLoseOutputSurface() OVERRIDE {}
+ virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
+ gfx::Rect viewport) OVERRIDE {}
};
TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientSuccess) {
diff --git a/cc/output/renderer.h b/cc/output/renderer.h
index aaf9fd7..a905d4c 100644
--- a/cc/output/renderer.h
+++ b/cc/output/renderer.h
@@ -20,7 +20,11 @@ class ScopedResource;
class CC_EXPORT RendererClient {
public:
- virtual gfx::Size DeviceViewportSize() const = 0;
+ // 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.
+ virtual gfx::Rect DeviceViewport() const = 0;
+
virtual float DeviceScaleFactor() const = 0;
virtual const LayerTreeSettings& Settings() const = 0;
virtual void SetFullRootLayerDamage() = 0;
@@ -44,12 +48,6 @@ class CC_EXPORT Renderer {
const LayerTreeSettings& Settings() const { return client_->Settings(); }
- gfx::Size ViewportSize() const { return client_->DeviceViewportSize(); }
- int ViewportWidth() const { return ViewportSize().width(); }
- int ViewportHeight() const { return ViewportSize().height(); }
-
- float DeviceScaleFactor() const { return client_->DeviceScaleFactor(); }
-
virtual void ViewportChanged() {}
virtual void ReceiveCompositorFrameAck(const CompositorFrameAck& ack) {}
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index d479e5f..2faa0d0 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -94,7 +94,10 @@ scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad(
return quad.PassAs<DrawQuad>();
}
-typedef ::testing::Types<GLRenderer, SoftwareRenderer> RendererTypes;
+typedef ::testing::Types<GLRenderer,
+ SoftwareRenderer,
+ GLRendererWithExpandedViewport,
+ SoftwareRendererWithExpandedViewport> RendererTypes;
TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
typedef ::testing::Types<GLRenderer,
@@ -135,6 +138,14 @@ bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
return fuzzy_.Compare(actual_bmp, expected_bmp);
}
+template <>
+bool FuzzyForSoftwareOnlyPixelComparator<
+ SoftwareRendererWithExpandedViewport>::Compare(
+ const SkBitmap& actual_bmp,
+ const SkBitmap& expected_bmp) const {
+ return fuzzy_.Compare(actual_bmp, expected_bmp);
+}
+
template<typename RendererType>
bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
const SkBitmap& actual_bmp,
diff --git a/cc/output/software_output_device.cc b/cc/output/software_output_device.cc
index 956ee6c..719eeed 100644
--- a/cc/output/software_output_device.cc
+++ b/cc/output/software_output_device.cc
@@ -8,6 +8,7 @@
#include "cc/output/software_frame_data.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDevice.h"
+#include "ui/gfx/skia_util.h"
namespace cc {
@@ -43,11 +44,8 @@ void SoftwareOutputDevice::EndPaint(SoftwareFrameData* frame_data) {
void SoftwareOutputDevice::CopyToBitmap(
gfx::Rect rect, SkBitmap* output) {
DCHECK(device_);
- SkIRect invert_rect = SkIRect::MakeXYWH(
- rect.x(), viewport_size_.height() - rect.bottom(),
- rect.width(), rect.height());
const SkBitmap& bitmap = device_->accessBitmap(false);
- bitmap.extractSubset(output, invert_rect);
+ bitmap.extractSubset(output, gfx::RectToSkIRect(rect));
}
void SoftwareOutputDevice::Scroll(
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc
index b555b57..c53e0c7 100644
--- a/cc/output/software_renderer.cc
+++ b/cc/output/software_renderer.cc
@@ -53,11 +53,10 @@ scoped_ptr<SoftwareRenderer> SoftwareRenderer::Create(
SoftwareRenderer::SoftwareRenderer(RendererClient* client,
OutputSurface* output_surface,
ResourceProvider* resource_provider)
- : DirectRenderer(client, resource_provider),
+ : DirectRenderer(client, output_surface, resource_provider),
visible_(true),
is_scissor_enabled_(false),
is_viewport_changed_(true),
- output_surface_(output_surface),
output_device_(output_surface->software_device()),
current_canvas_(NULL) {
if (resource_provider_) {
@@ -88,7 +87,7 @@ void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) {
TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame");
if (is_viewport_changed_) {
is_viewport_changed_ = false;
- output_device_->Resize(ViewportSize());
+ output_device_->Resize(client_->DeviceViewport().size());
}
root_canvas_ = output_device_->BeginPaint(
gfx::ToEnclosingRect(frame->root_damage_rect));
@@ -146,15 +145,17 @@ void SoftwareRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
bool SoftwareRenderer::BindFramebufferToTexture(
DrawingFrame* frame,
const ScopedResource* texture,
- gfx::Rect framebuffer_rect) {
+ gfx::Rect target_rect) {
current_framebuffer_lock_.reset();
current_framebuffer_lock_ = make_scoped_ptr(
new ResourceProvider::ScopedWriteLockSoftware(
resource_provider_, texture->id()));
current_canvas_ = current_framebuffer_lock_->sk_canvas();
- InitializeMatrices(frame, framebuffer_rect, false);
- SetDrawViewportSize(framebuffer_rect.size());
-
+ InitializeViewport(frame,
+ target_rect,
+ gfx::Rect(target_rect.size()),
+ target_rect.size(),
+ false);
return true;
}
@@ -193,7 +194,7 @@ void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame) {
}
}
-void SoftwareRenderer::SetDrawViewportSize(gfx::Size viewport_size) {}
+void SoftwareRenderer::SetDrawViewport(gfx::Rect window_space_viewport) {}
bool SoftwareRenderer::IsSoftwareResource(
ResourceProvider::ResourceId resource_id) const {
@@ -437,13 +438,12 @@ void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame,
void SoftwareRenderer::CopyCurrentRenderPassToBitmap(
DrawingFrame* frame,
scoped_ptr<CopyOutputRequest> request) {
- gfx::Size render_pass_size = frame->current_render_pass->output_rect.size();
-
scoped_ptr<SkBitmap> bitmap(new SkBitmap);
bitmap->setConfig(SkBitmap::kARGB_8888_Config,
- render_pass_size.width(),
- render_pass_size.height());
- current_canvas_->readPixels(bitmap.get(), 0, 0);
+ current_viewport_rect_.width(),
+ current_viewport_rect_.height());
+ current_canvas_->readPixels(
+ bitmap.get(), current_viewport_rect_.x(), current_viewport_rect_.y());
request->SendBitmapResult(bitmap.Pass());
}
@@ -451,6 +451,7 @@ void SoftwareRenderer::CopyCurrentRenderPassToBitmap(
void SoftwareRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) {
TRACE_EVENT0("cc", "SoftwareRenderer::GetFramebufferPixels");
SkBitmap subset_bitmap;
+ rect += current_viewport_rect_.OffsetFromOrigin();
output_device_->CopyToBitmap(rect, &subset_bitmap);
subset_bitmap.copyPixelsTo(pixels,
4 * rect.width() * rect.height(),
diff --git a/cc/output/software_renderer.h b/cc/output/software_renderer.h
index cbaf1d3..8eb9c0e 100644
--- a/cc/output/software_renderer.h
+++ b/cc/output/software_renderer.h
@@ -50,8 +50,8 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer {
virtual bool BindFramebufferToTexture(
DrawingFrame* frame,
const ScopedResource* texture,
- gfx::Rect framebuffer_rect) OVERRIDE;
- virtual void SetDrawViewportSize(gfx::Size viewport_size) OVERRIDE;
+ gfx::Rect target_rect) OVERRIDE;
+ virtual void SetDrawViewport(gfx::Rect window_space_viewport) OVERRIDE;
virtual void SetScissorTestRect(gfx::Rect scissor_rect) OVERRIDE;
virtual void ClearFramebuffer(DrawingFrame* frame) OVERRIDE;
virtual void DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) OVERRIDE;
@@ -64,12 +64,12 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer {
DrawingFrame* frame,
scoped_ptr<CopyOutputRequest> request) OVERRIDE;
- private:
SoftwareRenderer(
RendererClient* client,
OutputSurface* output_surface,
ResourceProvider* resource_provider);
+ private:
void ClearCanvas(SkColor color);
void SetClipRect(gfx::Rect rect);
bool IsSoftwareResource(ResourceProvider::ResourceId resource_id) const;
@@ -95,7 +95,6 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer {
bool is_viewport_changed_;
gfx::Rect scissor_rect_;
- OutputSurface* output_surface_;
SoftwareOutputDevice* output_device_;
SkCanvas* root_canvas_;
SkCanvas* current_canvas_;
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc
index af4d7d1..b4e91fc 100644
--- a/cc/output/software_renderer_unittest.cc
+++ b/cc/output/software_renderer_unittest.cc
@@ -18,6 +18,8 @@
#include "cc/test/render_pass_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkDevice.h"
namespace cc {
namespace {
@@ -26,9 +28,10 @@ class SoftwareRendererTest : public testing::Test, public RendererClient {
public:
SoftwareRendererTest() : should_clear_root_render_pass_(true) {}
- void InitializeRenderer() {
+ void InitializeRenderer(
+ scoped_ptr<SoftwareOutputDevice> software_output_device) {
output_surface_ = FakeOutputSurface::CreateSoftware(
- make_scoped_ptr(new SoftwareOutputDevice));
+ software_output_device.Pass());
resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
renderer_ = SoftwareRenderer::Create(
this, output_surface_.get(), resource_provider());
@@ -40,8 +43,8 @@ class SoftwareRendererTest : public testing::Test, public RendererClient {
SoftwareRenderer* renderer() const { return renderer_.get(); }
- void set_viewport_size(gfx::Size viewport_size) {
- viewport_size_ = viewport_size;
+ void set_viewport(gfx::Rect viewport) {
+ viewport_ = viewport;
}
void set_should_clear_root_render_pass(bool clear_root_render_pass) {
@@ -49,8 +52,8 @@ class SoftwareRendererTest : public testing::Test, public RendererClient {
}
// RendererClient implementation.
- virtual gfx::Size DeviceViewportSize() const OVERRIDE {
- return viewport_size_;
+ virtual gfx::Rect DeviceViewport() const OVERRIDE {
+ return viewport_;
}
virtual float DeviceScaleFactor() const OVERRIDE {
return 1.f;
@@ -78,7 +81,7 @@ class SoftwareRendererTest : public testing::Test, public RendererClient {
scoped_ptr<FakeOutputSurface> output_surface_;
scoped_ptr<ResourceProvider> resource_provider_;
scoped_ptr<SoftwareRenderer> renderer_;
- gfx::Size viewport_size_;
+ gfx::Rect viewport_;
LayerTreeSettings settings_;
bool should_clear_root_render_pass_;
};
@@ -88,9 +91,9 @@ TEST_F(SoftwareRendererTest, SolidColorQuad) {
gfx::Size inner_size(98, 98);
gfx::Rect outer_rect(outer_size);
gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
- set_viewport_size(outer_size);
+ set_viewport(gfx::Rect(outer_size));
- InitializeRenderer();
+ InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
shared_quad_state->SetAll(
@@ -113,8 +116,8 @@ TEST_F(SoftwareRendererTest, SolidColorQuad) {
SkBitmap output;
output.setConfig(SkBitmap::kARGB_8888_Config,
- DeviceViewportSize().width(),
- DeviceViewportSize().height());
+ DeviceViewport().width(),
+ DeviceViewport().height());
output.allocPixels();
renderer()->GetFramebufferPixels(output.getPixels(), outer_rect);
@@ -131,8 +134,8 @@ TEST_F(SoftwareRendererTest, TileQuad) {
gfx::Size inner_size(98, 98);
gfx::Rect outer_rect(outer_size);
gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
- set_viewport_size(outer_size);
- InitializeRenderer();
+ set_viewport(gfx::Rect(outer_size));
+ InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
ResourceProvider::ResourceId resource_yellow =
resource_provider()->CreateResource(
@@ -165,7 +168,7 @@ TEST_F(SoftwareRendererTest, TileQuad) {
gfx::Rect(inner_size),
gfx::Vector2d());
- gfx::Rect root_rect = gfx::Rect(DeviceViewportSize());
+ gfx::Rect root_rect = DeviceViewport();
scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
shared_quad_state->SetAll(
@@ -199,8 +202,8 @@ TEST_F(SoftwareRendererTest, TileQuad) {
SkBitmap output;
output.setConfig(SkBitmap::kARGB_8888_Config,
- DeviceViewportSize().width(),
- DeviceViewportSize().height());
+ DeviceViewport().width(),
+ DeviceViewport().height());
output.allocPixels();
renderer()->GetFramebufferPixels(output.getPixels(), outer_rect);
@@ -214,9 +217,9 @@ TEST_F(SoftwareRendererTest, TileQuad) {
TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) {
gfx::Rect viewport_rect(0, 0, 100, 100);
- set_viewport_size(viewport_rect.size());
+ set_viewport(viewport_rect);
set_should_clear_root_render_pass(false);
- InitializeRenderer();
+ InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
RenderPassList list;
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h
index 090571f..6eff484 100644
--- a/cc/test/fake_output_surface.h
+++ b/cc/test/fake_output_surface.h
@@ -81,7 +81,7 @@ class FakeOutputSurface : public OutputSurface {
}
virtual bool ForcedDrawToSoftwareDevice() const OVERRIDE;
- private:
+ protected:
FakeOutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
bool has_parent);
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 0885c76..1e75156 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -23,12 +23,12 @@ namespace cc {
class PixelTest::PixelTestRendererClient : public RendererClient {
public:
- explicit PixelTestRendererClient(gfx::Size device_viewport_size)
- : device_viewport_size_(device_viewport_size) {}
+ explicit PixelTestRendererClient(gfx::Rect device_viewport)
+ : device_viewport_(device_viewport) {}
// RendererClient implementation.
- virtual gfx::Size DeviceViewportSize() const OVERRIDE {
- return device_viewport_size_;
+ virtual gfx::Rect DeviceViewport() const OVERRIDE {
+ return device_viewport_ + test_expansion_offset_;
}
virtual float DeviceScaleFactor() const OVERRIDE {
return 1.f;
@@ -51,14 +51,60 @@ class PixelTest::PixelTestRendererClient : public RendererClient {
return true;
}
+ void SetTestExpansionOffset(gfx::Vector2d test_expansion_offset) {
+ test_expansion_offset_ = test_expansion_offset;
+ }
+
private:
- gfx::Size device_viewport_size_;
+ gfx::Rect device_viewport_;
+ gfx::Vector2d test_expansion_offset_;
LayerTreeSettings settings_;
};
+class PixelTest::PixelTestOutputSurface : public OutputSurface {
+ public:
+ explicit PixelTestOutputSurface(
+ scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
+ : OutputSurface(context3d.Pass()) {}
+ explicit PixelTestOutputSurface(
+ scoped_ptr<cc::SoftwareOutputDevice> software_device)
+ : OutputSurface(software_device.Pass()) {}
+ virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE {
+ OutputSurface::Reshape(
+ gfx::Size(size.width() + test_expansion_size_.width(),
+ size.height() + test_expansion_size_.height()),
+ scale_factor);
+ }
+
+ void SetTestExpansionSize(gfx::Size test_expansion_size) {
+ test_expansion_size_ = test_expansion_size;
+ }
+
+ private:
+ gfx::Size test_expansion_size_;
+};
+
+class PixelTestSoftwareOutputDevice : public SoftwareOutputDevice {
+ public:
+ PixelTestSoftwareOutputDevice() {}
+ virtual void Resize(gfx::Size size) OVERRIDE {
+ SoftwareOutputDevice::Resize(
+ gfx::Size(size.width() + test_expansion_size_.width(),
+ size.height() + test_expansion_size_.height()));
+ }
+
+ void SetTestExpansionSize(gfx::Size test_expansion_size) {
+ test_expansion_size_ = test_expansion_size;
+ }
+
+ private:
+ gfx::Size test_expansion_size_;
+};
+
PixelTest::PixelTest()
: device_viewport_size_(gfx::Size(200, 200)),
- fake_client_(new PixelTestRendererClient(device_viewport_size_)) {}
+ fake_client_(
+ new PixelTestRendererClient(gfx::Rect(device_viewport_size_))) {}
PixelTest::~PixelTest() {}
@@ -125,7 +171,7 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) {
scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d(
WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
WebKit::WebGraphicsContext3D::Attributes()));
- output_surface_.reset(new OutputSurface(
+ output_surface_.reset(new PixelTestOutputSurface(
context3d.PassAs<WebKit::WebGraphicsContext3D>()));
resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
renderer_ = GLRenderer::Create(fake_client_.get(),
@@ -140,11 +186,23 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) {
resource_provider_->set_offscreen_context_provider(offscreen_contexts);
}
+void PixelTest::ForceExpandedViewport(gfx::Size surface_expansion,
+ gfx::Vector2d viewport_offset) {
+ static_cast<PixelTestOutputSurface*>(output_surface_.get())
+ ->SetTestExpansionSize(surface_expansion);
+ fake_client_->SetTestExpansionOffset(viewport_offset);
+ SoftwareOutputDevice* device = output_surface_->software_device();
+ if (device) {
+ static_cast<PixelTestSoftwareOutputDevice*>(device)
+ ->SetTestExpansionSize(surface_expansion);
+ }
+}
+
void PixelTest::SetUpSoftwareRenderer() {
CHECK(fake_client_);
- scoped_ptr<SoftwareOutputDevice> device(new SoftwareOutputDevice());
- output_surface_.reset(new OutputSurface(device.Pass()));
+ scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice());
+ output_surface_.reset(new PixelTestOutputSurface(device.Pass()));
resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
renderer_ = SoftwareRenderer::Create(
fake_client_.get(),
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
index c7dd7aa..eb53e07 100644
--- a/cc/test/pixel_test.h
+++ b/cc/test/pixel_test.h
@@ -4,6 +4,7 @@
#include "base/file_util.h"
#include "cc/output/gl_renderer.h"
+#include "cc/output/software_renderer.h"
#include "cc/quads/render_pass.h"
#include "cc/test/pixel_comparator.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,9 +34,10 @@ class PixelTest : public testing::Test {
const PixelComparator& comparator);
gfx::Size device_viewport_size_;
+ class PixelTestOutputSurface;
+ class PixelTestRendererClient;
scoped_ptr<OutputSurface> output_surface_;
scoped_ptr<ResourceProvider> resource_provider_;
- class PixelTestRendererClient;
scoped_ptr<PixelTestRendererClient> fake_client_;
scoped_ptr<DirectRenderer> renderer_;
scoped_ptr<SkBitmap> result_bitmap_;
@@ -43,6 +45,9 @@ class PixelTest : public testing::Test {
void SetUpGLRenderer(bool use_skia_gpu_backend);
void SetUpSoftwareRenderer();
+ void ForceExpandedViewport(gfx::Size surface_expansion,
+ gfx::Vector2d viewport_offset);
+
private:
void ReadbackResult(base::Closure quit_run_loop, scoped_ptr<SkBitmap> bitmap);
@@ -58,6 +63,7 @@ class RendererPixelTest : public PixelTest {
}
bool UseSkiaGPUBackend() const;
+ bool ExpandedViewport() const;
protected:
virtual void SetUp() OVERRIDE;
@@ -77,6 +83,31 @@ class GLRendererWithSkiaGPUBackend : public GLRenderer {
highp_threshold_min) {}
};
+// Wrappers to differentiate renderers where the the output surface and viewport
+// have an externally determined size and offset.
+class GLRendererWithExpandedViewport : public GLRenderer {
+ public:
+ GLRendererWithExpandedViewport(RendererClient* client,
+ OutputSurface* output_surface,
+ ResourceProvider* resource_provider,
+ int highp_threshold_min)
+ : GLRenderer(client,
+ output_surface,
+ resource_provider,
+ highp_threshold_min) {}
+};
+
+class SoftwareRendererWithExpandedViewport : public SoftwareRenderer {
+ public:
+ SoftwareRendererWithExpandedViewport(RendererClient* client,
+ OutputSurface* output_surface,
+ ResourceProvider* resource_provider)
+ : SoftwareRenderer(client,
+ output_surface,
+ resource_provider) {}
+};
+
+
template<>
inline void RendererPixelTest<GLRenderer>::SetUp() {
SetUpGLRenderer(false);
@@ -89,6 +120,11 @@ inline bool RendererPixelTest<GLRenderer>::UseSkiaGPUBackend() const {
}
template<>
+inline bool RendererPixelTest<GLRenderer>::ExpandedViewport() const {
+ return false;
+}
+
+template<>
inline void RendererPixelTest<GLRendererWithSkiaGPUBackend>::SetUp() {
SetUpGLRenderer(true);
DCHECK(renderer()->CanUseSkiaGPUBackend());
@@ -100,6 +136,30 @@ RendererPixelTest<GLRendererWithSkiaGPUBackend>::UseSkiaGPUBackend() const {
return true;
}
+template <>
+inline bool RendererPixelTest<GLRendererWithSkiaGPUBackend>::ExpandedViewport()
+ const {
+ return false;
+}
+
+template<>
+inline void RendererPixelTest<GLRendererWithExpandedViewport>::SetUp() {
+ SetUpGLRenderer(false);
+ ForceExpandedViewport(gfx::Size(50, 50), gfx::Vector2d(10, 20));
+}
+
+template <>
+inline bool
+RendererPixelTest<GLRendererWithExpandedViewport>::UseSkiaGPUBackend() const {
+ return false;
+}
+
+template <>
+inline bool
+RendererPixelTest<GLRendererWithExpandedViewport>::ExpandedViewport() const {
+ return true;
+}
+
template<>
inline void RendererPixelTest<SoftwareRenderer>::SetUp() {
SetUpSoftwareRenderer();
@@ -110,6 +170,29 @@ inline bool RendererPixelTest<SoftwareRenderer>::UseSkiaGPUBackend() const {
return false;
}
+template <>
+inline bool RendererPixelTest<SoftwareRenderer>::ExpandedViewport() const {
+ return false;
+}
+
+template<>
+inline void RendererPixelTest<SoftwareRendererWithExpandedViewport>::SetUp() {
+ SetUpSoftwareRenderer();
+ ForceExpandedViewport(gfx::Size(50, 50), gfx::Vector2d(10, 20));
+}
+
+template <>
+inline bool RendererPixelTest<
+ SoftwareRendererWithExpandedViewport>::UseSkiaGPUBackend() const {
+ return false;
+}
+
+template <>
+inline bool RendererPixelTest<
+ SoftwareRendererWithExpandedViewport>::ExpandedViewport() const {
+ return true;
+}
+
typedef RendererPixelTest<GLRenderer> GLRendererPixelTest;
typedef RendererPixelTest<GLRendererWithSkiaGPUBackend>
GLRendererSkiaGPUBackendPixelTest;
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc
index 724fd37..56bf80b 100644
--- a/cc/trees/damage_tracker_unittest.cc
+++ b/cc/trees/damage_tracker_unittest.cc
@@ -36,6 +36,7 @@ void ExecuteCalculateDrawProperties(
LayerTreeHostCommon::CalculateDrawProperties(root,
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 4ba7d59..a637f02 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -715,6 +715,7 @@ void LayerTreeHost::UpdateLayers(Layer* root_layer,
LayerTreeHostCommon::CalculateDrawProperties(
root_layer,
device_viewport_size(),
+ gfx::Transform(),
device_scale_factor_,
page_scale_factor_,
root_scroll,
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 6123e25..88609329 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -406,8 +406,7 @@ gfx::Transform ComputeSizeDeltaCompensation(
gfx::Transform target_surface_space_to_container_layer_space;
// Calculate step 1a
- LayerImpl* container_target_surface =
- container ? container->render_target() : 0;
+ LayerImpl* container_target_surface = container->render_target();
for (LayerImpl* current_target_surface = NextTargetSurface(layer);
current_target_surface &&
current_target_surface != container_target_surface;
@@ -418,20 +417,18 @@ gfx::Transform ComputeSizeDeltaCompensation(
current_target_surface->render_surface()->draw_transform());
}
// Calculate step 1b
- if (container) {
- gfx::Transform container_layer_space_to_container_target_surface_space =
- container->draw_transform();
- container_layer_space_to_container_target_surface_space.Scale(
- container->contents_scale_x(), container->contents_scale_y());
-
- gfx::Transform container_target_surface_space_to_container_layer_space;
- if (container_layer_space_to_container_target_surface_space.GetInverse(
- &container_target_surface_space_to_container_layer_space)) {
- // Note: Again, Concat is used to conver the result coordinate space from
- // the container render surface to the container layer.
- target_surface_space_to_container_layer_space.ConcatTransform(
- container_target_surface_space_to_container_layer_space);
- }
+ gfx::Transform container_layer_space_to_container_target_surface_space =
+ container->draw_transform();
+ container_layer_space_to_container_target_surface_space.Scale(
+ container->contents_scale_x(), container->contents_scale_y());
+
+ gfx::Transform container_target_surface_space_to_container_layer_space;
+ if (container_layer_space_to_container_target_surface_space.GetInverse(
+ &container_target_surface_space_to_container_layer_space)) {
+ // Note: Again, Concat is used to conver the result coordinate space from
+ // the container render surface to the container layer.
+ target_surface_space_to_container_layer_space.ConcatTransform(
+ container_target_surface_space_to_container_layer_space);
}
// Apply step 3
@@ -482,8 +479,7 @@ void ApplyPositionAdjustment(
layer->position_constraint().is_fixed_to_right_edge();
bool fixed_to_bottom_edge =
layer->position_constraint().is_fixed_to_bottom_edge();
- gfx::Vector2dF position_offset =
- container ? container->fixed_container_size_delta() : gfx::Vector2dF();
+ gfx::Vector2dF position_offset = container->fixed_container_size_delta();
position_offset.set_x(fixed_to_right_edge ? position_offset.x() : 0);
position_offset.set_y(fixed_to_bottom_edge ? position_offset.y() : 0);
if (position_offset.IsZero())
@@ -1115,41 +1111,39 @@ static void CalculateDrawPropertiesInternal(
RenderSurfaceType* render_surface = layer->render_surface();
render_surface->ClearLayerLists();
- // The owning layer's draw transform has a scale from content to layer
- // space which we do not want; so here we use the combined_transform
- // instead of the draw_transform. However, we do need to add a different
- // scale factor that accounts for the surface's pixel dimensions.
- combined_transform.Scale(1.0 / render_surface_sublayer_scale.x(),
- 1.0 / render_surface_sublayer_scale.y());
- render_surface->SetDrawTransform(combined_transform);
-
- // If this is the root layer, there should be no scale in the surface's draw
- // transform.
if (IsRootLayer(layer)) {
- DCHECK_EQ(render_surface_sublayer_scale.x(),
- combined_transform_scales.x());
- DCHECK_EQ(render_surface_sublayer_scale.y(),
- combined_transform_scales.y());
+ // The root layer's render surface size is predetermined and so the root
+ // layer can't directly support non-identity transforms. It should just
+ // forward top-level transforms to the rest of the tree.
+ sublayer_matrix = combined_transform;
+ } else {
+ // The owning layer's draw transform has a scale from content to layer
+ // space which we do not want; so here we use the combined_transform
+ // instead of the draw_transform. However, we do need to add a different
+ // scale factor that accounts for the surface's pixel dimensions.
+ combined_transform.Scale(1.0 / render_surface_sublayer_scale.x(),
+ 1.0 / render_surface_sublayer_scale.y());
+ render_surface->SetDrawTransform(combined_transform);
+
+ // The owning layer's transform was re-parented by the surface, so the
+ // layer's new draw_transform only needs to scale the layer to surface
+ // space.
+ layer_draw_properties.target_space_transform.MakeIdentity();
+ layer_draw_properties.target_space_transform.
+ Scale(render_surface_sublayer_scale.x() / layer->contents_scale_x(),
+ render_surface_sublayer_scale.y() / layer->contents_scale_y());
+
+ // Inside the surface's subtree, we scale everything to the owning layer's
+ // scale. The sublayer matrix transforms layer rects into target surface
+ // content space. Conceptually, all layers in the subtree inherit the
+ // scale at the point of the render surface in the transform hierarchy,
+ // but we apply it explicitly to the owning layer and the remainder of the
+ // subtree independently.
+ DCHECK(sublayer_matrix.IsIdentity());
+ sublayer_matrix.Scale(render_surface_sublayer_scale.x(),
+ render_surface_sublayer_scale.y());
}
- // The owning layer's transform was re-parented by the surface, so the
- // layer's new draw_transform only needs to scale the layer to surface
- // space.
- layer_draw_properties.target_space_transform.MakeIdentity();
- layer_draw_properties.target_space_transform.
- Scale(render_surface_sublayer_scale.x() / layer->contents_scale_x(),
- render_surface_sublayer_scale.y() / layer->contents_scale_y());
-
- // Inside the surface's subtree, we scale everything to the owning layer's
- // scale. The sublayer matrix transforms layer rects into target surface
- // content space. Conceptually, all layers in the subtree inherit the scale
- // at the point of the render surface in the transform hierarchy, but we
- // apply it explicitly to the owning layer and the remainder of the subtree
- // indenpendently.
- DCHECK(sublayer_matrix.IsIdentity());
- sublayer_matrix.Scale(render_surface_sublayer_scale.x(),
- render_surface_sublayer_scale.y());
-
// The opacity value is moved from the layer to its surface, so that the
// entire subtree properly inherits opacity.
render_surface->SetDrawOpacity(accumulated_draw_opacity);
@@ -1337,6 +1331,7 @@ static void CalculateDrawPropertiesInternal(
LayerType* child =
LayerTreeHostCommon::get_child_as_raw_ptr(layer->children(), i);
gfx::Rect drawable_content_rect_of_child_subtree;
+ gfx::Transform identity_matrix;
CalculateDrawPropertiesInternal<LayerType, LayerList, RenderSurfaceType>(
child,
sublayer_matrix,
@@ -1526,6 +1521,7 @@ static void CalculateDrawPropertiesInternal(
void LayerTreeHostCommon::CalculateDrawProperties(
Layer* root_layer,
gfx::Size device_viewport_size,
+ const gfx::Transform& device_transform,
float device_scale_factor,
float page_scale_factor,
Layer* page_scale_application_layer,
@@ -1535,8 +1531,8 @@ void LayerTreeHostCommon::CalculateDrawProperties(
LayerList* render_surface_layer_list) {
gfx::Rect total_drawable_content_rect;
gfx::Transform identity_matrix;
- gfx::Transform device_scale_transform;
- device_scale_transform.Scale(device_scale_factor, device_scale_factor);
+ gfx::Transform scaled_device_transform = device_transform;
+ scaled_device_transform.Scale(device_scale_factor, device_scale_factor);
LayerList dummy_layer_list;
// The root layer's render_surface should receive the device viewport as the
@@ -1551,10 +1547,10 @@ void LayerTreeHostCommon::CalculateDrawProperties(
PreCalculateMetaInformation<Layer>(root_layer);
CalculateDrawPropertiesInternal<Layer, LayerList, RenderSurface>(
root_layer,
- device_scale_transform,
+ scaled_device_transform,
identity_matrix,
identity_matrix,
- NULL,
+ root_layer,
device_viewport_rect,
device_viewport_rect,
subtree_should_be_clipped,
@@ -1581,6 +1577,7 @@ void LayerTreeHostCommon::CalculateDrawProperties(
void LayerTreeHostCommon::CalculateDrawProperties(
LayerImpl* root_layer,
gfx::Size device_viewport_size,
+ const gfx::Transform& device_transform,
float device_scale_factor,
float page_scale_factor,
LayerImpl* page_scale_application_layer,
@@ -1590,8 +1587,8 @@ void LayerTreeHostCommon::CalculateDrawProperties(
LayerImplList* render_surface_layer_list) {
gfx::Rect total_drawable_content_rect;
gfx::Transform identity_matrix;
- gfx::Transform device_scale_transform;
- device_scale_transform.Scale(device_scale_factor, device_scale_factor);
+ gfx::Transform scaled_device_transform = device_transform;
+ scaled_device_transform.Scale(device_scale_factor, device_scale_factor);
LayerImplList dummy_layer_list;
LayerSorter layer_sorter;
@@ -1609,10 +1606,10 @@ void LayerTreeHostCommon::CalculateDrawProperties(
LayerImplList,
RenderSurfaceImpl>(
root_layer,
- device_scale_transform,
+ scaled_device_transform,
identity_matrix,
identity_matrix,
- NULL,
+ root_layer,
device_viewport_rect,
device_viewport_rect,
subtree_should_be_clipped,
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index 165cd5e..b2b39c4 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -29,6 +29,7 @@ class CC_EXPORT LayerTreeHostCommon {
static void CalculateDrawProperties(
Layer* root_layer,
gfx::Size device_viewport_size,
+ const gfx::Transform& device_transform,
float device_scale_factor,
float page_scale_factor,
Layer* page_scale_application_layer,
@@ -39,6 +40,7 @@ class CC_EXPORT LayerTreeHostCommon {
static void CalculateDrawProperties(
LayerImpl* root_layer,
gfx::Size device_viewport_size,
+ const gfx::Transform& device_transform,
float device_scale_factor,
float page_scale_factor,
LayerImpl* page_scale_application_layer,
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index aa9c7f0..8fa91ce 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -99,6 +99,7 @@ void ExecuteCalculateDrawProperties(Layer* root_layer,
LayerTreeHostCommon::CalculateDrawProperties(
root_layer,
device_viewport_size,
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
page_scale_application_layer,
@@ -126,6 +127,7 @@ void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
LayerTreeHostCommon::CalculateDrawProperties(
root_layer,
device_viewport_size,
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
page_scale_application_layer,
@@ -1484,6 +1486,121 @@ TEST(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) {
grand_child->draw_transform());
}
+TEST(LayerTreeHostCommonTest, TransformAboveRootLayer) {
+ // Transformations applied at the root of the tree should be forwarded
+ // to child layers instead of applied to the root RenderSurface.
+ const gfx::Transform identity_matrix;
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> child = Layer::Create();
+
+ root->AddChild(child);
+
+ SetLayerPropertiesForTesting(root.get(),
+ identity_matrix,
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(20, 20),
+ false);
+ SetLayerPropertiesForTesting(child.get(),
+ identity_matrix,
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(20, 20),
+ false);
+
+ LayerList render_surface_layer_list;
+ int dummy_max_texture_size = 512;
+
+ gfx::Transform translate;
+ translate.Translate(50, 50);
+ LayerTreeHostCommon::CalculateDrawProperties(root.get(),
+ root->bounds(),
+ translate,
+ 1.f,
+ 1.f,
+ NULL,
+ dummy_max_texture_size,
+ false,
+ true, // can_adjust_raster_scale
+ &render_surface_layer_list);
+ EXPECT_EQ(translate, root->draw_properties().target_space_transform);
+ EXPECT_EQ(translate, child->draw_properties().target_space_transform);
+ EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
+
+ gfx::Transform scale;
+ scale.Scale(2, 2);
+ LayerTreeHostCommon::CalculateDrawProperties(root.get(),
+ root->bounds(),
+ scale,
+ 1.f,
+ 1.f,
+ NULL,
+ dummy_max_texture_size,
+ false,
+ true, // can_adjust_raster_scale
+ &render_surface_layer_list);
+ EXPECT_EQ(scale, root->draw_properties().target_space_transform);
+ EXPECT_EQ(scale, child->draw_properties().target_space_transform);
+ EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
+
+ gfx::Transform rotate;
+ rotate.Rotate(2);
+ LayerTreeHostCommon::CalculateDrawProperties(root.get(),
+ root->bounds(),
+ rotate,
+ 1.f,
+ 1.f,
+ NULL,
+ dummy_max_texture_size,
+ false,
+ true, // can_adjust_raster_scale
+ &render_surface_layer_list);
+ EXPECT_EQ(rotate, root->draw_properties().target_space_transform);
+ EXPECT_EQ(rotate, child->draw_properties().target_space_transform);
+ EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
+
+ gfx::Transform composite;
+ composite.ConcatTransform(translate);
+ composite.ConcatTransform(scale);
+ composite.ConcatTransform(rotate);
+ LayerTreeHostCommon::CalculateDrawProperties(root.get(),
+ root->bounds(),
+ composite,
+ 1.f,
+ 1.f,
+ NULL,
+ dummy_max_texture_size,
+ false,
+ true, // can_adjust_raster_scale
+ &render_surface_layer_list);
+ EXPECT_EQ(composite, root->draw_properties().target_space_transform);
+ EXPECT_EQ(composite, child->draw_properties().target_space_transform);
+ EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
+
+ // Verify that it composes correctly with transforms directly on root layer.
+ root->SetTransform(composite);
+ root->SetSublayerTransform(composite);
+ LayerTreeHostCommon::CalculateDrawProperties(root.get(),
+ root->bounds(),
+ composite,
+ 1.f,
+ 1.f,
+ NULL,
+ dummy_max_texture_size,
+ false,
+ true, // can_adjust_raster_scale
+ &render_surface_layer_list);
+ gfx::Transform compositeSquared = composite;
+ compositeSquared.ConcatTransform(composite);
+ gfx::Transform compositeCubed = compositeSquared;
+ compositeCubed.ConcatTransform(composite);
+ EXPECT_EQ(compositeSquared, root->draw_properties().target_space_transform);
+ EXPECT_EQ(compositeCubed, child->draw_properties().target_space_transform);
+ EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
+}
+
TEST(LayerTreeHostCommonTest,
RenderSurfaceListForRenderSurfaceWithClippedLayer) {
scoped_refptr<Layer> parent = Layer::Create();
@@ -1523,6 +1640,7 @@ TEST(LayerTreeHostCommonTest,
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1572,6 +1690,7 @@ TEST(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1631,6 +1750,7 @@ TEST(LayerTreeHostCommonTest, ForceRenderSurface) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1648,6 +1768,7 @@ TEST(LayerTreeHostCommonTest, ForceRenderSurface) {
render_surface1->SetForceRenderSurface(false);
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1749,6 +1870,7 @@ TEST(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1830,6 +1952,7 @@ TEST(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1854,6 +1977,7 @@ TEST(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) {
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1958,6 +2082,7 @@ TEST(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -1987,6 +2112,7 @@ TEST(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) {
parent->SetMasksToBounds(true);
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -2015,6 +2141,7 @@ TEST(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) {
child2->SetMasksToBounds(true);
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -2123,6 +2250,7 @@ TEST(LayerTreeHostCommonTest, drawable_content_rectForLayers) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -2268,6 +2396,7 @@ TEST(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -3598,6 +3727,7 @@ TEST(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -3792,6 +3922,7 @@ TEST(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -3932,6 +4063,7 @@ TEST(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4060,6 +4192,7 @@ TEST(LayerTreeHostCommonTest,
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4138,6 +4271,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForSingleLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4214,6 +4348,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForSingleLayerAndHud) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
hud_bounds,
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4282,6 +4417,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForUninvertibleTransform) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4359,6 +4495,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForSinglePositionedLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4425,6 +4562,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForSingleRotatedLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4504,6 +4642,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForSinglePerspectiveLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4594,6 +4733,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForSingleLayerWithScaledContents) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4695,6 +4835,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForSimpleClippedLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4829,6 +4970,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForMultiClippedRotatedLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -4956,6 +5098,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForNonClippingIntermediateLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -5074,6 +5217,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForMultipleLayers) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -5228,6 +5372,7 @@ TEST(LayerTreeHostCommonTest, HitTestingForMultipleLayerLists) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -5346,6 +5491,7 @@ TEST(LayerTreeHostCommonTest, HitCheckingTouchHandlerRegionsForSingleLayer) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -5444,6 +5590,7 @@ TEST(LayerTreeHostCommonTest,
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -5532,6 +5679,7 @@ TEST(LayerTreeHostCommonTest,
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -5638,6 +5786,7 @@ TEST(LayerTreeHostCommonTest,
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -5751,6 +5900,7 @@ TEST(LayerTreeHostCommonTest,
gfx::ScaleSize(root->bounds(), device_scale_factor * page_scale_factor));
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
scaled_bounds_for_root,
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
root.get(),
@@ -5891,6 +6041,7 @@ TEST(LayerTreeHostCommonTest,
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -6036,6 +6187,7 @@ TEST(LayerTreeHostCommonTest, LayerTransformsInHighDPI) {
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6173,6 +6325,7 @@ TEST(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) {
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6273,6 +6426,7 @@ TEST(LayerTreeHostCommonTest,
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6412,6 +6566,7 @@ TEST(LayerTreeHostCommonTest, ContentsScale) {
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6454,6 +6609,7 @@ TEST(LayerTreeHostCommonTest, ContentsScale) {
render_surface_layer_list.clear();
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6482,6 +6638,7 @@ TEST(LayerTreeHostCommonTest, ContentsScale) {
render_surface_layer_list.clear();
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6507,6 +6664,7 @@ TEST(LayerTreeHostCommonTest, ContentsScale) {
render_surface_layer_list.clear();
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6595,6 +6753,7 @@ TEST(LayerTreeHostCommonTest,
LayerTreeHostCommon::CalculateDrawProperties(
root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6678,6 +6837,7 @@ TEST(LayerTreeHostCommonTest, SmallContentsScale) {
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6703,6 +6863,7 @@ TEST(LayerTreeHostCommonTest, SmallContentsScale) {
render_surface_layer_list.clear();
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -6824,6 +6985,7 @@ TEST(LayerTreeHostCommonTest, ContentsScaleForSurfaces) {
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -7039,6 +7201,7 @@ TEST(LayerTreeHostCommonTest,
LayerTreeHostCommon::CalculateDrawProperties(
root.get(),
root->bounds(),
+ gfx::Transform(),
device_scale_factor,
page_scale_factor,
parent.get(),
@@ -7192,6 +7355,7 @@ TEST(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) {
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -7210,6 +7374,7 @@ TEST(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) {
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -7280,6 +7445,7 @@ TEST(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
float device_scale_factor = 1.5f;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
device_scale_factor,
1.f,
NULL,
@@ -7417,6 +7583,7 @@ TEST(LayerTreeHostCommonTest,
float device_scale_factor = 1.7f;
LayerTreeHostCommon::CalculateDrawProperties(parent.get(),
parent->bounds(),
+ gfx::Transform(),
device_scale_factor,
1.f,
NULL,
@@ -7571,6 +7738,7 @@ TEST(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
int dummy_max_texture_size = 512;
LayerTreeHostCommon::CalculateDrawProperties(root.get(),
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 7d8bf91..5d84fcd 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -165,8 +165,6 @@ LayerTreeHostImpl::LayerTreeHostImpl(
wheel_scrolling_(false),
root_layer_scroll_offset_delegate_(NULL),
settings_(settings),
- overdraw_bottom_height_(0.f),
- device_scale_factor_(1.f),
visible_(true),
managed_memory_policy_(
PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
@@ -182,6 +180,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
last_sent_memory_visible_bytes_(0),
last_sent_memory_visible_and_nearby_bytes_(0),
last_sent_memory_use_bytes_(0),
+ device_scale_factor_(1.f),
+ overdraw_bottom_height_(0.f),
animation_registrar_(AnimationRegistrar::Create()),
rendering_stats_instrumentation_(rendering_stats_instrumentation) {
DCHECK(proxy_->IsImplThread());
@@ -1040,6 +1040,13 @@ void LayerTreeHostImpl::SetManagedMemoryPolicy(
client_->SetNeedsCommitOnImplThread();
}
+void LayerTreeHostImpl::SetExternalDrawConstraints(
+ const gfx::Transform& transform,
+ gfx::Rect viewport) {
+ external_transform_ = transform;
+ external_viewport_ = viewport;
+}
+
void LayerTreeHostImpl::SetNeedsRedrawRect(gfx::Rect damage_rect) {
client_->SetNeedsRedrawRectOnImplThread(damage_rect);
}
@@ -1221,17 +1228,13 @@ void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) {
output_surface_->SetNeedsBeginFrame(enable);
}
-gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
- return device_viewport_size();
-}
-
float LayerTreeHostImpl::DeviceScaleFactor() const {
return device_scale_factor_;
}
gfx::SizeF LayerTreeHostImpl::VisibleViewportSize() const {
gfx::SizeF dip_size =
- gfx::ScaleSize(DeviceViewportSize(), 1.f / device_scale_factor());
+ gfx::ScaleSize(device_viewport_size(), 1.f / device_scale_factor());
// The clip layer should be used if non-overlay scrollbars may exist since
// it adjusts for them.
@@ -1553,6 +1556,17 @@ void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
SetFullRootLayerDamage();
}
+gfx::Rect LayerTreeHostImpl::DeviceViewport() const {
+ if (external_viewport_.IsEmpty())
+ return gfx::Rect(device_viewport_size_);
+
+ return external_viewport_;
+}
+
+const gfx::Transform& LayerTreeHostImpl::DeviceTransform() const {
+ return external_transform_;
+}
+
void LayerTreeHostImpl::UpdateMaxScrollOffset() {
active_tree_->UpdateMaxScrollOffset();
}
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index f65922a..e3671cf 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -176,8 +176,8 @@ class CC_EXPORT LayerTreeHostImpl
gfx::SizeF VisibleViewportSize() const;
// RendererClient implementation
+ virtual gfx::Rect DeviceViewport() const OVERRIDE;
private:
- virtual gfx::Size DeviceViewportSize() const OVERRIDE;
virtual float DeviceScaleFactor() const OVERRIDE;
virtual const LayerTreeSettings& Settings() const OVERRIDE;
public:
@@ -207,6 +207,8 @@ class CC_EXPORT LayerTreeHostImpl
OVERRIDE;
virtual void OnSendFrameToParentCompositorAck(const CompositorFrameAck& ack)
OVERRIDE;
+ virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
+ gfx::Rect viewport) OVERRIDE;
// Called from LayerTreeImpl.
void OnCanDrawStateChangedForTree();
@@ -267,6 +269,8 @@ class CC_EXPORT LayerTreeHostImpl
void SetDeviceScaleFactor(float device_scale_factor);
float device_scale_factor() const { return device_scale_factor_; }
+ const gfx::Transform& DeviceTransform() const;
+
scoped_ptr<ScrollAndScaleSet> ProcessScrollDeltas();
bool needs_animate_layers() const {
@@ -457,9 +461,6 @@ class CC_EXPORT LayerTreeHostImpl
LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate_;
LayerTreeSettings settings_;
LayerTreeDebugState debug_state_;
- gfx::Size device_viewport_size_;
- float overdraw_bottom_height_;
- float device_scale_factor_;
bool visible_;
ManagedMemoryPolicy managed_memory_policy_;
@@ -493,6 +494,26 @@ class CC_EXPORT LayerTreeHostImpl
size_t last_sent_memory_visible_and_nearby_bytes_;
size_t last_sent_memory_use_bytes_;
+ // Viewport size passed in from the main thread, in physical pixels.
+ gfx::Size device_viewport_size_;
+
+ // Conversion factor from CSS pixels to physical pixels when
+ // pageScaleFactor=1.
+ float device_scale_factor_;
+
+ // Vertical amount of the viewport size that's known to covered by a
+ // browser-side UI element, such as an on-screen-keyboard. This affects
+ // scrollable size since we want to still be able to scroll to the bottom of
+ // 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.
+ gfx::Transform external_transform_;
+ gfx::Rect external_viewport_;
+
gfx::Rect viewport_damage_rect_;
base::TimeTicks current_frame_timeticks_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index ab97c86..95bc4fe 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -4602,8 +4602,8 @@ class TestRenderer : public GLRenderer, public RendererClient {
}
// RendererClient implementation.
- virtual gfx::Size DeviceViewportSize() const OVERRIDE {
- return viewport_size_;
+ virtual gfx::Rect DeviceViewport() const OVERRIDE {
+ return gfx::Rect(viewport_size_);
}
virtual float DeviceScaleFactor() const OVERRIDE {
return 1.f;
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 6bc370c..e8ae6f1 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -282,7 +282,8 @@ void LayerTreeImpl::UpdateDrawProperties() {
IsActiveTree());
LayerTreeHostCommon::CalculateDrawProperties(
root_layer(),
- device_viewport_size(),
+ layer_tree_host_impl_->DeviceViewport().size(),
+ layer_tree_host_impl_->DeviceTransform(),
device_scale_factor(),
total_page_scale_factor(),
root_scroll_layer_,
diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc
index 09c64ef..7cf6aa7 100644
--- a/cc/trees/occlusion_tracker_unittest.cc
+++ b/cc/trees/occlusion_tracker_unittest.cc
@@ -316,6 +316,7 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
LayerTreeHostCommon::CalculateDrawProperties(
root,
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
@@ -337,6 +338,7 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
LayerTreeHostCommon::CalculateDrawProperties(
root,
root->bounds(),
+ gfx::Transform(),
1.f,
1.f,
NULL,
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 d5876e4..b0e2d0e 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -154,24 +154,33 @@ bool SynchronousCompositorOutputSurface::IsHwReady() {
return context3d() != NULL;
}
+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);
+}
+} // namespace
+
bool SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
DCHECK(CalledOnValidThread());
DCHECK(canvas);
DCHECK(!current_sw_canvas_);
current_sw_canvas_ = canvas;
- SkRect canvas_clip;
- gfx::Rect damage_area;
- if (canvas->getClipBounds(&canvas_clip)) {
- damage_area = gfx::ToEnclosedRect(gfx::SkRectToRectF(canvas_clip));
- } else {
- damage_area = gfx::Rect(kint16max, kint16max);
- }
+ SkIRect canvas_clip;
+ canvas->getClipDeviceBounds(&canvas_clip);
+ gfx::Rect clip = gfx::SkIRectToRect(canvas_clip);
- gfx::Transform transform;
+ 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());
+ client_->SetExternalDrawConstraints(transform, clip);
- InvokeComposite(transform, damage_area);
+ InvokeComposite(clip.size());
bool finished_draw = current_sw_canvas_ == NULL;
current_sw_canvas_ = NULL;
@@ -179,9 +188,9 @@ bool SynchronousCompositorOutputSurface::DemandDrawSw(SkCanvas* canvas) {
}
bool SynchronousCompositorOutputSurface::DemandDrawHw(
- gfx::Size view_size,
+ gfx::Size surface_size,
const gfx::Transform& transform,
- gfx::Rect damage_area) {
+ gfx::Rect clip) {
DCHECK(CalledOnValidThread());
DCHECK(client_);
DCHECK(context3d());
@@ -196,17 +205,18 @@ bool SynchronousCompositorOutputSurface::DemandDrawHw(
did_swap_buffer_ = false;
- InvokeComposite(transform, damage_area);
+ gfx::Transform adjusted_transform = transform;
+ AdjustTransformForClip(&adjusted_transform, clip);
+ surface_size_ = surface_size;
+ client_->SetExternalDrawConstraints(adjusted_transform, clip);
+ InvokeComposite(clip.size());
return did_swap_buffer_;
}
void SynchronousCompositorOutputSurface::InvokeComposite(
- const gfx::Transform& transform,
- gfx::Rect damage_area) {
- // TODO(boliu): This assumes |transform| is identity and |damage_area| is the
- // whole view. Tracking bug to implement this: crbug.com/230463.
- client_->SetNeedsRedrawRect(damage_area);
+ gfx::Size damage_size) {
+ client_->SetNeedsRedrawRect(gfx::Rect(damage_size));
if (needs_begin_frame_)
client_->BeginFrame(base::TimeTicks::Now());
}
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 d6af43b..78672fd 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.h
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h
@@ -55,7 +55,7 @@ class SynchronousCompositorOutputSurface
// Partial SynchronousCompositor API implementation.
bool IsHwReady();
bool DemandDrawSw(SkCanvas* canvas);
- bool DemandDrawHw(gfx::Size view_size,
+ bool DemandDrawHw(gfx::Size surface_size,
const gfx::Transform& transform,
gfx::Rect clip);
@@ -63,7 +63,7 @@ class SynchronousCompositorOutputSurface
class SoftwareDevice;
friend class SoftwareDevice;
- void InvokeComposite(const gfx::Transform& transform, gfx::Rect damage_area);
+ void InvokeComposite(gfx::Size damage_size);
void UpdateCompositorClientSettings();
void NotifyCompositorSettingsChanged();
bool CalledOnValidThread() const;
diff --git a/content/renderer/gpu/mailbox_output_surface.cc b/content/renderer/gpu/mailbox_output_surface.cc
index aa9b4b0..d7b13ce 100644
--- a/content/renderer/gpu/mailbox_output_surface.cc
+++ b/content/renderer/gpu/mailbox_output_surface.cc
@@ -45,7 +45,7 @@ void MailboxOutputSurface::EnsureBackbuffer() {
// Find a texture of matching size to recycle.
while (!returned_textures_.empty()) {
TransferableFrame& texture = returned_textures_.front();
- if (texture.size == size_) {
+ if (texture.size == surface_size_) {
current_backing_ = texture;
if (current_backing_.sync_point)
context3d_->waitSyncPoint(current_backing_.sync_point);
@@ -59,7 +59,7 @@ void MailboxOutputSurface::EnsureBackbuffer() {
if (!current_backing_.texture_id) {
current_backing_.texture_id = context3d_->createTexture();
- current_backing_.size = size_;
+ current_backing_.size = surface_size_;
context3d_->bindTexture(GL_TEXTURE_2D, current_backing_.texture_id);
context3d_->texParameteri(
GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -70,7 +70,8 @@ void MailboxOutputSurface::EnsureBackbuffer() {
context3d_->texParameteri(
GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
context3d_->texImage2D(
- GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0,
+ GL_TEXTURE_2D, 0, GL_RGBA,
+ surface_size_.width(), surface_size_.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
context3d_->genMailboxCHROMIUM(current_backing_.mailbox.name);
context3d_->produceTextureCHROMIUM(
@@ -101,10 +102,11 @@ void MailboxOutputSurface::DiscardBackbuffer() {
}
void MailboxOutputSurface::Reshape(gfx::Size size, float scale_factor) {
- if (size == size_)
+ if (size == surface_size_)
return;
- size_ = size;
+ surface_size_ = size;
+ device_scale_factor_ = scale_factor;
DiscardBackbuffer();
EnsureBackbuffer();
}
@@ -125,8 +127,8 @@ void MailboxOutputSurface::SendFrameToParentCompositor(
cc::CompositorFrame* frame) {
frame->gl_frame_data.reset(new GLFrameData());
- DCHECK(!size_.IsEmpty());
- DCHECK(size_ == current_backing_.size);
+ DCHECK(!surface_size_.IsEmpty());
+ DCHECK(surface_size_ == current_backing_.size);
DCHECK(!current_backing_.mailbox.IsZero());
frame->gl_frame_data->mailbox = current_backing_.mailbox;
diff --git a/content/renderer/gpu/mailbox_output_surface.h b/content/renderer/gpu/mailbox_output_surface.h
index 34c25fe..9133c9a 100644
--- a/content/renderer/gpu/mailbox_output_surface.h
+++ b/content/renderer/gpu/mailbox_output_surface.h
@@ -61,7 +61,6 @@ class MailboxOutputSurface : public CompositorOutputSurface {
std::deque<TransferableFrame> pending_textures_;
std::queue<TransferableFrame> returned_textures_;
- gfx::Size size_;
uint32 fbo_;
bool is_backbuffer_discarded_;
};
diff --git a/webkit/renderer/compositor_bindings/web_layer_impl_fixed_bounds_unittest.cc b/webkit/renderer/compositor_bindings/web_layer_impl_fixed_bounds_unittest.cc
index f02afd2..7099d7f 100644
--- a/webkit/renderer/compositor_bindings/web_layer_impl_fixed_bounds_unittest.cc
+++ b/webkit/renderer/compositor_bindings/web_layer_impl_fixed_bounds_unittest.cc
@@ -131,6 +131,7 @@ void CompareFixedBoundsLayerAndNormalLayer(
cc::LayerTreeHostCommon::CalculateDrawProperties(
root_layer->layer(),
kDeviceViewportSize,
+ gfx::Transform(),
kDeviceScaleFactor,
kPageScaleFactor,
root_layer->layer(),
@@ -149,6 +150,7 @@ void CompareFixedBoundsLayerAndNormalLayer(
cc::LayerTreeHostCommon::CalculateDrawProperties(
root_layer->layer(),
kDeviceViewportSize,
+ gfx::Transform(),
kDeviceScaleFactor,
kPageScaleFactor,
root_layer->layer(),