diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-06 03:53:27 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-06 03:53:27 +0000 |
commit | b14d40d9db0a7b9bfd0396e08e789a769475e956 (patch) | |
tree | 438b909c086492c4fd21290dd9c097bdb5e4561b /ui | |
parent | 91a84f4de037be065c453cb80ec08b5c9be24b78 (diff) | |
download | chromium_src-b14d40d9db0a7b9bfd0396e08e789a769475e956.zip chromium_src-b14d40d9db0a7b9bfd0396e08e789a769475e956.tar.gz chromium_src-b14d40d9db0a7b9bfd0396e08e789a769475e956.tar.bz2 |
ÜC: Add support for delegated renderer layer in ui::Layer
BUG=123444
Review URL: https://chromiumcodereview.appspot.com/12379092
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186344 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/compositor/layer.cc | 129 | ||||
-rw-r--r-- | ui/compositor/layer.h | 25 | ||||
-rw-r--r-- | ui/compositor/layer_unittest.cc | 54 |
3 files changed, 159 insertions, 49 deletions
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index b73419a..10cbaca 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc @@ -11,8 +11,11 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "cc/content_layer.h" +#include "cc/delegated_frame_data.h" +#include "cc/delegated_renderer_layer.h" #include "cc/solid_color_layer.h" #include "cc/texture_layer.h" +#include "cc/transferable_resource.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperation.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebFilterOperations.h" #include "ui/base/animation/animation.h" @@ -419,52 +422,92 @@ void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { cc_layer_->setContentsOpaque(fills_bounds_opaquely); } +void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) { + if (texture_layer_.get()) + texture_layer_->willModifyTexture(); + // TODO(piman): delegated_renderer_layer_ cleanup. + + cc_layer_->removeAllChildren(); + if (parent_) { + DCHECK(parent_->cc_layer_); + parent_->cc_layer_->replaceChild(cc_layer_, new_layer); + } + cc_layer_->removeLayerAnimationEventObserver(this); + new_layer->setOpacity(cc_layer_->opacity()); + + cc_layer_= new_layer; + content_layer_ = NULL; + solid_color_layer_ = NULL; + texture_layer_ = NULL; + delegated_renderer_layer_ = NULL; + + cc_layer_->addLayerAnimationEventObserver(this); + for (size_t i = 0; i < children_.size(); ++i) { + DCHECK(children_[i]->cc_layer_); + cc_layer_->addChild(children_[i]->cc_layer_); + } + cc_layer_->setAnchorPoint(gfx::PointF()); + cc_layer_->setContentsOpaque(fills_bounds_opaquely_); + cc_layer_->setForceRenderSurface(force_render_surface_); + cc_layer_->setIsDrawable(IsDrawn()); +} + void Layer::SetExternalTexture(Texture* texture) { DCHECK_EQ(type_, LAYER_TEXTURED); DCHECK(!solid_color_layer_); - layer_updated_externally_ = !!texture; + bool has_texture = !!texture; + layer_updated_externally_ = has_texture; texture_ = texture; - if (cc_layer_is_accelerated_ != layer_updated_externally_) { + if (!!texture_layer_ != has_texture) { // Switch to a different type of layer. - cc_layer_->removeAllChildren(); - - scoped_refptr<cc::ContentLayer> old_content_layer; - old_content_layer.swap(content_layer_); - scoped_refptr<cc::TextureLayer> old_texture_layer; - old_texture_layer.swap(texture_layer_); - - cc::Layer* new_layer = NULL; - if (layer_updated_externally_) { - texture_layer_ = cc::TextureLayer::create(this); - texture_layer_->setFlipped(texture_->flipped()); - new_layer = texture_layer_.get(); + if (has_texture) { + scoped_refptr<cc::TextureLayer> new_layer = + cc::TextureLayer::create(this); + new_layer->setFlipped(texture_->flipped()); + SwitchToLayer(new_layer); + texture_layer_ = new_layer; } else { - old_texture_layer->willModifyTexture(); - content_layer_ = cc::ContentLayer::create(this); - new_layer = content_layer_.get(); + scoped_refptr<cc::ContentLayer> new_layer = + cc::ContentLayer::create(this); + SwitchToLayer(new_layer); + content_layer_ = new_layer; } - if (parent_) { - DCHECK(parent_->cc_layer_); - parent_->cc_layer_->replaceChild(cc_layer_, new_layer); - } - cc_layer_->removeLayerAnimationEventObserver(this); - new_layer->setOpacity(cc_layer_->opacity()); - cc_layer_= new_layer; - cc_layer_->addLayerAnimationEventObserver(this); - cc_layer_is_accelerated_ = layer_updated_externally_; - for (size_t i = 0; i < children_.size(); ++i) { - DCHECK(children_[i]->cc_layer_); - cc_layer_->addChild(children_[i]->cc_layer_); + RecomputeTransform(); + } + RecomputeDrawsContentAndUVRect(); +} + +void Layer::SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame, + gfx::Size frame_size_in_dip) { + DCHECK_EQ(type_, LAYER_TEXTURED); + bool has_frame = frame.get() && !frame->render_pass_list.empty(); + layer_updated_externally_ = has_frame; + delegated_frame_size_in_dip_ = frame_size_in_dip; + if (!!delegated_renderer_layer_ != has_frame) { + if (has_frame) { + scoped_refptr<cc::DelegatedRendererLayer> new_layer = + cc::DelegatedRendererLayer::Create(); + SwitchToLayer(new_layer); + delegated_renderer_layer_ = new_layer; + } else { + scoped_refptr<cc::ContentLayer> new_layer = + cc::ContentLayer::create(this); + SwitchToLayer(new_layer); + content_layer_ = new_layer; } - cc_layer_->setAnchorPoint(gfx::PointF()); - cc_layer_->setContentsOpaque(fills_bounds_opaquely_); - cc_layer_->setForceRenderSurface(force_render_surface_); - cc_layer_->setIsDrawable(IsDrawn()); RecomputeTransform(); } + if (has_frame) + delegated_renderer_layer_->SetFrameData(frame.Pass()); RecomputeDrawsContentAndUVRect(); } +void Layer::TakeUnusedResourcesForChildCompositor( + cc::TransferableResourceArray* list) { + if (delegated_renderer_layer_) + delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(list); +} + void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); } @@ -552,12 +595,12 @@ void Layer::paintContents(SkCanvas* sk_canvas, } unsigned Layer::prepareTexture(cc::ResourceUpdateQueue&) { - DCHECK(layer_updated_externally_); + DCHECK(texture_layer_); return texture_->PrepareTexture(); } WebKit::WebGraphicsContext3D* Layer::context() { - DCHECK(layer_updated_externally_); + DCHECK(texture_layer_); return texture_->HostContext3D(); } @@ -777,7 +820,6 @@ void Layer::CreateWebLayer() { content_layer_ = cc::ContentLayer::create(this); cc_layer_ = content_layer_.get(); } - cc_layer_is_accelerated_ = false; cc_layer_->setAnchorPoint(gfx::PointF()); cc_layer_->setContentsOpaque(true); cc_layer_->setIsDrawable(type_ != LAYER_NOT_DRAWN); @@ -804,25 +846,26 @@ void Layer::RecomputeTransform() { void Layer::RecomputeDrawsContentAndUVRect() { DCHECK(cc_layer_); - if (!cc_layer_is_accelerated_) { - cc_layer_->setBounds(ConvertSizeToPixel(this, bounds_.size())); - } else { + gfx::Size size(bounds_.size()); + if (texture_layer_.get()) { DCHECK(texture_); float texture_scale_factor = 1.0f / texture_->device_scale_factor(); gfx::Size texture_size = gfx::ToFlooredSize( gfx::ScaleSize(texture_->size(), texture_scale_factor)); + size.ClampToMax(texture_size); - gfx::Size size(std::min(bounds().width(), texture_size.width()), - std::min(bounds().height(), texture_size.height())); gfx::PointF uv_top_left(0.f, 0.f); gfx::PointF uv_bottom_right( static_cast<float>(size.width())/texture_size.width(), static_cast<float>(size.height())/texture_size.height()); texture_layer_->setUV(uv_top_left, uv_bottom_right); - - cc_layer_->setBounds(ConvertSizeToPixel(this, size)); + } else if (delegated_renderer_layer_.get()) { + delegated_renderer_layer_->SetDisplaySize( + ConvertSizeToPixel(this, delegated_frame_size_in_dip_)); + size.ClampToMax(delegated_frame_size_in_dip_); } + cc_layer_->setBounds(ConvertSizeToPixel(this, size)); } } // namespace ui diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index 2c322d0..42adbcc 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h @@ -29,10 +29,14 @@ class SkCanvas; namespace cc { class ContentLayer; +class DelegatedFrameData; +class DelegatedRendererLayer; class Layer; class ResourceUpdateQueue; class SolidColorLayer; class TextureLayer; +struct TransferableResource; +typedef std::vector<TransferableResource> TransferableResourceArray; } namespace ui { @@ -235,6 +239,14 @@ class COMPOSITOR_EXPORT Layer void SetExternalTexture(ui::Texture* texture); ui::Texture* external_texture() { return texture_.get(); } + // Sets a delegated frame, coming from a child compositor. + void SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame, + gfx::Size frame_size_in_dip); + + // Gets unused resources to recycle to the child compositor. + void TakeUnusedResourcesForChildCompositor( + cc::TransferableResourceArray* array); + // Sets the layer's fill color. May only be called for LAYER_SOLID_COLOR. void SetColor(SkColor color); @@ -304,11 +316,6 @@ class COMPOSITOR_EXPORT Layer bool GetTargetTransformRelativeTo(const Layer* ancestor, gfx::Transform* transform) const; - // The only externally updated layers are ones that get their pixels from - // WebKit and WebKit does not produce valid alpha values. All other layers - // should have valid alpha. - bool has_valid_alpha_channel() const { return !layer_updated_externally_; } - // Following are invoked from the animation or if no animation exists to // update the values immediately. void SetBoundsImmediately(const gfx::Rect& bounds); @@ -352,6 +359,8 @@ class COMPOSITOR_EXPORT Layer void UpdateIsDrawn(); + void SwitchToLayer(scoped_refptr<cc::Layer> new_layer); + const LayerType type_; Compositor* compositor_; @@ -423,8 +432,8 @@ class COMPOSITOR_EXPORT Layer scoped_refptr<cc::ContentLayer> content_layer_; scoped_refptr<cc::TextureLayer> texture_layer_; scoped_refptr<cc::SolidColorLayer> solid_color_layer_; + scoped_refptr<cc::DelegatedRendererLayer> delegated_renderer_layer_; cc::Layer* cc_layer_; - bool cc_layer_is_accelerated_; // If true, the layer scales the canvas and the texture with the device scale // factor as appropriate. When true, the texture size is in DIP. @@ -433,6 +442,10 @@ class COMPOSITOR_EXPORT Layer // A cached copy of |Compositor::device_scale_factor()|. float device_scale_factor_; + // The size of the delegated frame in DIP, set when SetDelegatedFrame was + // called. + gfx::Size delegated_frame_size_in_dip_; + DISALLOW_COPY_AND_ASSIGN(Layer); }; diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index 54fdea7..9bb3400 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc @@ -10,6 +10,7 @@ #include "base/path_service.h" #include "base/string_util.h" #include "base/stringprintf.h" +#include "cc/delegated_frame_data.h" #include "cc/layer.h" #include "cc/test/pixel_test_utils.h" #include "testing/gtest/include/gtest/gtest.h" @@ -1255,4 +1256,57 @@ TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) { EXPECT_TRUE(delegate.painted()); } +static scoped_ptr<cc::DelegatedFrameData> MakeFrameData(gfx::Size size) { + scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData); + scoped_ptr<cc::RenderPass> render_pass(cc::RenderPass::Create()); + render_pass->SetNew(cc::RenderPass::Id(1, 1), + gfx::Rect(size), + gfx::RectF(), + gfx::Transform()); + frame_data->render_pass_list.push_back(render_pass.Pass()); + return frame_data.Pass(); +} + +TEST_F(LayerWithDelegateTest, DelegatedLayer) { + scoped_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000))); + + scoped_ptr<Layer> child(CreateLayer(LAYER_TEXTURED)); + + child->SetBounds(gfx::Rect(0, 0, 10, 10)); + child->SetVisible(true); + root->Add(child.get()); + DrawTree(root.get()); + + // Content matches layer size. + child->SetDelegatedFrame(MakeFrameData(gfx::Size(10, 10)), gfx::Size(10, 10)); + EXPECT_EQ(child->cc_layer()->bounds().ToString(), + gfx::Size(10, 10).ToString()); + + // Content larger than layer. + child->SetBounds(gfx::Rect(0, 0, 5, 5)); + EXPECT_EQ(child->cc_layer()->bounds().ToString(), + gfx::Size(5, 5).ToString()); + + // Content smaller than layer. + child->SetBounds(gfx::Rect(0, 0, 10, 10)); + child->SetDelegatedFrame(MakeFrameData(gfx::Size(5, 5)), gfx::Size(5, 5)); + EXPECT_EQ(child->cc_layer()->bounds().ToString(), + gfx::Size(5, 5).ToString()); + + // Hi-DPI content on low-DPI layer. + child->SetDelegatedFrame(MakeFrameData(gfx::Size(20, 20)), gfx::Size(10, 10)); + EXPECT_EQ(child->cc_layer()->bounds().ToString(), + gfx::Size(10, 10).ToString()); + + // Hi-DPI content on hi-DPI layer. + compositor()->SetScaleAndSize(2.f, gfx::Size(1000, 1000)); + EXPECT_EQ(child->cc_layer()->bounds().ToString(), + gfx::Size(20, 20).ToString()); + + // Low-DPI content on hi-DPI layer. + child->SetDelegatedFrame(MakeFrameData(gfx::Size(10, 10)), gfx::Size(10, 10)); + EXPECT_EQ(child->cc_layer()->bounds().ToString(), + gfx::Size(20, 20).ToString()); +} + } // namespace ui |