diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-10 20:57:33 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-10 20:57:33 +0000 |
commit | a168bf1a8d5075a99c6ee9b1bbe7ed03c0386fc7 (patch) | |
tree | ce391199361212d1eb4d8fc41161349e21c6093d | |
parent | 2b38b733e5db9551766847da783f1b93e0fafd1e (diff) | |
download | chromium_src-a168bf1a8d5075a99c6ee9b1bbe7ed03c0386fc7.zip chromium_src-a168bf1a8d5075a99c6ee9b1bbe7ed03c0386fc7.tar.gz chromium_src-a168bf1a8d5075a99c6ee9b1bbe7ed03c0386fc7.tar.bz2 |
Invert DSF to map from delegated frame to layer space
The size of the frame data from a delegated source will not in general match up
exactly with the delegated layer's bounds. Frame sizes and layer bounds are both
expressed as integers, but frame sizes are in physical pixels and layer bounds
are in device-independent pixels. If the device scale is not an integer, there
may not be an exact mapping between the two spaces. For instance, if the layer
size is 105 x 211 and the device scale is 1.5, the delegated content is
responsible for filling 157.5 x 316.5 physical pixels in the final output. This
isn't really possible so what actually happens is the delegated renderer
produces a frame with a physical size of 158 x 317 pixels and sends that up to
the DRLI. To map this frame into physical space, the DRLI should apply the
inverse of the device scale factor to reflect that the frame covers 105.333 x
211.3333 logical pixels.
Before this patch, DRLI would attempt to scale the frame by (105/158, 211/317)
resulting in the frame being scaled down non-uniformly to try to make 158 x 317
pixels fit into a 157.5 x 316.6 space. This scaling looks bad and ends up
mapping pixels partially outside of the layer's logical bounds into the layer's
logical bounds.
BUG=370074
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=275544
Review URL: https://codereview.chromium.org/311253004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276139 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/layers/delegated_renderer_layer.cc | 9 | ||||
-rw-r--r-- | cc/layers/delegated_renderer_layer.h | 8 | ||||
-rw-r--r-- | cc/layers/delegated_renderer_layer_impl.cc | 43 | ||||
-rw-r--r-- | cc/layers/delegated_renderer_layer_impl.h | 7 | ||||
-rw-r--r-- | cc/layers/delegated_renderer_layer_impl_unittest.cc | 123 | ||||
-rw-r--r-- | cc/output/delegated_frame_data.cc | 3 | ||||
-rw-r--r-- | cc/output/delegated_frame_data.h | 3 | ||||
-rw-r--r-- | cc/output/delegating_renderer.cc | 1 | ||||
-rw-r--r-- | cc/surfaces/display.cc | 1 | ||||
-rw-r--r-- | cc/test/fake_delegated_renderer_layer_impl.cc | 8 | ||||
-rw-r--r-- | cc/test/fake_delegated_renderer_layer_impl.h | 3 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_delegated.cc | 51 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_android.cc | 18 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_android.h | 3 | ||||
-rw-r--r-- | content/common/cc_messages.cc | 8 | ||||
-rw-r--r-- | ui/compositor/layer.cc | 1 |
16 files changed, 141 insertions, 149 deletions
diff --git a/cc/layers/delegated_renderer_layer.cc b/cc/layers/delegated_renderer_layer.cc index 194455a..c472061 100644 --- a/cc/layers/delegated_renderer_layer.cc +++ b/cc/layers/delegated_renderer_layer.cc @@ -67,8 +67,6 @@ void DelegatedRendererLayer::PushPropertiesTo(LayerImpl* impl) { DelegatedRendererLayerImpl* delegated_impl = static_cast<DelegatedRendererLayerImpl*>(impl); - delegated_impl->SetDisplaySize(display_size_); - delegated_impl->CreateChildIdIfNeeded( frame_provider_->GetReturnResourcesCallbackForImplThread()); @@ -86,13 +84,6 @@ void DelegatedRendererLayer::ProviderHasNewFrame() { SetNextCommitWaitsForActivation(); } -void DelegatedRendererLayer::SetDisplaySize(const gfx::Size& size) { - if (display_size_ == size) - return; - display_size_ = size; - SetNeedsCommit(); -} - bool DelegatedRendererLayer::Update(ResourceUpdateQueue* queue, const OcclusionTracker<Layer>* occlusion) { bool updated = Layer::Update(queue, occlusion); diff --git a/cc/layers/delegated_renderer_layer.h b/cc/layers/delegated_renderer_layer.h index a229543..3bc0aa8 100644 --- a/cc/layers/delegated_renderer_layer.h +++ b/cc/layers/delegated_renderer_layer.h @@ -29,12 +29,6 @@ class CC_EXPORT DelegatedRendererLayer : public Layer { const OcclusionTracker<Layer>* occlusion) OVERRIDE; virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE; - // Set the size at which the frame should be displayed, with the origin at the - // layer's origin. This must always contain at least the layer's bounds. A - // value of (0, 0) implies that the frame should be displayed to fit exactly - // in the layer's bounds. - void SetDisplaySize(const gfx::Size& size); - // Called by the DelegatedFrameProvider when a new frame is available to be // picked up. void ProviderHasNewFrame(); @@ -52,8 +46,6 @@ class CC_EXPORT DelegatedRendererLayer : public Layer { DelegatedFrameData* frame_data_; gfx::RectF frame_damage_; - gfx::Size display_size_; - scoped_refptr<BlockingTaskRunner> main_thread_runner_; base::WeakPtrFactory<DelegatedRendererLayer> weak_ptrs_; diff --git a/cc/layers/delegated_renderer_layer_impl.cc b/cc/layers/delegated_renderer_layer_impl.cc index f59e1f2..c1cdbbe 100644 --- a/cc/layers/delegated_renderer_layer_impl.cc +++ b/cc/layers/delegated_renderer_layer_impl.cc @@ -20,10 +20,11 @@ namespace cc { -DelegatedRendererLayerImpl::DelegatedRendererLayerImpl( - LayerTreeImpl* tree_impl, int id) +DelegatedRendererLayerImpl::DelegatedRendererLayerImpl(LayerTreeImpl* tree_impl, + int id) : LayerImpl(tree_impl, id), have_render_passes_to_push_(false), + inverse_device_scale_factor_(1.0f), child_id_(0), own_child_id_(false) { } @@ -75,7 +76,6 @@ void DelegatedRendererLayerImpl::PushPropertiesTo(LayerImpl* layer) { delegated_layer->own_child_id_ = true; own_child_id_ = false; - delegated_layer->SetDisplaySize(display_size_); if (have_render_passes_to_push_) { // This passes ownership of the render passes to the active tree. delegated_layer->SetRenderPasses(&render_passes_in_draw_order_); @@ -141,13 +141,14 @@ void DelegatedRendererLayerImpl::SetFrameData( resources_.swap(resources_in_frame); resource_provider->DeclareUsedResourcesFromChild(child_id_, resources_); + inverse_device_scale_factor_ = 1.0f / frame_data->device_scale_factor; // Display size is already set so we can compute what the damage rect // will be in layer space. The damage may exceed the visible portion of // the frame, so intersect the damage to the layer's bounds. RenderPass* new_root_pass = render_pass_list.back(); gfx::Size frame_size = new_root_pass->output_rect.size(); - gfx::RectF damage_in_layer = MathUtil::MapClippedRect( - DelegatedFrameToLayerSpaceTransform(frame_size), damage_in_frame); + gfx::RectF damage_in_layer = damage_in_frame; + damage_in_layer.Scale(inverse_device_scale_factor_); SetUpdateRect(gfx::IntersectRects( gfx::UnionRects(update_rect(), damage_in_layer), gfx::Rect(bounds()))); @@ -155,13 +156,6 @@ void DelegatedRendererLayerImpl::SetFrameData( have_render_passes_to_push_ = true; } -void DelegatedRendererLayerImpl::SetDisplaySize(const gfx::Size& size) { - if (display_size_ == size) - return; - display_size_ = size; - NoteLayerPropertyChanged(); -} - void DelegatedRendererLayerImpl::SetRenderPasses( ScopedPtrVector<RenderPass>* render_passes_in_draw_order) { ClearRenderPasses(); @@ -196,17 +190,6 @@ void DelegatedRendererLayerImpl::ReleaseResources() { ClearChildId(); } -gfx::Transform DelegatedRendererLayerImpl::DelegatedFrameToLayerSpaceTransform( - const gfx::Size& frame_size) const { - gfx::Size display_size = display_size_.IsEmpty() ? bounds() : display_size_; - - gfx::Transform delegated_frame_to_layer_space_transform; - delegated_frame_to_layer_space_transform.Scale( - static_cast<double>(display_size.width()) / frame_size.width(), - static_cast<double>(display_size.height()) / frame_size.height()); - return delegated_frame_to_layer_space_transform; -} - static inline int IndexToId(int index) { return index + 1; } static inline int IdToIndex(int id) { return id - 1; } @@ -242,9 +225,9 @@ void DelegatedRendererLayerImpl::AppendContributingRenderPasses( const RenderPass* root_delegated_render_pass = render_passes_in_draw_order_.back(); gfx::Size frame_size = root_delegated_render_pass->output_rect.size(); - gfx::Transform delegated_frame_to_root_transform = - screen_space_transform() * - DelegatedFrameToLayerSpaceTransform(frame_size); + gfx::Transform delegated_frame_to_root_transform = screen_space_transform(); + delegated_frame_to_root_transform.Scale(inverse_device_scale_factor_, + inverse_device_scale_factor_); for (size_t i = 0; i < render_passes_in_draw_order_.size() - 1; ++i) { RenderPass::Id output_render_pass_id(-1, -1); @@ -413,11 +396,9 @@ void DelegatedRendererLayerImpl::AppendRenderPassQuads( bool is_root_delegated_render_pass = delegated_render_pass == render_passes_in_draw_order_.back(); if (is_root_delegated_render_pass) { - // Don't allow areas inside the bounds that are empty. - DCHECK(display_size_.IsEmpty() || - gfx::Rect(display_size_).Contains(gfx::Rect(bounds()))); - gfx::Transform delegated_frame_to_target_transform = - draw_transform() * DelegatedFrameToLayerSpaceTransform(frame_size); + gfx::Transform delegated_frame_to_target_transform = draw_transform(); + delegated_frame_to_target_transform.Scale(inverse_device_scale_factor_, + inverse_device_scale_factor_); output_shared_quad_state->content_to_target_transform.ConcatTransform( delegated_frame_to_target_transform); diff --git a/cc/layers/delegated_renderer_layer_impl.h b/cc/layers/delegated_renderer_layer_impl.h index e71fce8..9f7aaf8 100644 --- a/cc/layers/delegated_renderer_layer_impl.h +++ b/cc/layers/delegated_renderer_layer_impl.h @@ -48,8 +48,6 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl { void SetFrameData(const DelegatedFrameData* frame_data, const gfx::RectF& damage_in_frame); - void SetDisplaySize(const gfx::Size& size); - protected: DelegatedRendererLayerImpl(LayerTreeImpl* tree_impl, int id); @@ -77,9 +75,6 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl { RenderPass::Id delegated_render_pass_id, RenderPass::Id* output_render_pass_id) const; - gfx::Transform DelegatedFrameToLayerSpaceTransform( - const gfx::Size& frame_size) const; - void AppendRenderPassQuads( QuadSink* quad_sink, AppendQuadsData* append_quads_data, @@ -90,11 +85,11 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl { virtual const char* LayerTypeAsString() const OVERRIDE; bool have_render_passes_to_push_; + float inverse_device_scale_factor_; ScopedPtrVector<RenderPass> render_passes_in_draw_order_; base::hash_map<RenderPass::Id, int> render_passes_index_by_id_; ResourceProvider::ResourceIdArray resources_; - gfx::Size display_size_; int child_id_; bool own_child_id_; diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc index 3f30d15..fbaf8bbf 100644 --- a/cc/layers/delegated_renderer_layer_impl_unittest.cc +++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc @@ -109,7 +109,7 @@ class DelegatedRendererLayerImplTestSimple gfx::Transform(1, 0, 0, 1, 9, 10)); AddRenderPassQuad(pass3, pass2); delegated_renderer_layer->SetFrameDataForRenderPasses( - &delegated_render_passes); + 1.f, &delegated_render_passes); // The RenderPasses should be taken by the layer. EXPECT_EQ(0u, delegated_render_passes.size()); @@ -245,11 +245,8 @@ TEST_F(DelegatedRendererLayerImplTestSimple, // The DelegatedRendererLayer is at position 3,3 compared to its target, and // has a translation transform of 1,1. So its root RenderPass' quads should // all be transformed by that combined amount. - // The DelegatedRendererLayer has a size of 10x10, but the root delegated - // RenderPass has a size of 8x8, so any quads should be scaled by 10/8. gfx::Transform transform; transform.Translate(4.0, 4.0); - transform.Scale(10.0 / 8.0, 10.0 / 8.0); EXPECT_TRANSFORMATION_MATRIX_EQ( transform, frame.render_passes[3]->quad_list[0]->quadTransform()); @@ -280,12 +277,8 @@ TEST_F(DelegatedRendererLayerImplTestSimple, RenderPassTransformIsModified) { // The DelegatedRendererLayer is at position 9,9 compared to the root, so all // render pass' transforms to the root should be shifted by this amount. - // The DelegatedRendererLayer has a size of 10x10, but the root delegated - // RenderPass has a size of 8x8, so any render passes should be scaled by - // 10/8. gfx::Transform transform; transform.Translate(9.0, 9.0); - transform.Scale(10.0 / 8.0, 10.0 / 8.0); // The first contributing surface has a translation of 5, 6. gfx::Transform five_six(1, 0, 0, 1, 5, 6); @@ -468,12 +461,9 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface, ASSERT_EQ(6u, frame.render_passes.size()); // Because the DelegatedRendererLayer owns a RenderSurfaceImpl, its root - // RenderPass' quads do not need to be translated at all. However, they are - // scaled from the frame's size (8x8) to the layer's bounds (10x10). - gfx::Transform transform; - transform.Scale(10.0 / 8.0, 10.0 / 8.0); + // RenderPass' quads do not need to be translated at all. EXPECT_TRANSFORMATION_MATRIX_EQ( - transform, frame.render_passes[3]->quad_list[0]->quadTransform()); + gfx::Transform(), frame.render_passes[3]->quad_list[0]->quadTransform()); // Quads from non-root RenderPasses should not be shifted either. ASSERT_EQ(2u, frame.render_passes[2]->quad_list.size()); @@ -492,6 +482,10 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface, class DelegatedRendererLayerImplTestTransform : public DelegatedRendererLayerImplTest { public: + DelegatedRendererLayerImplTestTransform() + : root_delegated_render_pass_is_clipped_(false), + delegated_device_scale_factor_(2.f) {} + void SetUpTest() { host_impl_->SetDeviceScaleFactor(2.f); @@ -511,8 +505,6 @@ class DelegatedRendererLayerImplTestTransform transform.Scale(2.0, 2.0); transform.Translate(8.0, 8.0); delegated_renderer_layer->SetTransform(transform); - delegated_renderer_layer->SetTransformOrigin( - gfx::Point3F(75 * 0.5f, 75 * 0.5f, 0.0f)); ScopedPtrVector<RenderPass> delegated_render_passes; @@ -629,7 +621,7 @@ class DelegatedRendererLayerImplTestTransform pass->AppendDrawQuad(color_quad.PassAs<DrawQuad>()); delegated_renderer_layer->SetFrameDataForRenderPasses( - &delegated_render_passes); + delegated_device_scale_factor_, &delegated_render_passes); // The RenderPasses should be taken by the layer. EXPECT_EQ(0u, delegated_render_passes.size()); @@ -687,6 +679,7 @@ class DelegatedRendererLayerImplTestTransform LayerImpl* root_layer_; DelegatedRendererLayerImpl* delegated_renderer_layer_; bool root_delegated_render_pass_is_clipped_; + float delegated_device_scale_factor_; }; TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) { @@ -715,16 +708,15 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) { EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped); gfx::Transform expected; - // Device scale factor is 2. + // Device scale factor. expected.Scale(2.0, 2.0); // This is the transform from the layer's space to its target. - // The position (20) - the width / scale (75 / 2) = 20 - 37.5 = -17.5 - expected.Translate(-17.5, -17.5); + expected.Translate(20, 20); expected.Scale(2.0, 2.0); expected.Translate(8.0, 8.0); - // The frame has size 100x100 but the layer's bounds are 75x75. - expected.Scale(75.0 / 100.0, 75.0 / 100.0); // This is the transform within the source frame. + // Inverse device scale factor to go from physical space to layer space. + expected.Scale(0.5, 0.5); expected.Scale(1.5, 1.5); expected.Translate(7.0, 7.0); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -763,31 +755,27 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_NoSurface) { // Since the quads have a clip_rect it should be modified by delegated // renderer layer's draw_transform. // The position of the resulting clip_rect is: - // (clip rect position (10) * scale to layer (75/100) + translate (8)) * - // layer scale (2) + layer position (20) = 51 - // But the layer is centered, so: 51 - (75 / 2) = 51 - 75 / 2 = 13.5 - // The device scale is 2, so everything gets doubled, giving 27. + // (clip rect position (10) * inverse dsf (1/2) + translate (8)) * + // layer scale (2) + layer position (20) = 46 + // The device scale is 2, so everything gets doubled, giving 92. // - // The size is 35x35 scaled to fit inside the layer's bounds at 75x75 from - // a frame at 100x100: 35 * 2 (device scale) * 75 / 100 = 52.5. The device - // scale doubles this to 105. - EXPECT_EQ(gfx::Rect(27, 27, 105, 105).ToString(), + // The size is 35x35 scaled by the device scale. + EXPECT_EQ(gfx::Rect(92, 92, 70, 70).ToString(), root_delegated_shared_quad_state->clip_rect.ToString()); // The quads had a clip and it should be preserved. EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped); gfx::Transform expected; - // Device scale factor is 2. + // Device scale factor. expected.Scale(2.0, 2.0); // This is the transform from the layer's space to its target. - // The position (20) - the width / scale (75 / 2) = 20 - 37.5 = -17.5 - expected.Translate(-17.5, -17.5); + expected.Translate(20, 20); expected.Scale(2.0, 2.0); expected.Translate(8.0, 8.0); - // The frame has size 100x100 but the layer's bounds are 75x75. - expected.Scale(75.0 / 100.0, 75.0 / 100.0); // This is the transform within the source frame. + // Inverse device scale factor to go from physical space to layer space. + expected.Scale(0.5, 0.5); expected.Scale(1.5, 1.5); expected.Translate(7.0, 7.0); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -827,11 +815,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) { // When the layer owns a surface, then its position and translation are not // a part of its draw transform. - // The position of the resulting clip_rect is: - // (clip rect position (10) * scale to layer (75/100)) * device scale (2) = 15 - // The size is 35x35 scaled to fit inside the layer's bounds at 75x75 from - // a frame at 100x100: 35 * 2 (device scale) * 75 / 100 = 52.5. - EXPECT_EQ(gfx::Rect(15, 15, 53, 53).ToString(), + EXPECT_EQ(gfx::Rect(10, 10, 35, 35).ToString(), root_delegated_shared_quad_state->clip_rect.ToString()); // Since the layer owns a surface it doesn't need to clip its quads, so @@ -839,10 +823,6 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) { EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped); gfx::Transform expected; - // Device scale factor is 2. - expected.Scale(2.0, 2.0); - // The frame has size 100x100 but the layer's bounds are 75x75. - expected.Scale(75.0 / 100.0, 75.0 / 100.0); // This is the transform within the source frame. expected.Scale(1.5, 1.5); expected.Translate(7.0, 7.0); @@ -882,22 +862,14 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) { &contrib_delegated_shared_quad_state); // When the layer owns a surface, then its position and translation are not - // a part of its draw transform. - // The position of the resulting clip_rect is: - // (clip rect position (10) * scale to layer (75/100)) * device scale (2) = 15 - // The size is 35x35 scaled to fit inside the layer's bounds at 75x75 from - // a frame at 100x100: 35 * 2 (device scale) * 75 / 100 = 52.5. - EXPECT_EQ(gfx::Rect(15, 15, 53, 53).ToString(), + // a part of its draw transform. The clip_rect should be preserved. + EXPECT_EQ(gfx::Rect(10, 10, 35, 35).ToString(), root_delegated_shared_quad_state->clip_rect.ToString()); // The quads had a clip and it should be preserved. EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped); gfx::Transform expected; - // Device scale factor is 2. - expected.Scale(2.0, 2.0); - // The frame has size 100x100 but the layer's bounds are 75x75. - expected.Scale(75.0 / 100.0, 75.0 / 100.0); // This is the transform within the source frame. expected.Scale(1.5, 1.5); expected.Translate(7.0, 7.0); @@ -919,6 +891,45 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) { host_impl_->DidDrawAllLayers(frame); } +TEST_F(DelegatedRendererLayerImplTestTransform, MismatchedDeviceScaleFactor) { + root_delegated_render_pass_is_clipped_ = true; + delegated_device_scale_factor_ = 1.3f; + + SetUpTest(); + + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + + const SharedQuadState* root_delegated_shared_quad_state = NULL; + const SharedQuadState* contrib_delegated_shared_quad_state = NULL; + VerifyRenderPasses(frame, + 2, + &root_delegated_shared_quad_state, + &contrib_delegated_shared_quad_state); + + // The parent tree's device scale factor is 2.0, but the child has submitted a + // frame with a device scale factor of 1.3. Absent any better option, the + // only thing we can do is scale from 1.3 -> 2.0. + + gfx::Transform expected; + // Device scale factor (from parent). + expected.Scale(2.0, 2.0); + // This is the transform from the layer's space to its target. + expected.Translate(20, 20); + expected.Scale(2.0, 2.0); + expected.Translate(8.0, 8.0); + // This is the transform within the source frame. + // Inverse device scale factor (from child). + expected.Scale(1.0f / 1.3f, 1.0f / 1.3f); + expected.Scale(1.5, 1.5); + expected.Translate(7.0, 7.0); + EXPECT_TRANSFORMATION_MATRIX_EQ( + expected, root_delegated_shared_quad_state->content_to_target_transform); + + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); +} + class DelegatedRendererLayerImplTestClip : public DelegatedRendererLayerImplTest { public: @@ -1051,7 +1062,7 @@ class DelegatedRendererLayerImplTestClip pass->AppendDrawQuad(color_quad.PassAs<DrawQuad>()); delegated_renderer_layer->SetFrameDataForRenderPasses( - &delegated_render_passes); + 1.f, &delegated_render_passes); // The RenderPasses should be taken by the layer. EXPECT_EQ(0u, delegated_render_passes.size()); @@ -1355,7 +1366,7 @@ TEST_F(DelegatedRendererLayerImplTest, InvalidRenderPassDrawQuad) { AddRenderPassQuad(pass1, missing_pass.get()); delegated_renderer_layer->SetFrameDataForRenderPasses( - &delegated_render_passes); + 1.f, &delegated_render_passes); // The RenderPasses should be taken by the layer. EXPECT_EQ(0u, delegated_render_passes.size()); @@ -1408,7 +1419,7 @@ TEST_F(DelegatedRendererLayerImplTest, Occlusion) { gfx::Transform()); AddRenderPassQuad(pass1, pass2, 0, FilterOperations(), transform); delegated_renderer_layer_impl->SetFrameDataForRenderPasses( - &delegated_render_passes); + 1.f, &delegated_render_passes); impl.CalcDrawProps(viewport_size); diff --git a/cc/output/delegated_frame_data.cc b/cc/output/delegated_frame_data.cc index 516a3ec..94ff51d 100644 --- a/cc/output/delegated_frame_data.cc +++ b/cc/output/delegated_frame_data.cc @@ -6,7 +6,8 @@ namespace cc { -DelegatedFrameData::DelegatedFrameData() {} +DelegatedFrameData::DelegatedFrameData() : device_scale_factor(1.0f) { +} DelegatedFrameData::~DelegatedFrameData() {} diff --git a/cc/output/delegated_frame_data.h b/cc/output/delegated_frame_data.h index f7b89bc..644f180 100644 --- a/cc/output/delegated_frame_data.h +++ b/cc/output/delegated_frame_data.h @@ -18,6 +18,9 @@ class CC_EXPORT DelegatedFrameData { DelegatedFrameData(); ~DelegatedFrameData(); + // The device scale factor used when generating this frame. + float device_scale_factor; + TransferableResourceArray resource_list; ScopedPtrVector<RenderPass> render_pass_list; diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc index e3b7c68..68c29e5 100644 --- a/cc/output/delegating_renderer.cc +++ b/cc/output/delegating_renderer.cc @@ -93,6 +93,7 @@ void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData); DelegatedFrameData& out_data = *delegated_frame_data_; + out_data.device_scale_factor = device_scale_factor; // Move the render passes and resources into the |out_frame|. out_data.render_pass_list.swap(*render_passes_in_draw_order); diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index ba4ed03..1099c3e 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc @@ -66,7 +66,6 @@ bool Display::Draw() { DelegatedRendererLayer::Create(delegated_frame_provider_); layer_tree_host_->SetRootLayer(delegated_layer_); - delegated_layer_->SetDisplaySize(current_surface_->size()); delegated_layer_->SetBounds(current_surface_->size()); delegated_layer_->SetContentsOpaque(true); delegated_layer_->SetIsDrawable(true); diff --git a/cc/test/fake_delegated_renderer_layer_impl.cc b/cc/test/fake_delegated_renderer_layer_impl.cc index 8f4c104..d59eac5 100644 --- a/cc/test/fake_delegated_renderer_layer_impl.cc +++ b/cc/test/fake_delegated_renderer_layer_impl.cc @@ -13,8 +13,10 @@ namespace cc { FakeDelegatedRendererLayerImpl::FakeDelegatedRendererLayerImpl( - LayerTreeImpl* tree_impl, int id) - : DelegatedRendererLayerImpl(tree_impl, id) {} + LayerTreeImpl* tree_impl, + int id) + : DelegatedRendererLayerImpl(tree_impl, id) { +} FakeDelegatedRendererLayerImpl::~FakeDelegatedRendererLayerImpl() {} @@ -49,8 +51,10 @@ ResourceProvider::ResourceIdSet FakeDelegatedRendererLayerImpl::Resources() void NoopReturnCallback(const ReturnedResourceArray& returned) {} void FakeDelegatedRendererLayerImpl::SetFrameDataForRenderPasses( + float device_scale_factor, ScopedPtrVector<RenderPass>* pass_list) { scoped_ptr<DelegatedFrameData> delegated_frame(new DelegatedFrameData); + delegated_frame->device_scale_factor = device_scale_factor; delegated_frame->render_pass_list.swap(*pass_list); ResourceProvider* resource_provider = layer_tree_impl()->resource_provider(); diff --git a/cc/test/fake_delegated_renderer_layer_impl.h b/cc/test/fake_delegated_renderer_layer_impl.h index a958baf..0a071a5 100644 --- a/cc/test/fake_delegated_renderer_layer_impl.h +++ b/cc/test/fake_delegated_renderer_layer_impl.h @@ -26,7 +26,8 @@ class FakeDelegatedRendererLayerImpl : public DelegatedRendererLayerImpl { } ResourceProvider::ResourceIdSet Resources() const; - void SetFrameDataForRenderPasses(ScopedPtrVector<RenderPass>* pass_list); + void SetFrameDataForRenderPasses(float device_scale_factor, + ScopedPtrVector<RenderPass>* pass_list); protected: FakeDelegatedRendererLayerImpl(LayerTreeImpl* tree_impl, int id); diff --git a/cc/trees/layer_tree_host_unittest_delegated.cc b/cc/trees/layer_tree_host_unittest_delegated.cc index abd5e4b..37c928b 100644 --- a/cc/trees/layer_tree_host_unittest_delegated.cc +++ b/cc/trees/layer_tree_host_unittest_delegated.cc @@ -486,9 +486,8 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0))); break; case 3: - // Should create a total amount of gfx::Rect(2, 2, 10, 6) damage. - // The frame size is 20x20 while the layer is 10x10, so this should - // produce a gfx::Rect(1, 1, 5, 3) damage rect. + // Should create a total amount of gfx::Rect(2, 2, 8, 6) damage: + // (2, 2, 10, 6) clamped to the root output rect. SetFrameData( CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(2, 2, 5, 5))); SetFrameData( @@ -517,41 +516,35 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage layer_tree_host()->SetNeedsCommit(); break; case 9: - // Should damage the full layer. - delegated_->SetDisplaySize(gfx::Size(10, 10)); - break; - case 10: // Should create zero damage. layer_tree_host()->SetNeedsCommit(); break; - case 11: + case 10: // Changing the frame size damages the full layer. SetFrameData( CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1))); break; - case 12: + case 11: // An invalid frame isn't used, so it should not cause damage. SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1))); break; - case 13: - // Should create gfx::Rect(1, 1, 2, 2) of damage. The frame size is - // 5x5 and the display size is now set to 10x10, so this should result - // in a gfx::Rect(2, 2, 4, 4) damage rect. + case 12: + // Should create gfx::Rect(1, 1, 2, 2) of damage. SetFrameData( CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2))); break; - case 14: + case 13: // Should create zero damage. layer_tree_host()->SetNeedsCommit(); break; - case 15: + case 14: // Moving the layer out of the tree and back in will damage the whole // impl layer. delegated_->RemoveFromParent(); layer_tree_host()->root_layer()->AddChild(delegated_); break; - case 16: + case 15: // Make a larger frame with lots of damage. Then a frame smaller than // the first frame's damage. The entire layer should be damaged, but // nothing more. @@ -560,7 +553,7 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage SetFrameData( CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2))); break; - case 17: + case 16: // Make a frame with lots of damage. Then replace it with a frame with // no damage. The entire layer should be damaged, but nothing more. SetFrameData( @@ -568,7 +561,7 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage SetFrameData( CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 0, 0))); break; - case 18: + case 17: // Make another layer that uses the same frame provider. The new layer // should be damaged. delegated_copy_ = CreateDelegatedLayer(frame_provider_); @@ -578,11 +571,12 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage SetFrameData( CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1))); break; - case 19: + case 18: // Set another new frame, both layers should be damaged in the same // ways. SetFrameData( CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1))); + break; } first_draw_for_source_frame_ = true; } @@ -616,7 +610,7 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); break; case 3: - EXPECT_EQ(gfx::Rect(1, 1, 5, 3).ToString(), damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(2, 2, 8, 6).ToString(), damage_rect.ToString()); break; case 4: EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); @@ -634,22 +628,22 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); break; case 9: - EXPECT_EQ(gfx::Rect(6, 6).ToString(), damage_rect.ToString()); + EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); break; case 10: - EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); break; case 11: - EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); + EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); break; case 12: - EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(1, 1, 2, 2).ToString(), damage_rect.ToString()); break; case 13: - EXPECT_EQ(gfx::Rect(2, 2, 4, 4).ToString(), damage_rect.ToString()); + EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); break; case 14: - EXPECT_EQ(gfx::Rect().ToString(), damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); break; case 15: EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); @@ -658,14 +652,11 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); break; case 17: - EXPECT_EQ(gfx::Rect(10, 10).ToString(), damage_rect.ToString()); - break; - case 18: EXPECT_EQ(gfx::UnionRects(gfx::Rect(5, 0, 10, 10), gfx::Rect(4, 0, 1, 1)).ToString(), damage_rect.ToString()); break; - case 19: + case 18: EXPECT_EQ(gfx::Rect(3, 3, 6, 1).ToString(), damage_rect.ToString()); EndTest(); break; diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index e2ececa..1cc054c 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -688,11 +688,13 @@ void RenderWidgetHostViewAndroid::CopyFromCompositingSurface( DCHECK(frame_provider_); scoped_refptr<cc::DelegatedRendererLayer> delegated_layer = cc::DelegatedRendererLayer::Create(frame_provider_); - delegated_layer->SetDisplaySize(texture_size_in_layer_); delegated_layer->SetBounds(content_size_in_layer_); delegated_layer->SetHideLayerAndSubtree(true); delegated_layer->SetIsDrawable(true); delegated_layer->SetContentsOpaque(true); + gfx::Transform layer_scale( + device_scale_factor, 0.f, 0.f, device_scale_factor, 0.f, 0.f); + delegated_layer->SetTransform(layer_scale); compositor->AttachLayerForReadback(delegated_layer); readback_layer = delegated_layer; @@ -812,11 +814,23 @@ void RenderWidgetHostViewAndroid::SwapDelegatedFrame( } if (layer_.get()) { - layer_->SetDisplaySize(texture_size_in_layer_); layer_->SetIsDrawable(true); layer_->SetContentsOpaque(true); layer_->SetBounds(content_size_in_layer_); layer_->SetNeedsDisplay(); + // DelegatedRendererLayer scales the frame data from physical space to DIPs + // by inverting the frame's device scale factor, assuming that the browser + // compositor will map from DIPs back to physical pixels using its own + // device scale factor. However, the Android browser compositor always uses + // a device scale factor of 1.0, so we have to transform the delegated + // layer by the device scale to get it into the same physical pixel space as + // the rest of the UI. + const gfx::Display& display = + gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); + float device_scale_factor = display.device_scale_factor(); + gfx::Transform layer_scale( + device_scale_factor, 0.f, 0.f, device_scale_factor, 0.f, 0.f); + layer_->SetTransform(layer_scale); } base::Closure ack_callback = diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index d00c5b6..b0a9c48 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h @@ -311,6 +311,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid // The most recent content size that was pushed to the texture layer. gfx::Size content_size_in_layer_; + // The device scale of the last received frame. + float device_scale_factor_; + // The output surface id of the last received frame. uint32_t last_output_surface_id_; diff --git a/content/common/cc_messages.cc b/content/common/cc_messages.cc index 8d93e1f..8946d70 100644 --- a/content/common/cc_messages.cc +++ b/content/common/cc_messages.cc @@ -711,13 +711,15 @@ void ParamTraits<cc::DelegatedFrameData>::Write(Message* m, const param_type& p) { DCHECK_NE(0u, p.render_pass_list.size()); - size_t to_reserve = p.resource_list.size() * sizeof(cc::TransferableResource); + size_t to_reserve = sizeof(p.device_scale_factor); + to_reserve += p.resource_list.size() * sizeof(cc::TransferableResource); for (size_t i = 0; i < p.render_pass_list.size(); ++i) { const cc::RenderPass* pass = p.render_pass_list[i]; to_reserve += ReserveSizeForRenderPassWrite(*pass); } m->Reserve(to_reserve); + WriteParam(m, p.device_scale_factor); WriteParam(m, p.resource_list); WriteParam(m, p.render_pass_list.size()); for (size_t i = 0; i < p.render_pass_list.size(); ++i) @@ -727,6 +729,9 @@ void ParamTraits<cc::DelegatedFrameData>::Write(Message* m, bool ParamTraits<cc::DelegatedFrameData>::Read(const Message* m, PickleIterator* iter, param_type* p) { + if (!ReadParam(m, iter, &p->device_scale_factor)) + return false; + const static size_t kMaxRenderPasses = 10000; size_t num_render_passes; @@ -746,6 +751,7 @@ bool ParamTraits<cc::DelegatedFrameData>::Read(const Message* m, void ParamTraits<cc::DelegatedFrameData>::Log(const param_type& p, std::string* l) { l->append("DelegatedFrameData("); + LogParam(p.device_scale_factor, l); LogParam(p.resource_list, l); l->append(", ["); for (size_t i = 0; i < p.render_pass_list.size(); ++i) { diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 150e1ef..c176742 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc @@ -958,7 +958,6 @@ void Layer::RecomputeDrawsContentAndUVRect() { texture_layer_->SetUV(uv_top_left, uv_bottom_right); } else if (delegated_renderer_layer_.get()) { size.SetToMin(frame_size_in_dip_); - delegated_renderer_layer_->SetDisplaySize(frame_size_in_dip_); } cc_layer_->SetBounds(size); } |