summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/cc.gyp4
-rw-r--r--cc/cc_tests.gyp4
-rw-r--r--cc/layers/nine_patch_layer.cc96
-rw-r--r--cc/layers/nine_patch_layer.h21
-rw-r--r--cc/layers/nine_patch_layer_impl.cc83
-rw-r--r--cc/layers/nine_patch_layer_impl.h17
-rw-r--r--cc/layers/nine_patch_layer_impl_unittest.cc40
-rw-r--r--cc/layers/nine_patch_layer_unittest.cc38
-rw-r--r--cc/layers/ui_resource_layer.cc127
-rw-r--r--cc/layers/ui_resource_layer.h59
-rw-r--r--cc/layers/ui_resource_layer_impl.cc121
-rw-r--r--cc/layers/ui_resource_layer_impl.h62
-rw-r--r--cc/layers/ui_resource_layer_impl_unittest.cc123
-rw-r--r--cc/layers/ui_resource_layer_unittest.cc122
-rw-r--r--cc/test/fake_ui_resource_layer_tree_host_impl.cc39
-rw-r--r--cc/test/fake_ui_resource_layer_tree_host_impl.h35
-rw-r--r--cc/test/layer_tree_json_parser.cc3
-rw-r--r--cc/trees/layer_tree_host_impl.cc10
-rw-r--r--cc/trees/layer_tree_host_impl.h7
-rw-r--r--webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.cc31
-rw-r--r--webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.h9
21 files changed, 797 insertions, 254 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index e4ead4b..e60eae3 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -180,6 +180,10 @@
'layers/tiled_layer.h',
'layers/tiled_layer_impl.cc',
'layers/tiled_layer_impl.h',
+ 'layers/ui_resource_layer.cc',
+ 'layers/ui_resource_layer.h',
+ 'layers/ui_resource_layer_impl.cc',
+ 'layers/ui_resource_layer_impl.h',
'layers/video_frame_provider.h',
'layers/video_frame_provider_client_impl.cc',
'layers/video_frame_provider_client_impl.h',
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index 53aa85b..db8bc62 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -38,6 +38,8 @@
'layers/texture_layer_unittest.cc',
'layers/tiled_layer_impl_unittest.cc',
'layers/tiled_layer_unittest.cc',
+ 'layers/ui_resource_layer_impl_unittest.cc',
+ 'layers/ui_resource_layer_unittest.cc',
'output/delegating_renderer_unittest.cc',
'output/filter_operations_unittest.cc',
'output/gl_renderer_unittest.cc',
@@ -132,6 +134,8 @@
'test/fake_tile_manager.h',
'test/fake_tile_manager_client.h',
'test/fake_tile_manager_client.cc',
+ 'test/fake_ui_resource_layer_tree_host_impl.h',
+ 'test/fake_ui_resource_layer_tree_host_impl.cc',
'test/fake_output_surface.cc',
'test/fake_output_surface.h',
'test/fake_output_surface_client.cc',
diff --git a/cc/layers/nine_patch_layer.cc b/cc/layers/nine_patch_layer.cc
index 5e00007..f676131 100644
--- a/cc/layers/nine_patch_layer.cc
+++ b/cc/layers/nine_patch_layer.cc
@@ -14,44 +14,6 @@
namespace cc {
-
-namespace {
-
-class ScopedUIResourceHolder : public NinePatchLayer::UIResourceHolder {
- public:
- static scoped_ptr<ScopedUIResourceHolder> Create(LayerTreeHost* host,
- const SkBitmap& skbitmap) {
- return make_scoped_ptr(new ScopedUIResourceHolder(host, skbitmap));
- }
- virtual UIResourceId id() OVERRIDE { return resource_->id(); }
-
- private:
- ScopedUIResourceHolder(LayerTreeHost* host, const SkBitmap& skbitmap) {
- resource_ = ScopedUIResource::Create(host, UIResourceBitmap(skbitmap));
- }
-
- scoped_ptr<ScopedUIResource> resource_;
-};
-
-class SharedUIResourceHolder : public NinePatchLayer::UIResourceHolder {
- public:
- static scoped_ptr<SharedUIResourceHolder> Create(UIResourceId id) {
- return make_scoped_ptr(new SharedUIResourceHolder(id));
- }
-
- virtual UIResourceId id() OVERRIDE { return id_; }
-
- private:
- explicit SharedUIResourceHolder(UIResourceId id) : id_(id) {}
-
- UIResourceId id_;
-};
-
-} // anonymous namespace
-
-
-NinePatchLayer::UIResourceHolder::~UIResourceHolder() {}
-
scoped_refptr<NinePatchLayer> NinePatchLayer::Create() {
return make_scoped_refptr(new NinePatchLayer());
}
@@ -65,25 +27,6 @@ scoped_ptr<LayerImpl> NinePatchLayer::CreateLayerImpl(
return NinePatchLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
}
-void NinePatchLayer::SetLayerTreeHost(LayerTreeHost* host) {
- if (host == layer_tree_host())
- return;
-
- Layer::SetLayerTreeHost(host);
-
- // Recreate the resource hold against the new LTH.
- RecreateUIResourceHolder();
-}
-
-void NinePatchLayer::RecreateUIResourceHolder() {
- ui_resource_holder_.reset();
- if (!layer_tree_host() || bitmap_.empty())
- return;
-
- ui_resource_holder_ =
- ScopedUIResourceHolder::Create(layer_tree_host(), bitmap_);
-}
-
void NinePatchLayer::SetBorder(gfx::Rect border) {
if (border == border_)
return;
@@ -91,34 +34,11 @@ void NinePatchLayer::SetBorder(gfx::Rect border) {
SetNeedsCommit();
}
-void NinePatchLayer::SetBitmap(const SkBitmap& skbitmap, gfx::Rect aperture) {
- image_aperture_ = aperture;
- bitmap_ = skbitmap;
-
- // TODO(ccameron): Remove this. This provides the default border that was
- // provided before borders were required to be explicitly provided. Once Blink
- // fixes its callers to call SetBorder, this can be removed.
- SetBorder(gfx::Rect(aperture.x(),
- aperture.y(),
- skbitmap.width() - aperture.width(),
- skbitmap.height() - aperture.height()));
- RecreateUIResourceHolder();
- SetNeedsCommit();
-}
-
-void NinePatchLayer::SetUIResourceId(UIResourceId resource_id,
- gfx::Rect aperture) {
- if (ui_resource_holder_ && ui_resource_holder_->id() == resource_id &&
- image_aperture_ == aperture)
+void NinePatchLayer::SetAperture(gfx::Rect aperture) {
+ if (image_aperture_ == aperture)
return;
image_aperture_ = aperture;
- if (resource_id) {
- ui_resource_holder_ = SharedUIResourceHolder::Create(resource_id);
- } else {
- ui_resource_holder_.reset();
- }
-
SetNeedsCommit();
}
@@ -130,13 +50,8 @@ void NinePatchLayer::SetFillCenter(bool fill_center) {
SetNeedsCommit();
}
-bool NinePatchLayer::DrawsContent() const {
- return ui_resource_holder_ && ui_resource_holder_->id() &&
- Layer::DrawsContent();
-}
-
void NinePatchLayer::PushPropertiesTo(LayerImpl* layer) {
- Layer::PushPropertiesTo(layer);
+ UIResourceLayer::PushPropertiesTo(layer);
NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);
if (!ui_resource_holder_) {
@@ -144,10 +59,7 @@ void NinePatchLayer::PushPropertiesTo(LayerImpl* layer) {
} else {
DCHECK(layer_tree_host());
- gfx::Size image_size =
- layer_tree_host()->GetUIResourceSize(ui_resource_holder_->id());
- layer_impl->SetUIResourceId(ui_resource_holder_->id());
- layer_impl->SetLayout(image_size, image_aperture_, border_, fill_center_);
+ layer_impl->SetLayout(image_aperture_, border_, fill_center_);
}
}
diff --git a/cc/layers/nine_patch_layer.h b/cc/layers/nine_patch_layer.h
index 5880635..dc9f81f 100644
--- a/cc/layers/nine_patch_layer.h
+++ b/cc/layers/nine_patch_layer.h
@@ -8,6 +8,7 @@
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/layers/layer.h"
+#include "cc/layers/ui_resource_layer.h"
#include "cc/resources/ui_resource_client.h"
#include "ui/gfx/rect.h"
@@ -16,16 +17,12 @@ namespace cc {
class LayerTreeHost;
class ScopedUIResource;
-class CC_EXPORT NinePatchLayer : public Layer {
+class CC_EXPORT NinePatchLayer : public UIResourceLayer {
public:
static scoped_refptr<NinePatchLayer> Create();
- virtual bool DrawsContent() const OVERRIDE;
-
virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE;
- virtual void SetLayerTreeHost(LayerTreeHost* host) OVERRIDE;
-
// |border| is the space around the center rectangular region in layer space
// (known as aperture in image space). |border.x()| and |border.y()| are the
// size of the left and top boundary, respectively.
@@ -39,29 +36,17 @@ class CC_EXPORT NinePatchLayer : public Layer {
// on the edges of the layer. The corners are unscaled, the top and bottom
// rects are x-stretched to fit, and the left and right rects are
// y-stretched to fit.
- void SetBitmap(const SkBitmap& skbitmap, gfx::Rect aperture);
-
- // An alternative way of setting the resource to allow for sharing.
- void SetUIResourceId(UIResourceId resource_id, gfx::Rect aperture);
+ void SetAperture(gfx::Rect aperture);
void SetFillCenter(bool fill_center);
- class UIResourceHolder {
- public:
- virtual UIResourceId id() = 0;
- virtual ~UIResourceHolder();
- };
-
private:
NinePatchLayer();
virtual ~NinePatchLayer();
virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
OVERRIDE;
- void RecreateUIResourceHolder();
gfx::Rect border_;
bool fill_center_;
- scoped_ptr<UIResourceHolder> ui_resource_holder_;
- SkBitmap bitmap_;
// The transparent center region that shows the parent layer's contents in
// image space.
diff --git a/cc/layers/nine_patch_layer_impl.cc b/cc/layers/nine_patch_layer_impl.cc
index f609c3d..c3e0998 100644
--- a/cc/layers/nine_patch_layer_impl.cc
+++ b/cc/layers/nine_patch_layer_impl.cc
@@ -15,27 +15,21 @@
namespace cc {
NinePatchLayerImpl::NinePatchLayerImpl(LayerTreeImpl* tree_impl, int id)
- : LayerImpl(tree_impl, id),
- fill_center_(false),
- ui_resource_id_(0) {}
+ : UIResourceLayerImpl(tree_impl, id),
+ fill_center_(false) {}
NinePatchLayerImpl::~NinePatchLayerImpl() {}
-ResourceProvider::ResourceId NinePatchLayerImpl::ContentsResourceId() const {
- return 0;
-}
-
scoped_ptr<LayerImpl> NinePatchLayerImpl::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
return NinePatchLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
}
void NinePatchLayerImpl::PushPropertiesTo(LayerImpl* layer) {
- LayerImpl::PushPropertiesTo(layer);
+ UIResourceLayerImpl::PushPropertiesTo(layer);
NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);
- layer_impl->SetUIResourceId(ui_resource_id_);
- layer_impl->SetLayout(image_bounds_, image_aperture_, border_, fill_center_);
+ layer_impl->SetLayout(image_aperture_, border_, fill_center_);
}
static gfx::RectF NormalizedRect(float x,
@@ -50,70 +44,57 @@ static gfx::RectF NormalizedRect(float x,
height / total_height);
}
-void NinePatchLayerImpl::SetUIResourceId(UIResourceId uid) {
- if (uid == ui_resource_id_)
- return;
- ui_resource_id_ = uid;
- NoteLayerPropertyChanged();
-}
-
-void NinePatchLayerImpl::SetLayout(gfx::Size image_bounds,
- gfx::Rect aperture,
+void NinePatchLayerImpl::SetLayout(gfx::Rect aperture,
gfx::Rect border,
bool fill_center) {
// This check imposes an ordering on the call sequence. An UIResource must
// exist before SetLayout can be called.
DCHECK(ui_resource_id_);
+ if (image_aperture_ == aperture &&
+ border_ == border && fill_center_ == fill_center)
+ return;
+
+ image_aperture_ = aperture;
+ border_ = border;
+ fill_center_ = fill_center;
+
+ NoteLayerPropertyChanged();
+}
+
+void NinePatchLayerImpl::CheckGeometryLimitations() {
// TODO(ccameron): the following "greater than or equal to" (GE) checks should
// be greater than (GT) to avoid degenerate nine-patches. The relaxed
// condition "equal to" is a workaround for the overhang shadow use case and
// should be investigated further.
// |border| is in layer space. It cannot exceed the bounds of the layer.
- DCHECK(!border.size().IsEmpty());
- DCHECK_GE(bounds().width(), border.width());
- DCHECK_GE(bounds().height(), border.height());
+ DCHECK(!border_.size().IsEmpty());
+ DCHECK_GE(bounds().width(), border_.width());
+ DCHECK_GE(bounds().height(), border_.height());
// Sanity Check on |border|
- DCHECK_LT(border.x(), border.width());
- DCHECK_LT(border.y(), border.height());
- DCHECK_GE(border.x(), 0);
- DCHECK_GE(border.y(), 0);
+ DCHECK_LT(border_.x(), border_.width());
+ DCHECK_LT(border_.y(), border_.height());
+ DCHECK_GE(border_.x(), 0);
+ DCHECK_GE(border_.y(), 0);
// |aperture| is in image space. It cannot exceed the bounds of the bitmap.
- DCHECK(!aperture.size().IsEmpty());
- DCHECK(gfx::Rect(image_bounds.width(), image_bounds.height())
- .Contains(aperture));
+ DCHECK(!image_aperture_.size().IsEmpty());
+ DCHECK(gfx::Rect(image_bounds_.width(), image_bounds_.height())
+ .Contains(image_aperture_));
// Avoid the degenerate cases where the aperture touches the edge of the
// image.
- DCHECK_LT(aperture.width(), image_bounds.width() - 1);
- DCHECK_LT(aperture.height(), image_bounds.height() - 1);
- DCHECK_GT(aperture.x(), 0);
- DCHECK_GT(aperture.y(), 0);
-
- if (image_bounds_ == image_bounds && image_aperture_ == aperture &&
- border_ == border && fill_center_ == fill_center)
- return;
-
- image_bounds_ = image_bounds;
- image_aperture_ = aperture;
- border_ = border;
- fill_center_ = fill_center;
-
- NoteLayerPropertyChanged();
-}
-
-bool NinePatchLayerImpl::WillDraw(DrawMode draw_mode,
- ResourceProvider* resource_provider) {
- if (!ui_resource_id_ || draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
- return false;
- return LayerImpl::WillDraw(draw_mode, resource_provider);
+ DCHECK_LT(image_aperture_.width(), image_bounds_.width() - 1);
+ DCHECK_LT(image_aperture_.height(), image_bounds_.height() - 1);
+ DCHECK_GT(image_aperture_.x(), 0);
+ DCHECK_GT(image_aperture_.y(), 0);
}
void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
AppendQuadsData* append_quads_data) {
+ CheckGeometryLimitations();
SharedQuadState* shared_quad_state =
quad_sink->UseSharedQuadState(CreateSharedQuadState());
AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
diff --git a/cc/layers/nine_patch_layer_impl.h b/cc/layers/nine_patch_layer_impl.h
index ba414ae..d85e40f 100644
--- a/cc/layers/nine_patch_layer_impl.h
+++ b/cc/layers/nine_patch_layer_impl.h
@@ -9,6 +9,7 @@
#include "cc/base/cc_export.h"
#include "cc/layers/layer_impl.h"
+#include "cc/layers/ui_resource_layer_impl.h"
#include "cc/resources/resource_provider.h"
#include "cc/resources/ui_resource_client.h"
#include "ui/gfx/rect.h"
@@ -20,7 +21,7 @@ class DictionaryValue;
namespace cc {
-class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
+class CC_EXPORT NinePatchLayerImpl : public UIResourceLayerImpl {
public:
static scoped_ptr<NinePatchLayerImpl> Create(LayerTreeImpl* tree_impl,
int id) {
@@ -28,9 +29,6 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
}
virtual ~NinePatchLayerImpl();
-
- void SetUIResourceId(UIResourceId uid);
-
// The bitmap stretches out the bounds of the layer. The following picture
// illustrates the parameters associated with the dimensions.
//
@@ -55,8 +53,7 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
// |image_aperture| = (X, Y, P, Q)
// |border| = (A, C, A + B, C + D)
// |fill_center| indicates whether to draw the center quad or not.
- void SetLayout(gfx::Size image_bounds,
- gfx::Rect image_aperture,
+ void SetLayout(gfx::Rect image_aperture,
gfx::Rect border,
bool fill_center);
@@ -64,11 +61,8 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
OVERRIDE;
virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE;
- virtual bool WillDraw(DrawMode draw_mode,
- ResourceProvider* resource_provider) OVERRIDE;
virtual void AppendQuads(QuadSink* quad_sink,
AppendQuadsData* append_quads_data) OVERRIDE;
- virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE;
virtual base::DictionaryValue* LayerTreeAsJson() const OVERRIDE;
@@ -78,8 +72,7 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
private:
virtual const char* LayerTypeAsString() const OVERRIDE;
- // The size of the NinePatch bitmap in pixels.
- gfx::Size image_bounds_;
+ void CheckGeometryLimitations();
// The transparent center region that shows the parent layer's contents in
// image space.
@@ -90,8 +83,6 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
bool fill_center_;
- UIResourceId ui_resource_id_;
-
DISALLOW_COPY_AND_ASSIGN(NinePatchLayerImpl);
};
diff --git a/cc/layers/nine_patch_layer_impl_unittest.cc b/cc/layers/nine_patch_layer_impl_unittest.cc
index 0fbc645..6020111 100644
--- a/cc/layers/nine_patch_layer_impl_unittest.cc
+++ b/cc/layers/nine_patch_layer_impl_unittest.cc
@@ -9,7 +9,7 @@
#include "cc/resources/ui_resource_bitmap.h"
#include "cc/resources/ui_resource_client.h"
#include "cc/test/fake_impl_proxy.h"
-#include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/fake_ui_resource_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_test_common.h"
#include "cc/test/mock_quad_culler.h"
@@ -23,40 +23,6 @@
namespace cc {
namespace {
-class FakeUIResourceLayerTreeHostImpl : public FakeLayerTreeHostImpl {
- public:
- explicit FakeUIResourceLayerTreeHostImpl(Proxy* proxy)
- : FakeLayerTreeHostImpl(proxy), fake_next_resource_id_(1) {}
-
- virtual void CreateUIResource(
- UIResourceId uid,
- const UIResourceBitmap& bitmap) OVERRIDE {
- if (ResourceIdForUIResource(uid))
- DeleteUIResource(uid);
- fake_ui_resource_map_[uid] = fake_next_resource_id_;
- }
-
- virtual void DeleteUIResource(UIResourceId uid) OVERRIDE {
- ResourceProvider::ResourceId id = ResourceIdForUIResource(uid);
- if (id)
- fake_ui_resource_map_.erase(uid);
- }
-
- virtual ResourceProvider::ResourceId ResourceIdForUIResource(
- UIResourceId uid) const OVERRIDE {
- UIResourceMap::const_iterator iter = fake_ui_resource_map_.find(uid);
- if (iter != fake_ui_resource_map_.end())
- return iter->second;
- return 0;
- }
-
- private:
- ResourceProvider::ResourceId fake_next_resource_id_;
- typedef base::hash_map<UIResourceId, ResourceProvider::ResourceId>
- UIResourceMap;
- UIResourceMap fake_ui_resource_map_;
-};
-
gfx::Rect ToRoundedIntRect(gfx::RectF rect_f) {
return gfx::Rect(gfx::ToRoundedInt(rect_f.x()),
gfx::ToRoundedInt(rect_f.y()),
@@ -97,8 +63,8 @@ void NinePatchLayerLayoutTest(gfx::Size bitmap_size,
host_impl.CreateUIResource(uid, bitmap);
layer->SetUIResourceId(uid);
-
- layer->SetLayout(bitmap_size, aperture_rect, border, fill_center);
+ layer->SetImageBounds(bitmap_size);
+ layer->SetLayout(aperture_rect, border, fill_center);
AppendQuadsData data;
layer->AppendQuads(&quad_culler, &data);
diff --git a/cc/layers/nine_patch_layer_unittest.cc b/cc/layers/nine_patch_layer_unittest.cc
index 101146c..f616560 100644
--- a/cc/layers/nine_patch_layer_unittest.cc
+++ b/cc/layers/nine_patch_layer_unittest.cc
@@ -56,40 +56,7 @@ class NinePatchLayerTest : public testing::Test {
FakeLayerTreeHostClient fake_client_;
};
-TEST_F(NinePatchLayerTest, SetBitmap) {
- scoped_refptr<NinePatchLayer> test_layer = NinePatchLayer::Create();
- ASSERT_TRUE(test_layer.get());
- test_layer->SetIsDrawable(true);
- test_layer->SetBounds(gfx::Size(100, 100));
-
- layer_tree_host_->SetRootLayer(test_layer);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
- EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
-
- layer_tree_host_->InitializeOutputSurfaceIfNeeded();
-
- ResourceUpdateQueue queue;
- OcclusionTracker occlusion_tracker(gfx::Rect(), false);
- test_layer->SavePaintProperties();
- test_layer->Update(&queue, &occlusion_tracker);
-
- EXPECT_FALSE(test_layer->DrawsContent());
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
- bitmap.allocPixels();
- bitmap.setImmutable();
-
- gfx::Rect aperture(5, 5, 1, 1);
- bool fill_center = false;
- test_layer->SetBitmap(bitmap, aperture);
- test_layer->SetFillCenter(fill_center);
- test_layer->Update(&queue, &occlusion_tracker);
-
- EXPECT_TRUE(test_layer->DrawsContent());
-}
-
-TEST_F(NinePatchLayerTest, SetUIResourceId) {
+TEST_F(NinePatchLayerTest, SetLayerProperties) {
scoped_refptr<NinePatchLayer> test_layer = NinePatchLayer::Create();
ASSERT_TRUE(test_layer.get());
test_layer->SetIsDrawable(true);
@@ -117,7 +84,8 @@ TEST_F(NinePatchLayerTest, SetUIResourceId) {
layer_tree_host_.get(), UIResourceBitmap(bitmap));
gfx::Rect aperture(5, 5, 1, 1);
bool fill_center = true;
- test_layer->SetUIResourceId(resource->id(), aperture);
+ test_layer->SetAperture(aperture);
+ test_layer->SetUIResourceId(resource->id());
test_layer->SetFillCenter(fill_center);
test_layer->Update(&queue, &occlusion_tracker);
diff --git a/cc/layers/ui_resource_layer.cc b/cc/layers/ui_resource_layer.cc
new file mode 100644
index 0000000..8edc19e
--- /dev/null
+++ b/cc/layers/ui_resource_layer.cc
@@ -0,0 +1,127 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/ui_resource_layer.h"
+
+#include "cc/layers/ui_resource_layer_impl.h"
+#include "cc/resources/prioritized_resource.h"
+#include "cc/resources/resource_update.h"
+#include "cc/resources/resource_update_queue.h"
+#include "cc/resources/scoped_ui_resource.h"
+#include "cc/resources/ui_resource_bitmap.h"
+#include "cc/trees/layer_tree_host.h"
+
+namespace cc {
+
+
+namespace {
+
+class ScopedUIResourceHolder : public UIResourceLayer::UIResourceHolder {
+ public:
+ static scoped_ptr<ScopedUIResourceHolder> Create(LayerTreeHost* host,
+ const SkBitmap& skbitmap) {
+ return make_scoped_ptr(new ScopedUIResourceHolder(host, skbitmap));
+ }
+ virtual UIResourceId id() OVERRIDE { return resource_->id(); }
+
+ private:
+ ScopedUIResourceHolder(LayerTreeHost* host, const SkBitmap& skbitmap) {
+ resource_ = ScopedUIResource::Create(host, UIResourceBitmap(skbitmap));
+ }
+
+ scoped_ptr<ScopedUIResource> resource_;
+};
+
+class SharedUIResourceHolder : public UIResourceLayer::UIResourceHolder {
+ public:
+ static scoped_ptr<SharedUIResourceHolder> Create(UIResourceId id) {
+ return make_scoped_ptr(new SharedUIResourceHolder(id));
+ }
+
+ virtual UIResourceId id() OVERRIDE { return id_; }
+
+ private:
+ explicit SharedUIResourceHolder(UIResourceId id) : id_(id) {}
+
+ UIResourceId id_;
+};
+
+} // anonymous namespace
+
+UIResourceLayer::UIResourceHolder::~UIResourceHolder() {}
+
+scoped_refptr<UIResourceLayer> UIResourceLayer::Create() {
+ return make_scoped_refptr(new UIResourceLayer());
+}
+
+UIResourceLayer::UIResourceLayer() {}
+
+UIResourceLayer::~UIResourceLayer() {}
+
+scoped_ptr<LayerImpl> UIResourceLayer::CreateLayerImpl(
+ LayerTreeImpl* tree_impl) {
+ return UIResourceLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
+}
+
+void UIResourceLayer::SetLayerTreeHost(LayerTreeHost* host) {
+ if (host == layer_tree_host())
+ return;
+
+ Layer::SetLayerTreeHost(host);
+
+ // Recreate the resource hold against the new LTH.
+ RecreateUIResourceHolder();
+}
+
+void UIResourceLayer::RecreateUIResourceHolder() {
+ ui_resource_holder_.reset();
+ if (!layer_tree_host() || bitmap_.empty())
+ return;
+
+ ui_resource_holder_ =
+ ScopedUIResourceHolder::Create(layer_tree_host(), bitmap_);
+}
+
+void UIResourceLayer::SetBitmap(const SkBitmap& skbitmap) {
+ bitmap_ = skbitmap;
+
+ RecreateUIResourceHolder();
+ SetNeedsCommit();
+}
+
+void UIResourceLayer::SetUIResourceId(UIResourceId resource_id) {
+ if (ui_resource_holder_ && ui_resource_holder_->id() == resource_id)
+ return;
+
+ if (resource_id) {
+ ui_resource_holder_ = SharedUIResourceHolder::Create(resource_id);
+ } else {
+ ui_resource_holder_.reset();
+ }
+
+ SetNeedsCommit();
+}
+
+bool UIResourceLayer::DrawsContent() const {
+ return ui_resource_holder_ && ui_resource_holder_->id() &&
+ Layer::DrawsContent();
+}
+
+void UIResourceLayer::PushPropertiesTo(LayerImpl* layer) {
+ Layer::PushPropertiesTo(layer);
+ UIResourceLayerImpl* layer_impl = static_cast<UIResourceLayerImpl*>(layer);
+
+ if (!ui_resource_holder_) {
+ layer_impl->SetUIResourceId(0);
+ } else {
+ DCHECK(layer_tree_host());
+
+ gfx::Size image_size =
+ layer_tree_host()->GetUIResourceSize(ui_resource_holder_->id());
+ layer_impl->SetUIResourceId(ui_resource_holder_->id());
+ layer_impl->SetImageBounds(image_size);
+ }
+}
+
+} // namespace cc
diff --git a/cc/layers/ui_resource_layer.h b/cc/layers/ui_resource_layer.h
new file mode 100644
index 0000000..173ca44
--- /dev/null
+++ b/cc/layers/ui_resource_layer.h
@@ -0,0 +1,59 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_LAYERS_UI_RESOURCE_LAYER_H_
+#define CC_LAYERS_UI_RESOURCE_LAYER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+#include "cc/layers/layer.h"
+#include "cc/resources/ui_resource_client.h"
+#include "ui/gfx/rect.h"
+
+namespace cc {
+
+class LayerTreeHost;
+class ScopedUIResource;
+
+class CC_EXPORT UIResourceLayer : public Layer {
+ public:
+ static scoped_refptr<UIResourceLayer> Create();
+
+ virtual bool DrawsContent() const OVERRIDE;
+
+ virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE;
+
+ virtual void SetLayerTreeHost(LayerTreeHost* host) OVERRIDE;
+
+ void SetBitmap(const SkBitmap& skbitmap);
+
+ // An alternative way of setting the resource to allow for sharing.
+ void SetUIResourceId(UIResourceId resource_id);
+
+ class UIResourceHolder {
+ public:
+ virtual UIResourceId id() = 0;
+ virtual ~UIResourceHolder();
+ };
+
+ protected:
+ UIResourceLayer();
+ virtual ~UIResourceLayer();
+
+ scoped_ptr<UIResourceHolder> ui_resource_holder_;
+ SkBitmap bitmap_;
+
+ private:
+ virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
+ OVERRIDE;
+ void RecreateUIResourceHolder();
+
+
+
+ DISALLOW_COPY_AND_ASSIGN(UIResourceLayer);
+};
+
+} // namespace cc
+
+#endif // CC_LAYERS_UI_RESOURCE_LAYER_H_
diff --git a/cc/layers/ui_resource_layer_impl.cc b/cc/layers/ui_resource_layer_impl.cc
new file mode 100644
index 0000000..cb4d975
--- /dev/null
+++ b/cc/layers/ui_resource_layer_impl.cc
@@ -0,0 +1,121 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/ui_resource_layer_impl.h"
+
+#include "base/strings/stringprintf.h"
+#include "base/values.h"
+#include "cc/base/math_util.h"
+#include "cc/layers/quad_sink.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "cc/trees/layer_tree_impl.h"
+#include "ui/gfx/rect_f.h"
+
+namespace cc {
+
+UIResourceLayerImpl::UIResourceLayerImpl(LayerTreeImpl* tree_impl, int id)
+ : LayerImpl(tree_impl, id),
+ ui_resource_id_(0) {}
+
+UIResourceLayerImpl::~UIResourceLayerImpl() {}
+
+scoped_ptr<LayerImpl> UIResourceLayerImpl::CreateLayerImpl(
+ LayerTreeImpl* tree_impl) {
+ return UIResourceLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
+}
+
+void UIResourceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
+ LayerImpl::PushPropertiesTo(layer);
+ UIResourceLayerImpl* layer_impl = static_cast<UIResourceLayerImpl*>(layer);
+
+ layer_impl->SetUIResourceId(ui_resource_id_);
+ layer_impl->SetImageBounds(image_bounds_);
+}
+
+void UIResourceLayerImpl::SetUIResourceId(UIResourceId uid) {
+ if (uid == ui_resource_id_)
+ return;
+ ui_resource_id_ = uid;
+ NoteLayerPropertyChanged();
+}
+
+void UIResourceLayerImpl::SetImageBounds(gfx::Size image_bounds) {
+ // This check imposes an ordering on the call sequence. An UIResource must
+ // exist before SetImageBounds can be called.
+ DCHECK(ui_resource_id_);
+
+ if (image_bounds_ == image_bounds)
+ return;
+
+ image_bounds_ = image_bounds;
+
+ NoteLayerPropertyChanged();
+}
+
+bool UIResourceLayerImpl::WillDraw(DrawMode draw_mode,
+ ResourceProvider* resource_provider) {
+ if (!ui_resource_id_ || draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
+ return false;
+ return LayerImpl::WillDraw(draw_mode, resource_provider);
+}
+
+void UIResourceLayerImpl::AppendQuads(QuadSink* quad_sink,
+ AppendQuadsData* append_quads_data) {
+ SharedQuadState* shared_quad_state =
+ quad_sink->UseSharedQuadState(CreateSharedQuadState());
+ AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
+
+ if (!ui_resource_id_)
+ return;
+
+ ResourceProvider::ResourceId resource =
+ layer_tree_impl()->ResourceIdForUIResource(ui_resource_id_);
+
+ if (!resource)
+ return;
+
+ static const bool flipped = false;
+ static const bool premultiplied_alpha = true;
+
+ DCHECK(!bounds().IsEmpty());
+
+ // TODO(clholgat): Properly calculate opacity: crbug.com/300027
+ gfx::Rect opaque_rect;
+ if (contents_opaque())
+ opaque_rect = gfx::Rect(bounds());
+
+ gfx::Rect quad_rect(bounds());
+ gfx::Rect uv_top_left(0.f, 0.f);
+ gfx::Rect uv_bottom_right(1.f, 1.f);
+
+ const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ scoped_ptr<TextureDrawQuad> quad;
+
+ quad = TextureDrawQuad::Create();
+ quad->SetNew(shared_quad_state,
+ quad_rect,
+ opaque_rect,
+ resource,
+ premultiplied_alpha,
+ uv_top_left.origin(),
+ uv_bottom_right.bottom_right(),
+ SK_ColorTRANSPARENT,
+ vertex_opacity,
+ flipped);
+ quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
+}
+
+const char* UIResourceLayerImpl::LayerTypeAsString() const {
+ return "cc::UIResourceLayerImpl";
+}
+
+base::DictionaryValue* UIResourceLayerImpl::LayerTreeAsJson() const {
+ base::DictionaryValue* result = LayerImpl::LayerTreeAsJson();
+
+ result->Set("ImageBounds", MathUtil::AsValue(image_bounds_).release());
+
+ return result;
+}
+
+} // namespace cc
diff --git a/cc/layers/ui_resource_layer_impl.h b/cc/layers/ui_resource_layer_impl.h
new file mode 100644
index 0000000..4c1ffb6
--- /dev/null
+++ b/cc/layers/ui_resource_layer_impl.h
@@ -0,0 +1,62 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_LAYERS_UI_RESOURCE_LAYER_IMPL_H_
+#define CC_LAYERS_UI_RESOURCE_LAYER_IMPL_H_
+
+#include <string>
+
+#include "cc/base/cc_export.h"
+#include "cc/layers/layer_impl.h"
+#include "cc/resources/resource_provider.h"
+#include "cc/resources/ui_resource_client.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace cc {
+
+class CC_EXPORT UIResourceLayerImpl : public LayerImpl {
+ public:
+ static scoped_ptr<UIResourceLayerImpl> Create(LayerTreeImpl* tree_impl,
+ int id) {
+ return make_scoped_ptr(new UIResourceLayerImpl(tree_impl, id));
+ }
+ virtual ~UIResourceLayerImpl();
+
+ void SetUIResourceId(UIResourceId uid);
+
+ void SetImageBounds(gfx::Size image_bounds);
+
+ virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
+ OVERRIDE;
+ virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE;
+
+ virtual bool WillDraw(DrawMode draw_mode,
+ ResourceProvider* resource_provider) OVERRIDE;
+ virtual void AppendQuads(QuadSink* quad_sink,
+ AppendQuadsData* append_quads_data) OVERRIDE;
+
+ virtual base::DictionaryValue* LayerTreeAsJson() const OVERRIDE;
+
+ protected:
+ UIResourceLayerImpl(LayerTreeImpl* tree_impl, int id);
+
+ // The size of the resource bitmap in pixels.
+ gfx::Size image_bounds_;
+
+ UIResourceId ui_resource_id_;
+
+ private:
+ virtual const char* LayerTypeAsString() const OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(UIResourceLayerImpl);
+};
+
+} // namespace cc
+
+#endif // CC_LAYERS_UI_RESOURCE_LAYER_IMPL_H_
diff --git a/cc/layers/ui_resource_layer_impl_unittest.cc b/cc/layers/ui_resource_layer_impl_unittest.cc
new file mode 100644
index 0000000..383b8a3
--- /dev/null
+++ b/cc/layers/ui_resource_layer_impl_unittest.cc
@@ -0,0 +1,123 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/append_quads_data.h"
+#include "cc/layers/ui_resource_layer_impl.h"
+#include "cc/resources/ui_resource_bitmap.h"
+#include "cc/resources/ui_resource_client.h"
+#include "cc/test/fake_impl_proxy.h"
+#include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/fake_ui_resource_layer_tree_host_impl.h"
+#include "cc/test/layer_test_common.h"
+#include "cc/test/mock_quad_culler.h"
+#include "cc/trees/single_thread_proxy.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/transform.h"
+
+namespace cc {
+namespace {
+
+scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer(
+ FakeUIResourceLayerTreeHostImpl* host_impl,
+ gfx::Size bitmap_size,
+ gfx::Size layer_size,
+ UIResourceId uid) {
+ gfx::Rect visible_content_rect(layer_size);
+ scoped_ptr<UIResourceLayerImpl> layer =
+ UIResourceLayerImpl::Create(host_impl->active_tree(), 1);
+ layer->draw_properties().visible_content_rect = visible_content_rect;
+ layer->SetBounds(layer_size);
+ layer->SetContentBounds(layer_size);
+ layer->CreateRenderSurface();
+ layer->draw_properties().render_target = layer.get();
+
+ SkBitmap skbitmap;
+ skbitmap.setConfig(
+ SkBitmap::kARGB_8888_Config, bitmap_size.width(), bitmap_size.height());
+ skbitmap.allocPixels();
+ skbitmap.setImmutable();
+ UIResourceBitmap bitmap(skbitmap);
+
+ host_impl->CreateUIResource(uid, bitmap);
+ layer->SetUIResourceId(uid);
+
+ return layer.Pass();
+}
+
+void QuadSizeTest(scoped_ptr<UIResourceLayerImpl> layer,
+ size_t expected_quad_size) {
+ MockQuadCuller quad_culler;
+ AppendQuadsData data;
+ layer->AppendQuads(&quad_culler, &data);
+
+ // Verify quad rects
+ const QuadList& quads = quad_culler.quad_list();
+ EXPECT_EQ(expected_quad_size, quads.size());
+}
+
+TEST(UIResourceLayerImplTest, VerifyDrawQuads) {
+ FakeImplProxy proxy;
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy);
+ // Make sure we're appending quads when there are valid values.
+ gfx::Size bitmap_size(100, 100);
+ gfx::Size layer_size(100, 100);;
+ size_t expected_quad_size = 1;
+ UIResourceId uid = 1;
+ scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl,
+ bitmap_size,
+ layer_size,
+ uid);
+ QuadSizeTest(layer.Pass(), expected_quad_size);
+
+ // Make sure we're not appending quads when there are invalid values.
+ expected_quad_size = 0;
+ uid = 0;
+ layer = GenerateUIResourceLayer(&host_impl,
+ bitmap_size,
+ layer_size,
+ uid);
+ QuadSizeTest(layer.Pass(), expected_quad_size);
+}
+
+void OpaqueBoundsTest(scoped_ptr<UIResourceLayerImpl> layer,
+ gfx::Rect expected_opaque_bounds) {
+ MockQuadCuller quad_culler;
+ AppendQuadsData data;
+ layer->AppendQuads(&quad_culler, &data);
+
+ // Verify quad rects
+ const QuadList& quads = quad_culler.quad_list();
+ EXPECT_GE(quads.size(), (size_t)0);
+ gfx::Rect opaque_rect = quads.at(0)->opaque_rect;
+ EXPECT_EQ(expected_opaque_bounds, opaque_rect);
+}
+
+TEST(UIResourceLayerImplTest, VerifyOpaqueBounds) {
+ FakeImplProxy proxy;
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy);
+
+ gfx::Size bitmap_size(100, 100);
+ gfx::Size layer_size(100, 100);;
+ UIResourceId uid = 1;
+ scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl,
+ bitmap_size,
+ layer_size,
+ uid);
+ layer->SetContentsOpaque(false);
+ gfx::Rect expected_opaque_bounds;
+ OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds);
+
+ layer = GenerateUIResourceLayer(&host_impl,
+ bitmap_size,
+ layer_size,
+ uid);
+
+ layer->SetContentsOpaque(true);
+ expected_opaque_bounds = gfx::Rect(layer->bounds());
+ OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds);
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/layers/ui_resource_layer_unittest.cc b/cc/layers/ui_resource_layer_unittest.cc
new file mode 100644
index 0000000..1720b81
--- /dev/null
+++ b/cc/layers/ui_resource_layer_unittest.cc
@@ -0,0 +1,122 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/ui_resource_layer.h"
+
+#include "cc/debug/overdraw_metrics.h"
+#include "cc/resources/prioritized_resource_manager.h"
+#include "cc/resources/resource_provider.h"
+#include "cc/resources/resource_update_queue.h"
+#include "cc/resources/scoped_ui_resource.h"
+#include "cc/scheduler/texture_uploader.h"
+#include "cc/test/fake_layer_tree_host_client.h"
+#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/geometry_test_utils.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/occlusion_tracker.h"
+#include "cc/trees/single_thread_proxy.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+using ::testing::Mock;
+using ::testing::_;
+using ::testing::AtLeast;
+using ::testing::AnyNumber;
+
+namespace cc {
+namespace {
+
+class MockLayerTreeHost : public LayerTreeHost {
+ public:
+ explicit MockLayerTreeHost(LayerTreeHostClient* client)
+ : LayerTreeHost(client, LayerTreeSettings()) {
+ Initialize(NULL);
+ }
+};
+
+class UIResourceLayerTest : public testing::Test {
+ public:
+ UIResourceLayerTest() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {}
+
+ cc::Proxy* Proxy() const { return layer_tree_host_->proxy(); }
+
+ protected:
+ virtual void SetUp() {
+ layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
+ }
+
+ virtual void TearDown() {
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get());
+ }
+
+ scoped_ptr<MockLayerTreeHost> layer_tree_host_;
+ FakeLayerTreeHostClient fake_client_;
+};
+
+TEST_F(UIResourceLayerTest, SetBitmap) {
+ scoped_refptr<UIResourceLayer> test_layer = UIResourceLayer::Create();
+ ASSERT_TRUE(test_layer.get());
+ test_layer->SetIsDrawable(true);
+ test_layer->SetBounds(gfx::Size(100, 100));
+
+ layer_tree_host_->SetRootLayer(test_layer);
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get());
+ EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
+
+ layer_tree_host_->InitializeOutputSurfaceIfNeeded();
+
+ ResourceUpdateQueue queue;
+ OcclusionTracker occlusion_tracker(gfx::Rect(), false);
+ test_layer->SavePaintProperties();
+ test_layer->Update(&queue, &occlusion_tracker);
+
+ EXPECT_FALSE(test_layer->DrawsContent());
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
+ bitmap.allocPixels();
+ bitmap.setImmutable();
+
+ test_layer->SetBitmap(bitmap);
+ test_layer->Update(&queue, &occlusion_tracker);
+
+ EXPECT_TRUE(test_layer->DrawsContent());
+}
+
+TEST_F(UIResourceLayerTest, SetUIResourceId) {
+ scoped_refptr<UIResourceLayer> test_layer = UIResourceLayer::Create();
+ ASSERT_TRUE(test_layer.get());
+ test_layer->SetIsDrawable(true);
+ test_layer->SetBounds(gfx::Size(100, 100));
+
+ layer_tree_host_->SetRootLayer(test_layer);
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get());
+ EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
+
+ layer_tree_host_->InitializeOutputSurfaceIfNeeded();
+
+ ResourceUpdateQueue queue;
+ OcclusionTracker occlusion_tracker(gfx::Rect(), false);
+ test_layer->SavePaintProperties();
+ test_layer->Update(&queue, &occlusion_tracker);
+
+ EXPECT_FALSE(test_layer->DrawsContent());
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
+ bitmap.allocPixels();
+ bitmap.setImmutable();
+
+ scoped_ptr<ScopedUIResource> resource = ScopedUIResource::Create(
+ layer_tree_host_.get(), UIResourceBitmap(bitmap));
+ test_layer->SetUIResourceId(resource->id());
+ test_layer->Update(&queue, &occlusion_tracker);
+
+ EXPECT_TRUE(test_layer->DrawsContent());
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/test/fake_ui_resource_layer_tree_host_impl.cc b/cc/test/fake_ui_resource_layer_tree_host_impl.cc
new file mode 100644
index 0000000..ec087f2
--- /dev/null
+++ b/cc/test/fake_ui_resource_layer_tree_host_impl.cc
@@ -0,0 +1,39 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/test/fake_ui_resource_layer_tree_host_impl.h"
+
+#include "cc/test/fake_layer_tree_host_impl.h"
+
+namespace cc {
+
+FakeUIResourceLayerTreeHostImpl::FakeUIResourceLayerTreeHostImpl(Proxy* proxy)
+ : FakeLayerTreeHostImpl(proxy), fake_next_resource_id_(1) {}
+
+FakeUIResourceLayerTreeHostImpl::~FakeUIResourceLayerTreeHostImpl() {}
+
+void FakeUIResourceLayerTreeHostImpl::CreateUIResource(
+ UIResourceId uid,
+ const UIResourceBitmap& bitmap) {
+ if (ResourceIdForUIResource(uid))
+ DeleteUIResource(uid);
+ fake_ui_resource_map_[uid] = fake_next_resource_id_;
+}
+
+void FakeUIResourceLayerTreeHostImpl::DeleteUIResource(UIResourceId uid) {
+ ResourceProvider::ResourceId id = ResourceIdForUIResource(uid);
+ if (id)
+ fake_ui_resource_map_.erase(uid);
+}
+
+ResourceProvider::ResourceId
+ FakeUIResourceLayerTreeHostImpl::ResourceIdForUIResource(
+ UIResourceId uid) const {
+ UIResourceMap::const_iterator iter = fake_ui_resource_map_.find(uid);
+ if (iter != fake_ui_resource_map_.end())
+ return iter->second;
+ return 0;
+}
+
+} // namespace cc
diff --git a/cc/test/fake_ui_resource_layer_tree_host_impl.h b/cc/test/fake_ui_resource_layer_tree_host_impl.h
new file mode 100644
index 0000000..eceece9
--- /dev/null
+++ b/cc/test/fake_ui_resource_layer_tree_host_impl.h
@@ -0,0 +1,35 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TEST_FAKE_UI_RESOURCE_LAYER_TREE_HOST_IMPL_H_
+#define CC_TEST_FAKE_UI_RESOURCE_LAYER_TREE_HOST_IMPL_H_
+
+#include "base/containers/hash_tables.h"
+#include "cc/test/fake_layer_tree_host_impl.h"
+
+namespace cc {
+
+class FakeUIResourceLayerTreeHostImpl : public FakeLayerTreeHostImpl {
+ public:
+ explicit FakeUIResourceLayerTreeHostImpl(Proxy* proxy);
+ virtual ~FakeUIResourceLayerTreeHostImpl();
+
+ virtual void CreateUIResource(UIResourceId uid,
+ const UIResourceBitmap& bitmap) OVERRIDE;
+
+ virtual void DeleteUIResource(UIResourceId uid) OVERRIDE;
+
+ virtual ResourceProvider::ResourceId ResourceIdForUIResource(
+ UIResourceId uid) const OVERRIDE;
+
+ private:
+ ResourceProvider::ResourceId fake_next_resource_id_;
+ typedef base::hash_map<UIResourceId, ResourceProvider::ResourceId>
+ UIResourceMap;
+ UIResourceMap fake_ui_resource_map_;
+};
+
+} // namespace cc
+
+#endif // CC_TEST_FAKE_UI_RESOURCE_LAYER_TREE_HOST_IMPL_H_
diff --git a/cc/test/layer_tree_json_parser.cc b/cc/test/layer_tree_json_parser.cc
index 1c47e1e..099e75f 100644
--- a/cc/test/layer_tree_json_parser.cc
+++ b/cc/test/layer_tree_json_parser.cc
@@ -70,7 +70,8 @@ scoped_refptr<Layer> ParseTreeFromValue(base::Value* val,
bitmap.setConfig(SkBitmap::kARGB_8888_Config, image_width, image_height);
bitmap.allocPixels(NULL, NULL);
bitmap.setImmutable();
- nine_patch_layer->SetBitmap(bitmap,
+ nine_patch_layer->SetBitmap(bitmap);
+ nine_patch_layer->SetAperture(
gfx::Rect(aperture_x, aperture_y, aperture_width, aperture_height));
nine_patch_layer->SetBorder(
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index c447177..7e20fe0 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2745,7 +2745,11 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
ResourceProvider::TextureUsageAny,
resource_provider_->best_texture_format());
- ui_resource_map_[uid] = id;
+ UIResourceData data;
+ data.resource_id = id;
+ data.size = bitmap.GetSize();
+
+ ui_resource_map_[uid] = data;
AutoLockUIResourceBitmap bitmap_lock(bitmap);
resource_provider_->SetPixels(id,
@@ -2773,7 +2777,7 @@ void LayerTreeHostImpl::EvictAllUIResources() {
iter != ui_resource_map_.end();
++iter) {
evicted_ui_resources_.insert(iter->first);
- resource_provider_->DeleteResource(iter->second);
+ resource_provider_->DeleteResource(iter->second.resource_id);
}
ui_resource_map_.clear();
@@ -2786,7 +2790,7 @@ ResourceProvider::ResourceId LayerTreeHostImpl::ResourceIdForUIResource(
UIResourceId uid) const {
UIResourceMap::const_iterator iter = ui_resource_map_.find(uid);
if (iter != ui_resource_map_.end())
- return iter->second;
+ return iter->second.resource_id;
return 0;
}
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index aabd0b5..b725ef4 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -399,6 +399,11 @@ class CC_EXPORT LayerTreeHostImpl
virtual ResourceProvider::ResourceId ResourceIdForUIResource(
UIResourceId uid) const;
+ struct UIResourceData {
+ ResourceProvider::ResourceId resource_id;
+ gfx::Size size;
+ };
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -484,7 +489,7 @@ class CC_EXPORT LayerTreeHostImpl
void MarkUIResourceNotEvicted(UIResourceId uid);
- typedef base::hash_map<UIResourceId, ResourceProvider::ResourceId>
+ typedef base::hash_map<UIResourceId, UIResourceData>
UIResourceMap;
UIResourceMap ui_resource_map_;
diff --git a/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.cc b/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.cc
index 0c64a06..80c643a 100644
--- a/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.cc
+++ b/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.cc
@@ -23,8 +23,35 @@ WebKit::WebLayer* WebNinePatchLayerImpl::layer() { return layer_.get(); }
void WebNinePatchLayerImpl::setBitmap(SkBitmap bitmap,
const WebKit::WebRect& aperture) {
- static_cast<cc::NinePatchLayer*>(layer_->layer())->SetBitmap(
- bitmap, gfx::Rect(aperture));
+ setBitmap(bitmap);
+ setAperture(aperture);
+ setBorder(WebKit::WebRect(aperture.x, aperture.y,
+ bitmap.width() - aperture.width,
+ bitmap.height() - aperture.height));
+}
+
+void WebNinePatchLayerImpl::setBitmap(SkBitmap bitmap) {
+ cc::NinePatchLayer* nine_patch =
+ static_cast<cc::NinePatchLayer*>(layer_->layer());
+ nine_patch->SetBitmap(bitmap);
+}
+
+void WebNinePatchLayerImpl::setAperture(const WebKit::WebRect& aperture) {
+ cc::NinePatchLayer* nine_patch =
+ static_cast<cc::NinePatchLayer*>(layer_->layer());
+ nine_patch->SetAperture(gfx::Rect(aperture));
+}
+
+void WebNinePatchLayerImpl::setBorder(const WebKit::WebRect& border) {
+ cc::NinePatchLayer* nine_patch =
+ static_cast<cc::NinePatchLayer*>(layer_->layer());
+ nine_patch->SetBorder(gfx::Rect(border));
+}
+
+void WebNinePatchLayerImpl::setFillCenter(bool fill_center) {
+ cc::NinePatchLayer* nine_patch =
+ static_cast<cc::NinePatchLayer*>(layer_->layer());
+ nine_patch->SetFillCenter(fill_center);
}
} // namespace webkit
diff --git a/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.h b/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.h
index 34c8eff..2a5720d 100644
--- a/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.h
+++ b/webkit/renderer/compositor_bindings/web_nine_patch_layer_impl.h
@@ -21,7 +21,14 @@ class WebNinePatchLayerImpl : public WebKit::WebNinePatchLayer {
// WebKit::WebNinePatchLayer implementation.
virtual WebKit::WebLayer* layer();
- virtual void setBitmap(SkBitmap, const WebKit::WebRect& aperture);
+
+ // TODO(ccameron): Remove setBitmap(SkBitmap, WebKit::WebRect) in favor of
+ // setBitmap(), setAperture(), and setBorder();
+ virtual void setBitmap(SkBitmap bitmap, const WebKit::WebRect& aperture);
+ virtual void setBitmap(SkBitmap bitmap);
+ virtual void setAperture(const WebKit::WebRect& aperture);
+ virtual void setBorder(const WebKit::WebRect& border);
+ virtual void setFillCenter(bool fill_center);
private:
scoped_ptr<WebLayerImpl> layer_;