summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-23 18:50:16 +0000
committeralokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-23 18:50:16 +0000
commit15c54d5a7e94061ec7f21360284afcca9073a62f (patch)
tree81b6e55f11f9670259ac593ad7322a7abbbebf94
parentb450b4f786fb6b984960f729a0e0875cba36bf9c (diff)
downloadchromium_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.cc14
-rw-r--r--cc/layers/content_layer.h3
-rw-r--r--cc/layers/content_layer_client.h4
-rw-r--r--cc/layers/content_layer_unittest.cc1
-rw-r--r--cc/layers/picture_image_layer.h1
-rw-r--r--cc/test/fake_content_layer_client.h1
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc1
-rw-r--r--cc/trees/layer_tree_host_unittest.cc101
-rw-r--r--ui/compositor/layer.h1
-rw-r--r--webkit/compositor_bindings/web_content_layer_impl.cc22
-rw-r--r--webkit/compositor_bindings/web_content_layer_impl.h3
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