summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-06 03:53:27 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-06 03:53:27 +0000
commitb14d40d9db0a7b9bfd0396e08e789a769475e956 (patch)
tree438b909c086492c4fd21290dd9c097bdb5e4561b /ui
parent91a84f4de037be065c453cb80ec08b5c9be24b78 (diff)
downloadchromium_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.cc129
-rw-r--r--ui/compositor/layer.h25
-rw-r--r--ui/compositor/layer_unittest.cc54
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