diff options
author | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-27 14:18:09 +0000 |
---|---|---|
committer | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-27 14:18:09 +0000 |
commit | c1f67303d4c09d8e318922cc9426709aa1c61729 (patch) | |
tree | 3ceb9704899b4ad9fbde4c67f442782766e93eda /ui/gfx | |
parent | ded6e7eb09dcd19a286d8fd5ca07c8076f66c49f (diff) | |
download | chromium_src-c1f67303d4c09d8e318922cc9426709aa1c61729.zip chromium_src-c1f67303d4c09d8e318922cc9426709aa1c61729.tar.gz chromium_src-c1f67303d4c09d8e318922cc9426709aa1c61729.tar.bz2 |
Do not allocate a texture if hole covers entire layer.
BUG=None
TEST= poster circle, at 35FPS on tegra2 hardware
Review URL: http://codereview.chromium.org/7976004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102925 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx')
-rw-r--r-- | ui/gfx/compositor/layer.cc | 36 | ||||
-rw-r--r-- | ui/gfx/compositor/layer.h | 7 | ||||
-rw-r--r-- | ui/gfx/compositor/layer_unittest.cc | 16 |
3 files changed, 50 insertions, 9 deletions
diff --git a/ui/gfx/compositor/layer.cc b/ui/gfx/compositor/layer.cc index ace17e8..3982b97 100644 --- a/ui/gfx/compositor/layer.cc +++ b/ui/gfx/compositor/layer.cc @@ -15,9 +15,9 @@ namespace ui { Layer::Layer(Compositor* compositor) : compositor_(compositor), - texture_(compositor->CreateTexture()), parent_(NULL), visible_(true), + can_have_texture_(true), fills_bounds_opaquely_(false), layer_updated_externally_(false), opacity_(1.0f), @@ -26,10 +26,9 @@ Layer::Layer(Compositor* compositor) Layer::Layer(Compositor* compositor, TextureParam texture_param) : compositor_(compositor), - texture_(texture_param == LAYER_HAS_TEXTURE ? - compositor->CreateTexture() : NULL), parent_(NULL), visible_(true), + can_have_texture_(texture_param == LAYER_HAS_TEXTURE), fills_bounds_opaquely_(false), layer_updated_externally_(false), opacity_(1.0f), @@ -86,6 +85,11 @@ void Layer::SetBounds(const gfx::Rect& bounds) { parent()->RecomputeHole(); } +bool Layer::ShouldDraw() { + return can_have_texture_ && GetCombinedOpacity() > 0.0f && + !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size())); +} + // static void Layer::ConvertPointToLayer(const Layer* source, const Layer* target, @@ -122,6 +126,11 @@ void Layer::SetExternalTexture(ui::Texture* texture) { } void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) { + DCHECK(can_have_texture_); + + if (!texture_.get()) + texture_ = compositor_->CreateTexture(); + texture_->SetCanvas(canvas, origin, bounds_.size()); invalid_rect_ = gfx::Rect(); } @@ -132,12 +141,13 @@ void Layer::SchedulePaint(const gfx::Rect& invalid_rect) { } void Layer::Draw() { - const float combined_opacity = GetCombinedOpacity(); - if (!texture_.get() || combined_opacity == 0.0f) + if (!ShouldDraw()) return; UpdateLayerCanvas(); + DCHECK(texture_.get()); + ui::TextureDrawParams texture_draw_params; for (Layer* layer = this; layer; layer = layer->parent_) { texture_draw_params.transform.ConcatTransform(layer->transform_); @@ -146,6 +156,8 @@ void Layer::Draw() { static_cast<float>(layer->bounds_.y())); } + const float combined_opacity = GetCombinedOpacity(); + // Only blend for transparent child layers (and when we're forcing // transparency). The root layer will clobber the cleared bg. const bool is_root = parent_ == NULL; @@ -255,16 +267,24 @@ void Layer::UpdateLayerCanvas() { } void Layer::RecomputeHole() { + if (!can_have_texture_) + return; + + // If there are no opaque child layers, hole_rect_ should remain empty. + hole_rect_ = gfx::Rect(); + for (size_t i = 0; i < children_.size(); ++i) { if (children_[i]->fills_bounds_opaquely() && children_[i]->GetCombinedOpacity() == 1.0f && !children_[i]->transform().HasChange()) { hole_rect_ = children_[i]->bounds(); - return; + break; } } - // no opaque child layers, set hole_rect_ to empty - hole_rect_ = gfx::Rect(); + + // Free up texture memory if the hole fills bounds of layer + if (!ShouldDraw() && !layer_updated_externally_) + texture_ = NULL; } bool Layer::ConvertPointForAncestor(const Layer* ancestor, diff --git a/ui/gfx/compositor/layer.h b/ui/gfx/compositor/layer.h index 0850fdb..865a427 100644 --- a/ui/gfx/compositor/layer.h +++ b/ui/gfx/compositor/layer.h @@ -72,6 +72,10 @@ class COMPOSITOR_EXPORT Layer { bool visible() const { return visible_; } void set_visible(bool visible) { visible_ = visible; } + // Returns true if this layer can have a texture (has_texture_ is true) + // and is not completely obscured by a child. + bool ShouldDraw(); + // Converts a point from the coordinates of |source| to the coordinates of // |target|. Necessarily, |source| and |target| must inhabit the same Layer // tree. @@ -184,6 +188,9 @@ class COMPOSITOR_EXPORT Layer { bool visible_; + // If true, layer can have non-null texture. + const bool can_have_texture_; + bool fills_bounds_opaquely_; gfx::Rect hole_rect_; diff --git a/ui/gfx/compositor/layer_unittest.cc b/ui/gfx/compositor/layer_unittest.cc index 97419cd..3037bbf 100644 --- a/ui/gfx/compositor/layer_unittest.cc +++ b/ui/gfx/compositor/layer_unittest.cc @@ -300,5 +300,19 @@ TEST_F(LayerTest, HierarchyNoTexture) { EXPECT_TRUE(d3.painted()); } -} // namespace ui +// Verifies that a layer which is set never to have a texture does not +// get a texture when SetFillsBoundsOpaquely is called. +TEST_F(LayerTest, LayerHasNoTextureSetFillsOpaquely) { + Layer* parent = CreateLayer(Layer::LAYER_HAS_NO_TEXTURE); + parent->SetBounds(gfx::Rect(0, 0, 400, 400)); + + Layer* child = CreateLayer(Layer::LAYER_HAS_TEXTURE); + child->SetBounds(gfx::Rect(50, 50, 100, 100)); + child->SetFillsBoundsOpaquely(true); + + parent->Add(child); + EXPECT_TRUE(parent->texture() == NULL); +} + +} // namespace ui |