diff options
author | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-23 18:50:16 +0000 |
---|---|---|
committer | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-23 18:50:16 +0000 |
commit | 15c54d5a7e94061ec7f21360284afcca9073a62f (patch) | |
tree | 81b6e55f11f9670259ac593ad7322a7abbbebf94 | |
parent | b450b4f786fb6b984960f729a0e0875cba36bf9c (diff) | |
download | chromium_src-15c54d5a7e94061ec7f21360284afcca9073a62f.zip chromium_src-15c54d5a7e94061ec7f21360284afcca9073a62f.tar.gz chromium_src-15c54d5a7e94061ec7f21360284afcca9073a62f.tar.bz2 |
Invalidate content-layer if LCD text setting changes.
BUG=100666
Review URL: https://chromiumcodereview.appspot.com/12543018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190061 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/layers/content_layer.cc | 14 | ||||
-rw-r--r-- | cc/layers/content_layer.h | 3 | ||||
-rw-r--r-- | cc/layers/content_layer_client.h | 4 | ||||
-rw-r--r-- | cc/layers/content_layer_unittest.cc | 1 | ||||
-rw-r--r-- | cc/layers/picture_image_layer.h | 1 | ||||
-rw-r--r-- | cc/test/fake_content_layer_client.h | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common_unittest.cc | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 101 | ||||
-rw-r--r-- | ui/compositor/layer.h | 1 | ||||
-rw-r--r-- | webkit/compositor_bindings/web_content_layer_impl.cc | 22 | ||||
-rw-r--r-- | webkit/compositor_bindings/web_content_layer_impl.h | 3 |
11 files changed, 148 insertions, 4 deletions
diff --git a/cc/layers/content_layer.cc b/cc/layers/content_layer.cc index 540f01f..c29d72e 100644 --- a/cc/layers/content_layer.cc +++ b/cc/layers/content_layer.cc @@ -49,7 +49,9 @@ scoped_refptr<ContentLayer> ContentLayer::Create(ContentLayerClient* client) { ContentLayer::ContentLayer(ContentLayerClient* client) : TiledLayer(), - client_(client) {} + client_(client), + can_use_lcd_text_last_frame_(can_use_lcd_text()) { +} ContentLayer::~ContentLayer() {} @@ -73,6 +75,7 @@ void ContentLayer::Update(ResourceUpdateQueue* queue, true); CreateUpdaterIfNeeded(); + UpdateCanUseLCDText(); } TiledLayer::Update(queue, occlusion, stats); @@ -111,4 +114,13 @@ void ContentLayer::SetContentsOpaque(bool opaque) { updater_->SetOpaque(opaque); } +void ContentLayer::UpdateCanUseLCDText() { + if (can_use_lcd_text_last_frame_ == can_use_lcd_text()) + return; + + can_use_lcd_text_last_frame_ = can_use_lcd_text(); + if (client_) + client_->DidChangeLayerCanUseLCDText(); +} + } // namespace cc diff --git a/cc/layers/content_layer.h b/cc/layers/content_layer.h index 94db0bf..d59b56c 100644 --- a/cc/layers/content_layer.h +++ b/cc/layers/content_layer.h @@ -59,8 +59,11 @@ class CC_EXPORT ContentLayer : public TiledLayer { virtual LayerUpdater* Updater() const OVERRIDE; virtual void CreateUpdaterIfNeeded() OVERRIDE; + void UpdateCanUseLCDText(); + ContentLayerClient* client_; scoped_refptr<LayerUpdater> updater_; + bool can_use_lcd_text_last_frame_; DISALLOW_COPY_AND_ASSIGN(ContentLayer); }; diff --git a/cc/layers/content_layer_client.h b/cc/layers/content_layer_client.h index 7d51fd9..1fdf024 100644 --- a/cc/layers/content_layer_client.h +++ b/cc/layers/content_layer_client.h @@ -22,6 +22,10 @@ class CC_EXPORT ContentLayerClient { gfx::Rect clip, gfx::RectF* opaque) = 0; + // Called by the content layer during the update phase. + // If the client paints LCD text, it may want to invalidate the layer. + virtual void DidChangeLayerCanUseLCDText() = 0; + protected: virtual ~ContentLayerClient() {} }; diff --git a/cc/layers/content_layer_unittest.cc b/cc/layers/content_layer_unittest.cc index 259e44f..ab09d81 100644 --- a/cc/layers/content_layer_unittest.cc +++ b/cc/layers/content_layer_unittest.cc @@ -26,6 +26,7 @@ class MockContentLayerClient : public ContentLayerClient { gfx::RectF* opaque) OVERRIDE { *opaque = gfx::RectF(opaque_layer_rect_); } + virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} private: gfx::Rect opaque_layer_rect_; diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h index fb4b5be..4f5e5c5 100644 --- a/cc/layers/picture_image_layer.h +++ b/cc/layers/picture_image_layer.h @@ -29,6 +29,7 @@ class CC_EXPORT PictureImageLayer : public PictureLayer, ContentLayerClient { SkCanvas* canvas, gfx::Rect clip, gfx::RectF* opaque) OVERRIDE; + virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} private: PictureImageLayer(); diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h index 4cfffa2..462fa47 100644 --- a/cc/test/fake_content_layer_client.h +++ b/cc/test/fake_content_layer_client.h @@ -21,6 +21,7 @@ class FakeContentLayerClient : public cc::ContentLayerClient { virtual void PaintContents(SkCanvas* canvas, gfx::Rect rect, gfx::RectF* opaque_rect) OVERRIDE; + virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} void set_paint_all_opaque(bool opaque) { paint_all_opaque_ = opaque; } diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 4fcceb4..502937b 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc @@ -149,6 +149,7 @@ public: MockContentLayerClient() { } virtual ~MockContentLayerClient() { } virtual void PaintContents(SkCanvas* canvas, gfx::Rect clip, gfx::RectF* opaque) OVERRIDE { } + virtual void DidChangeLayerCanUseLCDText() OVERRIDE { } }; scoped_refptr<ContentLayer> createDrawableContentLayer(ContentLayerClient* delegate) diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 67a45750..9004168 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -682,6 +682,7 @@ public: if (m_testLayer) m_testLayer->SetOpacity(0); } + virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} private: Layer* m_testLayer; @@ -1884,6 +1885,7 @@ public: *opaque = gfx::RectF(rect.width(), rect.height()); canvas->drawRect(rect, paint); } + virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} }; virtual void BeginTest() OVERRIDE @@ -2248,5 +2250,104 @@ private: SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPinchZoomScrollbarNewRootLayer) +class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { +public: + class NotificationClient : public ContentLayerClient { + public: + NotificationClient() + : layer_(0) + , paint_count_(0) + , lcd_notification_count_(0) + { + } + + void set_layer(Layer* layer) { layer_ = layer; } + int paint_count() const { return paint_count_; } + int lcd_notification_count() const { return lcd_notification_count_; } + + virtual void PaintContents(SkCanvas* canvas, + gfx::Rect clip, + gfx::RectF* opaque) OVERRIDE + { + ++paint_count_; + } + virtual void DidChangeLayerCanUseLCDText() OVERRIDE + { + ++lcd_notification_count_; + layer_->SetNeedsDisplay(); + } + + private: + Layer* layer_; + int paint_count_; + int lcd_notification_count_; + }; + + virtual void SetupTree() OVERRIDE + { + scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_); + root_layer->SetIsDrawable(true); + root_layer->SetBounds(gfx::Size(1, 1)); + + layer_tree_host()->SetRootLayer(root_layer); + client_.set_layer(root_layer.get()); + + // The expecations are based on the assumption that the default + // LCD settings are: + EXPECT_EQ(true, layer_tree_host()->settings().can_use_lcd_text); + EXPECT_EQ(false, root_layer->can_use_lcd_text()); + + LayerTreeHostTest::SetupTree(); + } + + virtual void BeginTest() OVERRIDE + { + PostSetNeedsCommitToMainThread(); + } + virtual void AfterTest() OVERRIDE { } + + virtual void DidCommit() OVERRIDE + { + switch (layer_tree_host()->commit_number()) { + case 1: + // The first update consists one LCD notification and one paint. + EXPECT_EQ(1, client_.lcd_notification_count()); + EXPECT_EQ(1, client_.paint_count()); + // LCD text must have been enabled on the layer. + EXPECT_EQ(true, layer_tree_host()->root_layer()->can_use_lcd_text()); + PostSetNeedsCommitToMainThread(); + break; + case 2: + // Since nothing changed on layer, there should be no notification + // or paint on the second update. + EXPECT_EQ(1, client_.lcd_notification_count()); + EXPECT_EQ(1, client_.paint_count()); + // LCD text must not have changed. + EXPECT_EQ(true, layer_tree_host()->root_layer()->can_use_lcd_text()); + // Change layer opacity that should trigger lcd notification. + layer_tree_host()->root_layer()->SetOpacity(0.5); + // No need to request a commit - setting opacity will do it. + break; + default: + // Verify that there is not extra commit due to layer invalidation. + EXPECT_EQ(3, layer_tree_host()->commit_number()); + // LCD notification count should have incremented due to + // change in layer opacity. + EXPECT_EQ(2, client_.lcd_notification_count()); + // Paint count should be incremented due to invalidation. + EXPECT_EQ(2, client_.paint_count()); + // LCD text must have been disabled on the layer due to opacity. + EXPECT_EQ(false, layer_tree_host()->root_layer()->can_use_lcd_text()); + EndTest(); + break; + } + } + +private: + NotificationClient client_; +}; + +SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification) + } // namespace } // namespace cc diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index d722875..5c95a36 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h @@ -294,6 +294,7 @@ class COMPOSITOR_EXPORT Layer // ContentLayerClient virtual void PaintContents( SkCanvas* canvas, gfx::Rect clip, gfx::RectF* opaque) OVERRIDE; + virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} cc::Layer* cc_layer() { return cc_layer_; } diff --git a/webkit/compositor_bindings/web_content_layer_impl.cc b/webkit/compositor_bindings/web_content_layer_impl.cc index 6503a89..6b3e1e7 100644 --- a/webkit/compositor_bindings/web_content_layer_impl.cc +++ b/webkit/compositor_bindings/web_content_layer_impl.cc @@ -25,12 +25,14 @@ static bool usingPictureLayer() { } WebContentLayerImpl::WebContentLayerImpl(WebKit::WebContentLayerClient* client) - : client_(client) { + : client_(client), + ignore_lcd_text_change_(false) { if (usingPictureLayer()) layer_ = make_scoped_ptr(new WebLayerImpl(PictureLayer::Create(this))); else layer_ = make_scoped_ptr(new WebLayerImpl(ContentLayer::Create(this))); layer_->layer()->SetIsDrawable(true); + can_use_lcd_text_ = layer_->layer()->can_use_lcd_text(); } WebContentLayerImpl::~WebContentLayerImpl() { @@ -73,9 +75,23 @@ void WebContentLayerImpl::PaintContents(SkCanvas* canvas, return; WebKit::WebFloatRect web_opaque; - client_->paintContents( - canvas, clip, layer_->layer()->can_use_lcd_text(), web_opaque); + client_->paintContents(canvas, clip, can_use_lcd_text_, web_opaque); *opaque = web_opaque; } +void WebContentLayerImpl::DidChangeLayerCanUseLCDText() { + // It is important to make this comparison because the LCD text status + // here can get out of sync with that in the layer. + if (can_use_lcd_text_ == layer_->layer()->can_use_lcd_text()) + return; + + // LCD text cannot be enabled once disabled. + if (layer_->layer()->can_use_lcd_text() && ignore_lcd_text_change_) + return; + + can_use_lcd_text_ = layer_->layer()->can_use_lcd_text(); + ignore_lcd_text_change_ = true; + layer_->invalidate(); +} + } // namespace webkit diff --git a/webkit/compositor_bindings/web_content_layer_impl.h b/webkit/compositor_bindings/web_content_layer_impl.h index d687c91..9681227 100644 --- a/webkit/compositor_bindings/web_content_layer_impl.h +++ b/webkit/compositor_bindings/web_content_layer_impl.h @@ -42,6 +42,7 @@ class WebContentLayerImpl : public WebKit::WebContentLayer, virtual void PaintContents(SkCanvas* canvas, gfx::Rect clip, gfx::RectF* opaque) OVERRIDE; + virtual void DidChangeLayerCanUseLCDText() OVERRIDE; scoped_ptr<WebLayerImpl> layer_; WebKit::WebContentLayerClient* client_; @@ -49,6 +50,8 @@ class WebContentLayerImpl : public WebKit::WebContentLayer, private: DISALLOW_COPY_AND_ASSIGN(WebContentLayerImpl); + bool can_use_lcd_text_; + bool ignore_lcd_text_change_; }; } // namespace webkit |