summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/layers/nine_patch_layer.cc171
-rw-r--r--cc/layers/nine_patch_layer.h43
-rw-r--r--cc/layers/nine_patch_layer_impl.cc304
-rw-r--r--cc/layers/nine_patch_layer_impl.h42
-rw-r--r--cc/layers/nine_patch_layer_impl_unittest.cc199
-rw-r--r--cc/layers/nine_patch_layer_unittest.cc104
-rw-r--r--cc/layers/painted_scrollbar_layer.cc15
-rw-r--r--cc/layers/painted_scrollbar_layer.h4
-rw-r--r--cc/layers/scrollbar_layer_unittest.cc9
-rw-r--r--cc/resources/scoped_ui_resource.cc15
-rw-r--r--cc/resources/scoped_ui_resource.h25
-rw-r--r--cc/resources/ui_resource_bitmap.cc46
-rw-r--r--cc/resources/ui_resource_bitmap.h40
-rw-r--r--cc/resources/ui_resource_client.h4
-rw-r--r--cc/test/data/10_10_layer_tree.json364
-rw-r--r--cc/test/fake_scoped_ui_resource.cc29
-rw-r--r--cc/test/fake_scoped_ui_resource.h5
-rw-r--r--cc/test/layer_tree_json_parser.cc15
-rw-r--r--cc/trees/layer_tree_host.cc96
-rw-r--r--cc/trees/layer_tree_host.h37
-rw-r--r--cc/trees/layer_tree_host_impl.cc17
-rw-r--r--cc/trees/layer_tree_host_impl.h11
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc22
-rw-r--r--cc/trees/layer_tree_impl.cc6
-rw-r--r--cc/trees/layer_tree_impl.h2
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc24
-rw-r--r--content/browser/renderer_host/compositor_impl_android.h10
-rw-r--r--content/public/browser/android/compositor.h9
-rw-r--r--content/public/browser/android/compositor_client.h6
-rw-r--r--ui/gfx/android/java_bitmap.cc46
-rw-r--r--ui/gfx/android/java_bitmap.h2
31 files changed, 1099 insertions, 623 deletions
diff --git a/cc/layers/nine_patch_layer.cc b/cc/layers/nine_patch_layer.cc
index b500798..5e00007 100644
--- a/cc/layers/nine_patch_layer.cc
+++ b/cc/layers/nine_patch_layer.cc
@@ -8,16 +8,55 @@
#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 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());
}
-NinePatchLayer::NinePatchLayer()
- : bitmap_dirty_(false) {}
+NinePatchLayer::NinePatchLayer() : fill_center_(false) {}
NinePatchLayer::~NinePatchLayer() {}
@@ -26,96 +65,90 @@ scoped_ptr<LayerImpl> NinePatchLayer::CreateLayerImpl(
return NinePatchLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
}
-void NinePatchLayer::SetTexturePriorities(
- const PriorityCalculator& priority_calc) {
- if (resource_ && !resource_->texture()->resource_manager()) {
- // Release the resource here, as it is no longer tied to a resource manager.
- resource_.reset();
- if (!bitmap_.isNull())
- CreateResource();
- } else if (bitmap_dirty_ && DrawsContent()) {
- CreateResource();
- }
+void NinePatchLayer::SetLayerTreeHost(LayerTreeHost* host) {
+ if (host == layer_tree_host())
+ return;
- if (resource_) {
- resource_->texture()->set_request_priority(
- PriorityCalculator::UIPriority(true));
- resource_->texture()->SetDimensions(
- gfx::Size(bitmap_.width(), bitmap_.height()),
- layer_tree_host()->GetRendererCapabilities().best_texture_format);
- }
-}
+ Layer::SetLayerTreeHost(host);
-void NinePatchLayer::SetBitmap(const SkBitmap& bitmap, gfx::Rect aperture) {
- bitmap_ = bitmap;
- image_aperture_ = aperture;
- bitmap_dirty_ = true;
- SetNeedsDisplay();
+ // Recreate the resource hold against the new LTH.
+ RecreateUIResourceHolder();
}
-bool NinePatchLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker* occlusion) {
- bool updated = Layer::Update(queue, occlusion);
-
- CreateUpdaterIfNeeded();
-
- if (resource_ &&
- (bitmap_dirty_ || resource_->texture()->resource_id() == 0)) {
- gfx::Rect content_rect(0, 0, bitmap_.width(), bitmap_.height());
- ResourceUpdate upload = ResourceUpdate::Create(resource_->texture(),
- &bitmap_,
- content_rect,
- content_rect,
- gfx::Vector2d());
- queue->AppendFullUpload(upload);
- bitmap_dirty_ = false;
- updated = true;
- }
+void NinePatchLayer::RecreateUIResourceHolder() {
+ ui_resource_holder_.reset();
+ if (!layer_tree_host() || bitmap_.empty())
+ return;
- return updated;
+ ui_resource_holder_ =
+ ScopedUIResourceHolder::Create(layer_tree_host(), bitmap_);
}
-void NinePatchLayer::CreateUpdaterIfNeeded() {
- if (updater_.get())
+void NinePatchLayer::SetBorder(gfx::Rect border) {
+ if (border == border_)
return;
+ border_ = border;
+ SetNeedsCommit();
+}
- updater_ = ImageLayerUpdater::Create();
+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::CreateResource() {
- DCHECK(!bitmap_.isNull());
- CreateUpdaterIfNeeded();
- updater_->SetBitmap(bitmap_);
+void NinePatchLayer::SetUIResourceId(UIResourceId resource_id,
+ gfx::Rect aperture) {
+ if (ui_resource_holder_ && ui_resource_holder_->id() == resource_id &&
+ image_aperture_ == aperture)
+ return;
- if (!resource_) {
- resource_ = updater_->CreateResource(
- layer_tree_host()->contents_texture_manager());
+ image_aperture_ = aperture;
+ if (resource_id) {
+ ui_resource_holder_ = SharedUIResourceHolder::Create(resource_id);
+ } else {
+ ui_resource_holder_.reset();
}
+
+ SetNeedsCommit();
+}
+
+void NinePatchLayer::SetFillCenter(bool fill_center) {
+ if (fill_center_ == fill_center)
+ return;
+
+ fill_center_ = fill_center;
+ SetNeedsCommit();
}
bool NinePatchLayer::DrawsContent() const {
- bool draws = !bitmap_.isNull() &&
- Layer::DrawsContent() &&
- bitmap_.width() &&
- bitmap_.height();
- return draws;
+ return ui_resource_holder_ && ui_resource_holder_->id() &&
+ Layer::DrawsContent();
}
void NinePatchLayer::PushPropertiesTo(LayerImpl* layer) {
Layer::PushPropertiesTo(layer);
NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);
- if (resource_) {
- DCHECK(!bitmap_.isNull());
- layer_impl->SetResourceId(resource_->texture()->resource_id());
- layer_impl->SetLayout(
- gfx::Size(bitmap_.width(), bitmap_.height()), image_aperture_);
- }
+ if (!ui_resource_holder_) {
+ layer_impl->SetUIResourceId(0);
+ } else {
+ DCHECK(layer_tree_host());
- // NinePatchLayer must push properties every commit to make sure
- // NinePatchLayerImpl::resource_id_ is valid.
- // http://crbug.com/276482
- needs_push_properties_ = true;
+ 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_);
+ }
}
} // namespace cc
diff --git a/cc/layers/nine_patch_layer.h b/cc/layers/nine_patch_layer.h
index 35d0881..5880635 100644
--- a/cc/layers/nine_patch_layer.h
+++ b/cc/layers/nine_patch_layer.h
@@ -8,47 +8,60 @@
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/layers/layer.h"
-#include "cc/resources/image_layer_updater.h"
-#include "third_party/skia/include/core/SkBitmap.h"
+#include "cc/resources/ui_resource_client.h"
#include "ui/gfx/rect.h"
namespace cc {
-class ResourceUpdateQueue;
+class LayerTreeHost;
+class ScopedUIResource;
class CC_EXPORT NinePatchLayer : public Layer {
public:
static scoped_refptr<NinePatchLayer> Create();
virtual bool DrawsContent() const OVERRIDE;
- virtual void SetTexturePriorities(const PriorityCalculator& priority_calc)
- OVERRIDE;
- virtual bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker* occlusion) 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.
+ // |border.width()-border.x()| and |border.height()-border.y()| are the size
+ // of the right and bottom boundary, respectively.
+ void SetBorder(gfx::Rect border);
+
// aperture is in the pixel space of the bitmap resource and refers to
// the center patch of the ninepatch (which is unused in this
// implementation). We split off eight rects surrounding it and stick them
// 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& bitmap, gfx::Rect aperture);
+ 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 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();
- void CreateUpdaterIfNeeded();
- void CreateResource();
-
- scoped_refptr<ImageLayerUpdater> updater_;
- scoped_ptr<LayerUpdater::Resource> resource_;
-
+ gfx::Rect border_;
+ bool fill_center_;
+ scoped_ptr<UIResourceHolder> ui_resource_holder_;
SkBitmap bitmap_;
- bool bitmap_dirty_;
// 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 4274bf0..f609c3d 100644
--- a/cc/layers/nine_patch_layer_impl.cc
+++ b/cc/layers/nine_patch_layer_impl.cc
@@ -6,15 +6,18 @@
#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 {
NinePatchLayerImpl::NinePatchLayerImpl(LayerTreeImpl* tree_impl, int id)
: LayerImpl(tree_impl, id),
- resource_id_(0) {}
+ fill_center_(false),
+ ui_resource_id_(0) {}
NinePatchLayerImpl::~NinePatchLayerImpl() {}
@@ -31,11 +34,8 @@ void NinePatchLayerImpl::PushPropertiesTo(LayerImpl* layer) {
LayerImpl::PushPropertiesTo(layer);
NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);
- if (!resource_id_)
- return;
-
- layer_impl->SetResourceId(resource_id_);
- layer_impl->SetLayout(image_bounds_, image_aperture_);
+ layer_impl->SetUIResourceId(ui_resource_id_);
+ layer_impl->SetLayout(image_bounds_, image_aperture_, border_, fill_center_);
}
static gfx::RectF NormalizedRect(float x,
@@ -50,14 +50,64 @@ static gfx::RectF NormalizedRect(float x,
height / total_height);
}
-void NinePatchLayerImpl::SetLayout(gfx::Size image_bounds, gfx::Rect aperture) {
+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,
+ 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_);
+
+ // 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());
+
+ // 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);
+
+ // |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));
+
+ // 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 (!resource_id_ || draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
+ if (!ui_resource_id_ || draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
return false;
return LayerImpl::WillDraw(draw_mode, resource_provider);
}
@@ -68,7 +118,13 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad_sink->UseSharedQuadState(CreateSharedQuadState());
AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
- if (!resource_id_)
+ if (!ui_resource_id_)
+ return;
+
+ ResourceProvider::ResourceId resource =
+ layer_tree_impl()->ResourceIdForUIResource(ui_resource_id_);
+
+ if (!resource)
return;
static const bool flipped = false;
@@ -76,95 +132,106 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
DCHECK(!bounds().IsEmpty());
- // NinePatch border widths in bitmap pixel space
- int left_width = image_aperture_.x();
- int top_height = image_aperture_.y();
- int right_width = image_bounds_.width() - image_aperture_.right();
- int bottom_height = image_bounds_.height() - image_aperture_.bottom();
+ // NinePatch border widths in layer space.
+ int layer_left_width = border_.x();
+ int layer_top_height = border_.y();
+ int layer_right_width = border_.width() - layer_left_width;
+ int layer_bottom_height = border_.height() - layer_top_height;
- // If layer can't fit the corners, clip to show the outer edges of the
- // image.
- int corner_total_width = left_width + right_width;
- int middle_width = bounds().width() - corner_total_width;
- if (middle_width < 0) {
- float left_width_proportion =
- static_cast<float>(left_width) / corner_total_width;
- int left_width_crop = middle_width * left_width_proportion;
- left_width += left_width_crop;
- right_width = bounds().width() - left_width;
- middle_width = 0;
- }
- int corner_total_height = top_height + bottom_height;
- int middle_height = bounds().height() - corner_total_height;
- if (middle_height < 0) {
- float top_height_proportion =
- static_cast<float>(top_height) / corner_total_height;
- int top_height_crop = middle_height * top_height_proportion;
- top_height += top_height_crop;
- bottom_height = bounds().height() - top_height;
- middle_height = 0;
- }
+ int layer_middle_width = bounds().width() - border_.width();
+ int layer_middle_height = bounds().height() - border_.height();
// Patch positions in layer space
- gfx::Rect top_left(0, 0, left_width, top_height);
- gfx::Rect top_right(
- bounds().width() - right_width, 0, right_width, top_height);
- gfx::Rect bottom_left(
- 0, bounds().height() - bottom_height, left_width, bottom_height);
- gfx::Rect bottom_right(
- top_right.x(), bottom_left.y(), right_width, bottom_height);
- gfx::Rect top(top_left.right(), 0, middle_width, top_height);
- gfx::Rect left(0, top_left.bottom(), left_width, middle_height);
- gfx::Rect right(top_right.x(),
- top_right.bottom(),
- right_width,
- left.height());
- gfx::Rect bottom(top.x(), bottom_left.y(), top.width(), bottom_height);
-
- float img_width = image_bounds_.width();
- float img_height = image_bounds_.height();
-
+ gfx::Rect layer_top_left(0, 0, layer_left_width, layer_top_height);
+ gfx::Rect layer_top_right(bounds().width() - layer_right_width,
+ 0,
+ layer_right_width,
+ layer_top_height);
+ gfx::Rect layer_bottom_left(0,
+ bounds().height() - layer_bottom_height,
+ layer_left_width,
+ layer_bottom_height);
+ gfx::Rect layer_bottom_right(layer_top_right.x(),
+ layer_bottom_left.y(),
+ layer_right_width,
+ layer_bottom_height);
+ gfx::Rect layer_top(
+ layer_top_left.right(), 0, layer_middle_width, layer_top_height);
+ gfx::Rect layer_left(
+ 0, layer_top_left.bottom(), layer_left_width, layer_middle_height);
+ gfx::Rect layer_right(layer_top_right.x(),
+ layer_top_right.bottom(),
+ layer_right_width,
+ layer_left.height());
+ gfx::Rect layer_bottom(layer_top.x(),
+ layer_bottom_left.y(),
+ layer_top.width(),
+ layer_bottom_height);
+ gfx::Rect layer_center(layer_left_width,
+ layer_top_height,
+ layer_middle_width,
+ layer_middle_height);
+
+ // Note the following values are in image (bitmap) space.
+ float image_width = image_bounds_.width();
+ float image_height = image_bounds_.height();
+
+ int image_aperture_left_width = image_aperture_.x();
+ int image_aperture_top_height = image_aperture_.y();
+ int image_aperture_right_width = image_width - image_aperture_.right();
+ int image_aperture_bottom_height = image_height - image_aperture_.bottom();
// Patch positions in bitmap UV space (from zero to one)
gfx::RectF uv_top_left = NormalizedRect(0,
0,
- left_width,
- top_height,
- img_width,
- img_height);
- gfx::RectF uv_top_right = NormalizedRect(img_width - right_width,
- 0,
- right_width,
- top_height,
- img_width,
- img_height);
- gfx::RectF uv_bottom_left = NormalizedRect(0,
- img_height - bottom_height,
- left_width,
- bottom_height,
- img_width,
- img_height);
- gfx::RectF uv_bottom_right = NormalizedRect(img_width - right_width,
- img_height - bottom_height,
- right_width,
- bottom_height,
- img_width,
- img_height);
- gfx::RectF uv_top(uv_top_left.right(),
- 0,
- (img_width - left_width - right_width) / img_width,
- (top_height) / img_height);
+ image_aperture_left_width,
+ image_aperture_top_height,
+ image_width,
+ image_height);
+ gfx::RectF uv_top_right =
+ NormalizedRect(image_width - image_aperture_right_width,
+ 0,
+ image_aperture_right_width,
+ image_aperture_top_height,
+ image_width,
+ image_height);
+ gfx::RectF uv_bottom_left =
+ NormalizedRect(0,
+ image_height - image_aperture_bottom_height,
+ image_aperture_left_width,
+ image_aperture_bottom_height,
+ image_width,
+ image_height);
+ gfx::RectF uv_bottom_right =
+ NormalizedRect(image_width - image_aperture_right_width,
+ image_height - image_aperture_bottom_height,
+ image_aperture_right_width,
+ image_aperture_bottom_height,
+ image_width,
+ image_height);
+ gfx::RectF uv_top(
+ uv_top_left.right(),
+ 0,
+ (image_width - image_aperture_left_width - image_aperture_right_width) /
+ image_width,
+ (image_aperture_top_height) / image_height);
gfx::RectF uv_left(0,
- uv_top_left.bottom(),
- left_width / img_width,
- (img_height - top_height - bottom_height) / img_height);
+ uv_top_left.bottom(),
+ image_aperture_left_width / image_width,
+ (image_height - image_aperture_top_height -
+ image_aperture_bottom_height) /
+ image_height);
gfx::RectF uv_right(uv_top_right.x(),
- uv_top_right.bottom(),
- right_width / img_width,
- uv_left.height());
+ uv_top_right.bottom(),
+ image_aperture_right_width / image_width,
+ uv_left.height());
gfx::RectF uv_bottom(uv_top.x(),
- uv_bottom_left.y(),
- uv_top.width(),
- bottom_height / img_height);
+ uv_bottom_left.y(),
+ uv_top.width(),
+ image_aperture_bottom_height / image_height);
+ gfx::RectF uv_center(uv_top_left.right(),
+ uv_top_left.bottom(),
+ uv_top.width(),
+ uv_left.height());
// Nothing is opaque here.
// TODO(danakj): Should we look at the SkBitmaps to determine opaqueness?
@@ -174,9 +241,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- top_left,
+ layer_top_left,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_top_left.origin(),
uv_top_left.bottom_right(),
@@ -187,9 +254,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- top_right,
+ layer_top_right,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_top_right.origin(),
uv_top_right.bottom_right(),
@@ -200,9 +267,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- bottom_left,
+ layer_bottom_left,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_bottom_left.origin(),
uv_bottom_left.bottom_right(),
@@ -213,9 +280,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- bottom_right,
+ layer_bottom_right,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_bottom_right.origin(),
uv_bottom_right.bottom_right(),
@@ -226,9 +293,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- top,
+ layer_top,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_top.origin(),
uv_top.bottom_right(),
@@ -239,9 +306,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- left,
+ layer_left,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_left.origin(),
uv_left.bottom_right(),
@@ -252,9 +319,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- right,
+ layer_right,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_right.origin(),
uv_right.bottom_right(),
@@ -265,9 +332,9 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
quad = TextureDrawQuad::Create();
quad->SetNew(shared_quad_state,
- bottom,
+ layer_bottom,
opaque_rect,
- resource_id_,
+ resource,
premultiplied_alpha,
uv_bottom.origin(),
uv_bottom.bottom_right(),
@@ -275,10 +342,21 @@ void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
vertex_opacity,
flipped);
quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
-}
-void NinePatchLayerImpl::DidLoseOutputSurface() {
- resource_id_ = 0;
+ if (fill_center_) {
+ quad = TextureDrawQuad::Create();
+ quad->SetNew(shared_quad_state,
+ layer_center,
+ opaque_rect,
+ resource,
+ premultiplied_alpha,
+ uv_center.origin(),
+ uv_center.bottom_right(),
+ SK_ColorTRANSPARENT,
+ vertex_opacity,
+ flipped);
+ quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data);
+ }
}
const char* NinePatchLayerImpl::LayerTypeAsString() const {
@@ -295,10 +373,12 @@ base::DictionaryValue* NinePatchLayerImpl::LayerTreeAsJson() const {
list->AppendInteger(image_aperture_.size().height());
result->Set("ImageAperture", list);
- list = new base::ListValue;
- list->AppendInteger(image_bounds_.width());
- list->AppendInteger(image_bounds_.height());
- result->Set("ImageBounds", list);
+ result->Set("ImageBounds", MathUtil::AsValue(image_bounds_).release());
+ result->Set("Border", MathUtil::AsValue(border_).release());
+
+ base::FundamentalValue* fill_center =
+ base::Value::CreateBooleanValue(fill_center_);
+ result->Set("FillCenter", fill_center);
return result;
}
diff --git a/cc/layers/nine_patch_layer_impl.h b/cc/layers/nine_patch_layer_impl.h
index bc442d4..ba414ae 100644
--- a/cc/layers/nine_patch_layer_impl.h
+++ b/cc/layers/nine_patch_layer_impl.h
@@ -10,6 +10,7 @@
#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"
@@ -27,8 +28,37 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
}
virtual ~NinePatchLayerImpl();
- void SetResourceId(unsigned id) { resource_id_ = id; }
- void SetLayout(gfx::Size image_bounds, gfx::Rect aperture);
+
+ void SetUIResourceId(UIResourceId uid);
+
+ // The bitmap stretches out the bounds of the layer. The following picture
+ // illustrates the parameters associated with the dimensions.
+ //
+ // Layer space layout Bitmap space layout
+ //
+ // ------------------------ ~~~~~~~~~~ W ~~~~~~~~~~
+ // | : | : : |
+ // | C | : Y |
+ // | : | : : |
+ // | ------------ | :~~X~~------------ |
+ // | | | | : | : |
+ // | | | | : | : |
+ // |~~A~~| |~~B~~| H | Q |
+ // | | | | : | : |
+ // | ------------ | : ~~~~~P~~~~~ |
+ // | : | : |
+ // | D | : |
+ // | : | : |
+ // ------------------------ ------------------------
+ //
+ // |image_bounds| = (W, H)
+ // |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,
+ gfx::Rect border,
+ bool fill_center);
virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
OVERRIDE;
@@ -39,7 +69,6 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
virtual void AppendQuads(QuadSink* quad_sink,
AppendQuadsData* append_quads_data) OVERRIDE;
virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE;
- virtual void DidLoseOutputSurface() OVERRIDE;
virtual base::DictionaryValue* LayerTreeAsJson() const OVERRIDE;
@@ -56,7 +85,12 @@ class CC_EXPORT NinePatchLayerImpl : public LayerImpl {
// image space.
gfx::Rect image_aperture_;
- ResourceProvider::ResourceId resource_id_;
+ // An inset border that the patches will be mapped to.
+ gfx::Rect border_;
+
+ 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 1985bd4..0fbc645 100644
--- a/cc/layers/nine_patch_layer_impl_unittest.cc
+++ b/cc/layers/nine_patch_layer_impl_unittest.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <stdio.h>
-
+#include "base/containers/hash_tables.h"
#include "cc/layers/append_quads_data.h"
#include "cc/layers/nine_patch_layer_impl.h"
#include "cc/quads/texture_draw_quad.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/geometry_test_utils.h"
@@ -22,6 +23,40 @@
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()),
@@ -29,19 +64,21 @@ gfx::Rect ToRoundedIntRect(gfx::RectF rect_f) {
gfx::ToRoundedInt(rect_f.height()));
}
-TEST(NinePatchLayerImplTest, VerifyDrawQuads) {
- // Input is a 100x100 bitmap with a 40x50 aperture at x=20, y=30.
- // The bounds of the layer are set to 400x400, so the draw quads
- // generated should leave the border width (40) intact.
+void NinePatchLayerLayoutTest(gfx::Size bitmap_size,
+ gfx::Rect aperture_rect,
+ gfx::Size layer_size,
+ gfx::Rect border,
+ bool fill_center,
+ size_t expected_quad_size) {
MockQuadCuller quad_culler;
- gfx::Size bitmap_size(100, 100);
- gfx::Size layer_size(400, 400);
gfx::Rect visible_content_rect(layer_size);
- gfx::Rect aperture_rect(20, 30, 40, 50);
- gfx::Rect scaled_aperture_non_uniform(20, 30, 340, 350);
+ gfx::Rect expected_remaining(border.x(),
+ border.y(),
+ layer_size.width() - border.width(),
+ layer_size.height() - border.height());
FakeImplProxy proxy;
- FakeLayerTreeHostImpl host_impl(&proxy);
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy);
scoped_ptr<NinePatchLayerImpl> layer =
NinePatchLayerImpl::Create(host_impl.active_tree(), 1);
layer->draw_properties().visible_content_rect = visible_content_rect;
@@ -49,21 +86,26 @@ TEST(NinePatchLayerImplTest, VerifyDrawQuads) {
layer->SetContentBounds(layer_size);
layer->CreateRenderSurface();
layer->draw_properties().render_target = layer.get();
- layer->SetLayout(bitmap_size, aperture_rect);
- layer->SetResourceId(1);
- // This scale should not affect the generated quad geometry, but only
- // the shared draw transform.
- gfx::Transform transform;
- transform.Scale(10, 10);
- layer->draw_properties().target_space_transform = transform;
+ UIResourceId uid = 1;
+ 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);
+ layer->SetLayout(bitmap_size, aperture_rect, border, fill_center);
AppendQuadsData data;
layer->AppendQuads(&quad_culler, &data);
// Verify quad rects
const QuadList& quads = quad_culler.quad_list();
- EXPECT_EQ(8u, quads.size());
+ EXPECT_EQ(expected_quad_size, quads.size());
+
Region remaining(visible_content_rect);
for (size_t i = 0; i < quads.size(); ++i) {
DrawQuad* quad = quads[i];
@@ -71,12 +113,16 @@ TEST(NinePatchLayerImplTest, VerifyDrawQuads) {
EXPECT_TRUE(visible_content_rect.Contains(quad_rect)) << i;
EXPECT_TRUE(remaining.Contains(quad_rect)) << i;
- EXPECT_EQ(transform, quad->quadTransform());
remaining.Subtract(Region(quad_rect));
}
- EXPECT_RECT_EQ(scaled_aperture_non_uniform, remaining.bounds());
- Region scaled_aperture_region(scaled_aperture_non_uniform);
- EXPECT_EQ(scaled_aperture_region, remaining);
+
+ // Check if the left-over quad is the same size as the mapped aperture quad in
+ // layer space.
+ if (!fill_center) {
+ EXPECT_RECT_EQ(expected_remaining, gfx::ToEnclosedRect(remaining.bounds()));
+ } else {
+ EXPECT_TRUE(remaining.bounds().IsEmpty());
+ }
// Verify UV rects
gfx::Rect bitmap_rect(bitmap_size);
@@ -89,66 +135,59 @@ TEST(NinePatchLayerImplTest, VerifyDrawQuads) {
tex_rect.Scale(bitmap_size.width(), bitmap_size.height());
tex_remaining.Subtract(Region(ToRoundedIntRect(tex_rect)));
}
- EXPECT_RECT_EQ(aperture_rect, tex_remaining.bounds());
- Region aperture_region(aperture_rect);
- EXPECT_EQ(aperture_region, tex_remaining);
-}
-
-TEST(NinePatchLayerImplTest, VerifyDrawQuadsForSqueezedLayer) {
- // Test with a layer much smaller than the bitmap.
- MockQuadCuller quad_culler;
- gfx::Size bitmap_size(101, 101);
- gfx::Size layer_size(51, 51);
- gfx::Rect visible_content_rect(layer_size);
- gfx::Rect aperture_rect(20, 30, 40, 45); // rightWidth: 40, botHeight: 25
-
- FakeImplProxy proxy;
- FakeLayerTreeHostImpl host_impl(&proxy);
- scoped_ptr<NinePatchLayerImpl> layer =
- NinePatchLayerImpl::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();
- layer->SetLayout(bitmap_size, aperture_rect);
- layer->SetResourceId(1);
- AppendQuadsData data;
- layer->AppendQuads(&quad_culler, &data);
-
- // Verify corner rects fill the layer and don't overlap
- const QuadList& quads = quad_culler.quad_list();
- EXPECT_EQ(4u, quads.size());
- Region filled;
- for (size_t i = 0; i < quads.size(); ++i) {
- DrawQuad* quad = quads[i];
- gfx::Rect quad_rect = quad->rect;
-
- EXPECT_FALSE(filled.Intersects(quad_rect));
- filled.Union(quad_rect);
+ if (!fill_center) {
+ EXPECT_RECT_EQ(aperture_rect, tex_remaining.bounds());
+ Region aperture_region(aperture_rect);
+ EXPECT_EQ(aperture_region, tex_remaining);
+ } else {
+ EXPECT_TRUE(remaining.bounds().IsEmpty());
}
- Region expected_full(visible_content_rect);
- EXPECT_EQ(expected_full, filled);
+}
- // Verify UV rects cover the corners of the bitmap and the crop is weighted
- // proportionately to the relative corner sizes (for uneven apertures).
- gfx::Rect bitmap_rect(bitmap_size);
- Region tex_remaining(bitmap_rect);
- for (size_t i = 0; i < quads.size(); ++i) {
- DrawQuad* quad = quads[i];
- const TextureDrawQuad* tex_quad = TextureDrawQuad::MaterialCast(quad);
- gfx::RectF tex_rect =
- gfx::BoundingRect(tex_quad->uv_top_left, tex_quad->uv_bottom_right);
- tex_rect.Scale(bitmap_size.width(), bitmap_size.height());
- tex_remaining.Subtract(Region(ToRoundedIntRect(tex_rect)));
- }
- Region expected_remaining_region = Region(gfx::Rect(bitmap_size));
- expected_remaining_region.Subtract(gfx::Rect(0, 0, 17, 28));
- expected_remaining_region.Subtract(gfx::Rect(67, 0, 34, 28));
- expected_remaining_region.Subtract(gfx::Rect(0, 78, 17, 23));
- expected_remaining_region.Subtract(gfx::Rect(67, 78, 34, 23));
- EXPECT_EQ(expected_remaining_region, tex_remaining);
+TEST(NinePatchLayerImplTest, VerifyDrawQuads) {
+ // Input is a 100x100 bitmap with a 40x50 aperture at x=20, y=30.
+ // The bounds of the layer are set to 400x400.
+ gfx::Size bitmap_size(100, 100);
+ gfx::Size layer_size(400, 500);
+ gfx::Rect aperture_rect(20, 30, 40, 50);
+ gfx::Rect border(40, 40, 80, 80);
+ bool fill_center = false;
+ size_t expected_quad_size = 8;
+ NinePatchLayerLayoutTest(bitmap_size,
+ aperture_rect,
+ layer_size,
+ border,
+ fill_center,
+ expected_quad_size);
+
+ // The bounds of the layer are set to less than the bitmap size.
+ bitmap_size = gfx::Size(100, 100);
+ layer_size = gfx::Size(40, 50);
+ aperture_rect = gfx::Rect(20, 30, 40, 50);
+ border = gfx::Rect(10, 10, 25, 15);
+ fill_center = true;
+ expected_quad_size = 9;
+ NinePatchLayerLayoutTest(bitmap_size,
+ aperture_rect,
+ layer_size,
+ border,
+ fill_center,
+ expected_quad_size);
+
+ // Layer and image sizes are equal.
+ bitmap_size = gfx::Size(100, 100);
+ layer_size = gfx::Size(100, 100);
+ aperture_rect = gfx::Rect(20, 30, 40, 50);
+ border = gfx::Rect(20, 30, 40, 50);
+ fill_center = true;
+ expected_quad_size = 9;
+ NinePatchLayerLayoutTest(bitmap_size,
+ aperture_rect,
+ layer_size,
+ border,
+ fill_center,
+ expected_quad_size);
}
} // namespace
diff --git a/cc/layers/nine_patch_layer_unittest.cc b/cc/layers/nine_patch_layer_unittest.cc
index 2e18808..101146c 100644
--- a/cc/layers/nine_patch_layer_unittest.cc
+++ b/cc/layers/nine_patch_layer_unittest.cc
@@ -8,6 +8,7 @@
#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"
@@ -55,7 +56,7 @@ class NinePatchLayerTest : public testing::Test {
FakeLayerTreeHostClient fake_client_;
};
-TEST_F(NinePatchLayerTest, TriggerFullUploadOnceWhenChangingBitmap) {
+TEST_F(NinePatchLayerTest, SetBitmap) {
scoped_refptr<NinePatchLayer> test_layer = NinePatchLayer::Create();
ASSERT_TRUE(test_layer.get());
test_layer->SetIsDrawable(true);
@@ -67,83 +68,60 @@ TEST_F(NinePatchLayerTest, TriggerFullUploadOnceWhenChangingBitmap) {
layer_tree_host_->InitializeOutputSurfaceIfNeeded();
- PriorityCalculator calculator;
ResourceUpdateQueue queue;
OcclusionTracker occlusion_tracker(gfx::Rect(), false);
-
- // No bitmap set should not trigger any uploads.
test_layer->SavePaintProperties();
- test_layer->SetTexturePriorities(calculator);
test_layer->Update(&queue, &occlusion_tracker);
- EXPECT_EQ(0u, queue.FullUploadSize());
- EXPECT_EQ(0u, queue.PartialUploadSize());
- // Setting a bitmap set should trigger a single full upload.
+ EXPECT_FALSE(test_layer->DrawsContent());
+
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
bitmap.allocPixels();
- test_layer->SetBitmap(bitmap, gfx::Rect(5, 5, 1, 1));
- test_layer->SavePaintProperties();
- test_layer->SetTexturePriorities(calculator);
+ 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_EQ(1u, queue.FullUploadSize());
- EXPECT_EQ(0u, queue.PartialUploadSize());
- ResourceUpdate params = queue.TakeFirstFullUpload();
- EXPECT_TRUE(params.texture != NULL);
-
- // Upload the texture.
- layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
- 1024 * 1024);
- layer_tree_host_->contents_texture_manager()->PrioritizeTextures();
-
- FakeOutputSurfaceClient output_surface_client;
- scoped_ptr<OutputSurface> output_surface;
- scoped_ptr<ResourceProvider> resource_provider;
- {
- DebugScopedSetImplThread impl_thread(Proxy());
- DebugScopedSetMainThreadBlocked main_thread_blocked(Proxy());
- output_surface = FakeOutputSurface::Create3d();
- CHECK(output_surface->BindToClient(&output_surface_client));
- resource_provider =
- ResourceProvider::Create(output_surface.get(), 0, false);
- params.texture->AcquireBackingTexture(resource_provider.get());
- ASSERT_TRUE(params.texture->have_backing_texture());
- }
- // Nothing changed, so no repeated upload.
+ EXPECT_TRUE(test_layer->DrawsContent());
+}
+
+TEST_F(NinePatchLayerTest, SetUIResourceId) {
+ 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->SetTexturePriorities(calculator);
test_layer->Update(&queue, &occlusion_tracker);
- EXPECT_EQ(0u, queue.FullUploadSize());
- EXPECT_EQ(0u, queue.PartialUploadSize());
- {
- DebugScopedSetImplThread impl_thread(Proxy());
- DebugScopedSetMainThreadBlocked main_thread_blocked(Proxy());
- layer_tree_host_->contents_texture_manager()->ClearAllMemory(
- resource_provider.get());
- }
- // Reupload after eviction
- test_layer->SavePaintProperties();
- test_layer->SetTexturePriorities(calculator);
+ 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));
+ gfx::Rect aperture(5, 5, 1, 1);
+ bool fill_center = true;
+ test_layer->SetUIResourceId(resource->id(), aperture);
+ test_layer->SetFillCenter(fill_center);
test_layer->Update(&queue, &occlusion_tracker);
- EXPECT_EQ(1u, queue.FullUploadSize());
- EXPECT_EQ(0u, queue.PartialUploadSize());
- // PrioritizedResourceManager clearing
- layer_tree_host_->contents_texture_manager()->UnregisterTexture(
- params.texture);
- EXPECT_EQ(NULL, params.texture->resource_manager());
- test_layer->SavePaintProperties();
- test_layer->SetTexturePriorities(calculator);
- ResourceUpdateQueue queue2;
- test_layer->Update(&queue2, &occlusion_tracker);
- EXPECT_EQ(1u, queue2.FullUploadSize());
- EXPECT_EQ(0u, queue2.PartialUploadSize());
- params = queue2.TakeFirstFullUpload();
- EXPECT_TRUE(params.texture != NULL);
- EXPECT_EQ(params.texture->resource_manager(),
- layer_tree_host_->contents_texture_manager());
+ EXPECT_TRUE(test_layer->DrawsContent());
}
} // namespace
diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc
index f5795de..4272fe6 100644
--- a/cc/layers/painted_scrollbar_layer.cc
+++ b/cc/layers/painted_scrollbar_layer.cc
@@ -210,20 +210,14 @@ bool PaintedScrollbarLayer::Update(ResourceUpdateQueue* queue,
return true;
}
-scoped_refptr<UIResourceBitmap> PaintedScrollbarLayer::RasterizeScrollbarPart(
+UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart(
gfx::Rect rect,
ScrollbarPart part) {
DCHECK(!rect.size().IsEmpty());
- scoped_refptr<UIResourceBitmap> bitmap =
- UIResourceBitmap::Create(new uint8_t[rect.width() * rect.height() * 4],
- UIResourceBitmap::RGBA8,
- UIResourceBitmap::CLAMP_TO_EDGE,
- rect.size());
-
SkBitmap skbitmap;
skbitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
- skbitmap.setPixels(bitmap->GetPixels());
+ skbitmap.allocPixels();
SkCanvas skcanvas(skbitmap);
skcanvas.translate(SkFloatToScalar(-rect.x()), SkFloatToScalar(-rect.y()));
@@ -240,8 +234,11 @@ scoped_refptr<UIResourceBitmap> PaintedScrollbarLayer::RasterizeScrollbarPart(
skcanvas.clipRect(layer_skrect);
scrollbar_->PaintPart(&skcanvas, part, layer_rect);
+ // Make sure that the pixels are no longer mutable to unavoid unnecessary
+ // allocation and copying.
+ skbitmap.setImmutable();
- return bitmap;
+ return UIResourceBitmap(skbitmap);
}
} // namespace cc
diff --git a/cc/layers/painted_scrollbar_layer.h b/cc/layers/painted_scrollbar_layer.h
index 8140f8c..e84377d 100644
--- a/cc/layers/painted_scrollbar_layer.h
+++ b/cc/layers/painted_scrollbar_layer.h
@@ -68,8 +68,8 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface,
int MaxTextureSize();
float ClampScaleToMaxTextureSize(float scale);
- scoped_refptr<UIResourceBitmap> RasterizeScrollbarPart(gfx::Rect rect,
- ScrollbarPart part);
+ UIResourceBitmap RasterizeScrollbarPart(gfx::Rect rect,
+ ScrollbarPart part);
scoped_ptr<Scrollbar> scrollbar_;
int scroll_layer_id_;
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index e62a032d..2e1b4b6 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -525,7 +525,8 @@ class MockLayerTreeHost : public LayerTreeHost {
virtual UIResourceId CreateUIResource(UIResourceClient* content) OVERRIDE {
total_ui_resource_created_++;
UIResourceId nid = next_id_++;
- ui_resource_bitmap_map_[nid] = content->GetBitmap(nid, false);
+ ui_resource_bitmap_map_.insert(
+ std::make_pair(nid, content->GetBitmap(nid, false)));
return nid;
}
@@ -544,13 +545,13 @@ class MockLayerTreeHost : public LayerTreeHost {
gfx::Size ui_resource_size(UIResourceId id) {
UIResourceBitmapMap::iterator iter = ui_resource_bitmap_map_.find(id);
- if (iter != ui_resource_bitmap_map_.end() && iter->second.get())
- return iter->second->GetSize();
+ if (iter != ui_resource_bitmap_map_.end())
+ return iter->second.GetSize();
return gfx::Size();
}
private:
- typedef base::hash_map<UIResourceId, scoped_refptr<UIResourceBitmap> >
+ typedef base::hash_map<UIResourceId, UIResourceBitmap>
UIResourceBitmapMap;
UIResourceBitmapMap ui_resource_bitmap_map_;
diff --git a/cc/resources/scoped_ui_resource.cc b/cc/resources/scoped_ui_resource.cc
index 0136a8e..e69b4bc 100644
--- a/cc/resources/scoped_ui_resource.cc
+++ b/cc/resources/scoped_ui_resource.cc
@@ -12,12 +12,12 @@ namespace cc {
scoped_ptr<ScopedUIResource> ScopedUIResource::Create(
LayerTreeHost* host,
- scoped_refptr<UIResourceBitmap> bitmap) {
+ const UIResourceBitmap& bitmap) {
return make_scoped_ptr(new ScopedUIResource(host, bitmap));
}
ScopedUIResource::ScopedUIResource(LayerTreeHost* host,
- scoped_refptr<UIResourceBitmap> bitmap)
+ const UIResourceBitmap& bitmap)
: bitmap_(bitmap), host_(host) {
DCHECK(host_);
id_ = host_->CreateUIResource(this);
@@ -32,16 +32,9 @@ ScopedUIResource::~ScopedUIResource() {
}
}
-gfx::Size ScopedUIResource::GetSize() const {
- return bitmap_->GetSize();
-}
-
-scoped_refptr<UIResourceBitmap> ScopedUIResource::GetBitmap(
- UIResourceId uid,
- bool resource_lost) {
+UIResourceBitmap ScopedUIResource::GetBitmap(UIResourceId uid,
+ bool resource_lost) {
return bitmap_;
}
-ScopedUIResource::ScopedUIResource() {}
-
} // namespace cc
diff --git a/cc/resources/scoped_ui_resource.h b/cc/resources/scoped_ui_resource.h
index a4525e6..c257e1e 100644
--- a/cc/resources/scoped_ui_resource.h
+++ b/cc/resources/scoped_ui_resource.h
@@ -15,28 +15,27 @@ namespace cc {
class LayerTreeHost;
+// ScopedUIResource creates an UIResource from a bitmap and a LayerTreeHost.
+// This class holds a pointer to the host so that when the instance goes out of
+// scope, the created resource is deleted. On a GetBitmap call from the
+// UIResource manager, ScopeUIResource always returns the reference to the
+// initially given bitmap regardless of whether the request was due to lost
+// resource or not.
class CC_EXPORT ScopedUIResource : public UIResourceClient {
public:
- static scoped_ptr<ScopedUIResource> Create(
- LayerTreeHost* host,
- scoped_refptr<UIResourceBitmap> bitmap);
+ static scoped_ptr<ScopedUIResource> Create(LayerTreeHost* host,
+ const UIResourceBitmap& bitmap);
virtual ~ScopedUIResource();
- gfx::Size GetSize() const;
-
// UIResourceClient implementation.
- virtual scoped_refptr<UIResourceBitmap> GetBitmap(
- UIResourceId uid,
- bool resource_lost) OVERRIDE;
+ virtual UIResourceBitmap GetBitmap(UIResourceId uid,
+ bool resource_lost) OVERRIDE;
UIResourceId id() { return id_; }
protected:
- ScopedUIResource(LayerTreeHost* host, scoped_refptr<UIResourceBitmap> bitmap);
-
- // An empty default contructor for testing.
- ScopedUIResource();
+ ScopedUIResource(LayerTreeHost* host, const UIResourceBitmap& bitmap);
- scoped_refptr<UIResourceBitmap> bitmap_;
+ UIResourceBitmap bitmap_;
LayerTreeHost* host_;
UIResourceId id_;
diff --git a/cc/resources/ui_resource_bitmap.cc b/cc/resources/ui_resource_bitmap.cc
index 1510607d..2acbd95 100644
--- a/cc/resources/ui_resource_bitmap.cc
+++ b/cc/resources/ui_resource_bitmap.cc
@@ -4,25 +4,45 @@
#include "cc/resources/ui_resource_bitmap.h"
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "third_party/skia/include/core/SkBitmap.h"
namespace cc {
-scoped_refptr<UIResourceBitmap>
-UIResourceBitmap::Create(uint8_t* pixels,
- UIResourceFormat format,
- UIResourceWrapMode wrap_mode,
- gfx::Size size) {
- scoped_refptr<UIResourceBitmap> ret = new UIResourceBitmap();
- ret->pixels_ = scoped_ptr<uint8_t[]>(pixels);
- ret->format_ = format;
- ret->wrap_mode_ = wrap_mode;
- ret->size_ = size;
-
- return ret;
+uint8_t* UIResourceBitmap::GetPixels() const {
+ if (!pixel_ref_)
+ return NULL;
+ return static_cast<uint8_t*>(pixel_ref_->pixels());
+}
+
+void UIResourceBitmap::Create(const skia::RefPtr<SkPixelRef>& pixel_ref,
+ UIResourceFormat format,
+ UIResourceWrapMode wrap_mode,
+ gfx::Size size) {
+ DCHECK(size.width());
+ DCHECK(size.height());
+ DCHECK(pixel_ref);
+ DCHECK(pixel_ref->isImmutable());
+ format_ = format;
+ wrap_mode_ = wrap_mode;
+ size_ = size;
+ pixel_ref_ = pixel_ref;
+}
+
+UIResourceBitmap::UIResourceBitmap(const SkBitmap& skbitmap,
+ UIResourceWrapMode wrap_mode) {
+ DCHECK_EQ(skbitmap.config(), SkBitmap::kARGB_8888_Config);
+ DCHECK_EQ(skbitmap.width(), skbitmap.rowBytesAsPixels());
+ DCHECK(skbitmap.isImmutable());
+
+ skia::RefPtr<SkPixelRef> pixel_ref = skia::SharePtr(skbitmap.pixelRef());
+ Create(pixel_ref,
+ UIResourceBitmap::RGBA8,
+ wrap_mode,
+ gfx::Size(skbitmap.width(), skbitmap.height()));
}
-UIResourceBitmap::UIResourceBitmap() {}
UIResourceBitmap::~UIResourceBitmap() {}
} // namespace cc
diff --git a/cc/resources/ui_resource_bitmap.h b/cc/resources/ui_resource_bitmap.h
index e1b5aee..f10fed9 100644
--- a/cc/resources/ui_resource_bitmap.h
+++ b/cc/resources/ui_resource_bitmap.h
@@ -8,16 +8,20 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
+#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
#include "third_party/skia/include/core/SkTypes.h"
#include "ui/gfx/size.h"
+class SkBitmap;
+
namespace cc {
-// Ref-counted bitmap class (can’t use SkBitmap because of ETC1). Thread-safety
-// ensures that both main and impl threads can hold references to the bitmap and
-// that asynchronous uploads are allowed.
-class CC_EXPORT UIResourceBitmap
- : public base::RefCountedThreadSafe<UIResourceBitmap> {
+// A bitmap class that contains a ref-counted reference to a SkPixelRef* that
+// holds the content of the bitmap (cannot use SkBitmap because of ETC1).
+// Thread-safety (by ways of SkPixelRef) ensures that both main and impl threads
+// can hold references to the bitmap and that asynchronous uploads are allowed.
+class CC_EXPORT UIResourceBitmap {
public:
enum UIResourceFormat {
RGBA8
@@ -27,29 +31,29 @@ class CC_EXPORT UIResourceBitmap
REPEAT
};
- // Takes ownership of “pixels”.
- static scoped_refptr<UIResourceBitmap> Create(uint8_t* pixels,
- UIResourceFormat format,
- UIResourceWrapMode wrap_mode,
- gfx::Size size);
-
gfx::Size GetSize() const { return size_; }
UIResourceFormat GetFormat() const { return format_; }
UIResourceWrapMode GetWrapMode() const { return wrap_mode_; }
- uint8_t* GetPixels() { return pixels_.get(); }
+ uint8_t* GetPixels() const;
- private:
- friend class base::RefCountedThreadSafe<UIResourceBitmap>;
+ // The constructor for the UIResourceBitmap. User must ensure that |skbitmap|
+ // is immutable. The SkBitmap format should be in 32-bit RGBA. Wrap mode is
+ // unnecessary for most UI resources and is defaulted to CLAMP_TO_EDGE.
+ UIResourceBitmap(const SkBitmap& skbitmap,
+ UIResourceWrapMode wrap_mode = CLAMP_TO_EDGE);
- UIResourceBitmap();
~UIResourceBitmap();
- scoped_ptr<uint8_t[]> pixels_;
+ private:
+ void Create(const skia::RefPtr<SkPixelRef>& pixel_ref,
+ UIResourceFormat format,
+ UIResourceWrapMode wrap_mode,
+ gfx::Size size);
+
+ skia::RefPtr<SkPixelRef> pixel_ref_;
UIResourceFormat format_;
UIResourceWrapMode wrap_mode_;
gfx::Size size_;
-
- DISALLOW_COPY_AND_ASSIGN(UIResourceBitmap);
};
} // namespace cc
diff --git a/cc/resources/ui_resource_client.h b/cc/resources/ui_resource_client.h
index d647936..24309a5 100644
--- a/cc/resources/ui_resource_client.h
+++ b/cc/resources/ui_resource_client.h
@@ -24,8 +24,8 @@ class CC_EXPORT UIResourceClient {
// delete a UIResourceClient object after DeleteUIResource has been called for
// all IDs associated with it. A valid bitmap always must be returned but it
// doesn't need to be the same size or format as the original.
- virtual scoped_refptr<UIResourceBitmap> GetBitmap(UIResourceId uid,
- bool resource_lost) = 0;
+ virtual UIResourceBitmap GetBitmap(UIResourceId uid,
+ bool resource_lost) = 0;
virtual ~UIResourceClient() {}
};
diff --git a/cc/test/data/10_10_layer_tree.json b/cc/test/data/10_10_layer_tree.json
index e2d7071..be624e5 100644
--- a/cc/test/data/10_10_layer_tree.json
+++ b/cc/test/data/10_10_layer_tree.json
@@ -14,21 +14,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, -55.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -52,21 +56,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 200, 200 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 7.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ -8.0, -8.0 ]
}, {
- "Bounds": [ 0, 0 ],
+ "Bounds": [ 4, 4 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 0.0, 0.0 ]
@@ -110,21 +118,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 51 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, -47.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -140,9 +152,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 15.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -150,11 +164,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 859.8399658203125, 23.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 38, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -206,21 +222,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 82 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, -5.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -236,9 +256,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 57.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -246,11 +268,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 859.8399658203125, 65.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -302,21 +326,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 110 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, 132.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -332,9 +360,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 194.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -342,11 +372,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 859.8399658203125, 202.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -398,21 +430,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 124 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, 356.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -428,9 +464,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 418.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -438,11 +476,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 859.8399658203125, 426.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -494,21 +534,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 124 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, 625.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -524,9 +568,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 687.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -534,11 +580,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 859.8399658203125, 695.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -590,19 +638,23 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 56 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, 894.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.024660587310791, 0.0, 0.0, 0.0, 0.0, 1.024660587310791, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 118.47874069213867, 149.62063217163086, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -620,9 +672,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 956.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -630,11 +684,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 859.8399658203125, 964.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -686,21 +742,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, 952.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -716,9 +776,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 1014.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -726,11 +788,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 384.8399658203125, 1001.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -774,21 +838,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, 960.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -804,9 +872,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 1022.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -814,11 +884,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 384.8399658203125, 951.828857421875, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -862,21 +934,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 568.0, 968.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -900,21 +976,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 620.0, 1030.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ -8.0, -8.0 ]
}, {
- "Bounds": [ 0, 0 ],
+ "Bounds": [ 3, 3 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 0.0, 0.0 ]
@@ -958,21 +1038,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, -55.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -996,9 +1080,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 7.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1006,11 +1092,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 15.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1054,21 +1142,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 45 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, -47.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1084,9 +1176,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 15.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1094,11 +1188,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 23.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1150,21 +1246,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 75 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, -25.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1180,9 +1280,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 37.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1190,11 +1292,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 45.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1246,21 +1350,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 103 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, 91.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1276,9 +1384,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 153.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1286,11 +1396,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 161.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1342,21 +1454,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 123 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, 295.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1372,9 +1488,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 357.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1382,11 +1500,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 365.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1438,21 +1558,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 124 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, 561.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1468,9 +1592,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 623.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1478,11 +1604,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 631.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1534,21 +1662,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 77 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, 830.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1580,9 +1712,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 892.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1590,11 +1724,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 900.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1646,21 +1782,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, 952.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1676,9 +1816,11 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 1014.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
@@ -1686,11 +1828,13 @@
"Position": [ -8.0, -8.0 ]
}, {
"Bounds": [ 306, 60 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 261.8399658203125, 1012.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 38, 0, 0, 0 ],
- "ImageBounds": [ 39, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 37, 1, 1, 1 ],
+ "ImageBounds": [ 39, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 231.8399658203125, 0.0 ]
@@ -1734,21 +1878,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, 960.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1764,21 +1912,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 1022.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ -8.0, -8.0 ]
}, {
- "Bounds": [ 0, 0 ],
+ "Bounds": [ 3, 3 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 0.0, 0.0 ]
@@ -1822,21 +1974,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 210, 40 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 3.125, 0.0, 0.0, 0.0, 0.0, 3.125, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -30.0, 968.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 32, 32, 0, 0 ],
+ "FillCenter": false,
+ "ImageAperture": [ 31, 31, 1, 1 ],
"ImageBounds": [ 33, 33 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.5,
"Position": [ -60.0, -70.0 ]
}, {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ -8.0, -8.0 ]
@@ -1852,21 +2008,25 @@
"Bounds": [ 0, 0 ],
"Children": [ {
"Bounds": [ 553, 791 ],
+ "Border": [ 1, 1, 20, 20 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 22.0, 1030.0, 0.0, 1.0 ],
"DrawsContent": true,
+ "FillCenter": false,
"ImageAperture": [ 17, 35, 2, 1 ],
"ImageBounds": [ 20, 37 ],
"LayerType": "NinePatchLayer",
"Opacity": 1.0,
"Position": [ -8.0, -8.0 ]
}, {
- "Bounds": [ 0, 0 ],
+ "Bounds": [ 3, 3 ],
+ "Border": [ 1, 1, 2, 2 ],
"Children": [ ],
"DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"DrawsContent": true,
- "ImageAperture": [ 0, 0, 0, 0 ],
- "ImageBounds": [ 1, 1 ],
+ "FillCenter": false,
+ "ImageAperture": [ 1, 1, 1, 1 ],
+ "ImageBounds": [ 3, 3 ],
"LayerType": "NinePatchLayer",
"Opacity": 0.0,
"Position": [ 0.0, 0.0 ]
diff --git a/cc/test/fake_scoped_ui_resource.cc b/cc/test/fake_scoped_ui_resource.cc
index ce5ee11..bf86f54 100644
--- a/cc/test/fake_scoped_ui_resource.cc
+++ b/cc/test/fake_scoped_ui_resource.cc
@@ -8,25 +8,34 @@
namespace cc {
+namespace {
+
+UIResourceBitmap CreateMockUIResourceBitmap() {
+ SkBitmap skbitmap;
+ skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
+ skbitmap.allocPixels();
+ skbitmap.setImmutable();
+ return UIResourceBitmap(skbitmap);
+}
+
+} // anonymous namespace
+
scoped_ptr<FakeScopedUIResource> FakeScopedUIResource::Create(
LayerTreeHost* host) {
return make_scoped_ptr(new FakeScopedUIResource(host));
}
-FakeScopedUIResource::FakeScopedUIResource(LayerTreeHost* host) {
+FakeScopedUIResource::FakeScopedUIResource(LayerTreeHost* host)
+ : ScopedUIResource(host, CreateMockUIResourceBitmap()) {
+ // The constructor of ScopedUIResource already created a resource so we need
+ // to delete the created resource to wipe the state clean.
+ host_->DeleteUIResource(id_);
ResetCounters();
- bitmap_ = UIResourceBitmap::Create(
- new uint8_t[1],
- UIResourceBitmap::RGBA8,
- UIResourceBitmap::CLAMP_TO_EDGE,
- gfx::Size(1, 1));
- host_ = host;
id_ = host_->CreateUIResource(this);
}
-scoped_refptr<UIResourceBitmap> FakeScopedUIResource::GetBitmap(
- UIResourceId uid,
- bool resource_lost) {
+UIResourceBitmap FakeScopedUIResource::GetBitmap(UIResourceId uid,
+ bool resource_lost) {
resource_create_count++;
if (resource_lost)
lost_resource_count++;
diff --git a/cc/test/fake_scoped_ui_resource.h b/cc/test/fake_scoped_ui_resource.h
index 84c097f..970d7b0 100644
--- a/cc/test/fake_scoped_ui_resource.h
+++ b/cc/test/fake_scoped_ui_resource.h
@@ -16,9 +16,8 @@ class FakeScopedUIResource : public ScopedUIResource {
public:
static scoped_ptr<FakeScopedUIResource> Create(LayerTreeHost* host);
- virtual scoped_refptr<UIResourceBitmap> GetBitmap(
- UIResourceId uid,
- bool resource_lost) OVERRIDE;
+ virtual UIResourceBitmap GetBitmap(UIResourceId uid,
+ bool resource_lost) OVERRIDE;
void ResetCounters();
int resource_create_count;
diff --git a/cc/test/layer_tree_json_parser.cc b/cc/test/layer_tree_json_parser.cc
index 51c421f..1c47e1e 100644
--- a/cc/test/layer_tree_json_parser.cc
+++ b/cc/test/layer_tree_json_parser.cc
@@ -54,14 +54,29 @@ scoped_refptr<Layer> ParseTreeFromValue(base::Value* val,
success &= list->GetInteger(0, &image_width);
success &= list->GetInteger(1, &image_height);
+ success &= dict->GetList("Border", &list);
+ int border_x, border_y, border_width, border_height;
+ success &= list->GetInteger(0, &border_x);
+ success &= list->GetInteger(1, &border_y);
+ success &= list->GetInteger(2, &border_width);
+ success &= list->GetInteger(3, &border_height);
+
+ bool fill_center;
+ success &= dict->GetBoolean("FillCenter", &fill_center);
+
scoped_refptr<NinePatchLayer> nine_patch_layer = NinePatchLayer::Create();
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, image_width, image_height);
bitmap.allocPixels(NULL, NULL);
+ bitmap.setImmutable();
nine_patch_layer->SetBitmap(bitmap,
gfx::Rect(aperture_x, aperture_y, aperture_width, aperture_height));
+ nine_patch_layer->SetBorder(
+ gfx::Rect(border_x, border_y, border_width, border_height));
+ nine_patch_layer->SetFillCenter(fill_center);
+
new_layer = nine_patch_layer;
} else if (layer_type == "PictureLayer") {
new_layer = PictureLayer::Create(content_client);
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 8afb592..7c06b96 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -61,8 +61,31 @@ RendererCapabilities::RendererCapabilities()
RendererCapabilities::~RendererCapabilities() {}
-UIResourceRequest::UIResourceRequest()
- : type(UIResourceInvalidRequest), id(0), bitmap(NULL) {}
+UIResourceRequest::UIResourceRequest(UIResourceRequestType type,
+ UIResourceId id)
+ : type_(type), id_(id) {}
+
+UIResourceRequest::UIResourceRequest(UIResourceRequestType type,
+ UIResourceId id,
+ const UIResourceBitmap& bitmap)
+ : type_(type), id_(id), bitmap_(new UIResourceBitmap(bitmap)) {}
+
+UIResourceRequest::UIResourceRequest(const UIResourceRequest& request) {
+ (*this) = request;
+}
+
+UIResourceRequest& UIResourceRequest::operator=(
+ const UIResourceRequest& request) {
+ type_ = request.type_;
+ id_ = request.id_;
+ if (request.bitmap_) {
+ bitmap_ = make_scoped_ptr(new UIResourceBitmap(*request.bitmap_.get()));
+ } else {
+ bitmap_.reset();
+ }
+
+ return *this;
+}
UIResourceRequest::~UIResourceRequest() {}
@@ -389,7 +412,7 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
if (overhang_ui_resource_) {
host_impl->SetOverhangUIResource(
overhang_ui_resource_->id(),
- overhang_ui_resource_->GetSize());
+ GetUIResourceSize(overhang_ui_resource_->id()));
}
DCHECK(!sync_tree->ViewportSizeInvalid());
@@ -647,16 +670,16 @@ void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
DCHECK(bitmap.width() && bitmap.height());
DCHECK_EQ(bitmap.bytesPerPixel(), 4);
- scoped_refptr<UIResourceBitmap> overhang_ui_bitmap(UIResourceBitmap::Create(
- new uint8_t[bitmap.width() * bitmap.height() * bitmap.bytesPerPixel()],
- UIResourceBitmap::RGBA8,
- UIResourceBitmap::REPEAT,
- gfx::Size(bitmap.width(), bitmap.height())));
- bitmap.copyPixelsTo(
- overhang_ui_bitmap->GetPixels(),
- bitmap.width() * bitmap.height() * bitmap.bytesPerPixel(),
- bitmap.width() * bitmap.bytesPerPixel());
- overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_ui_bitmap);
+ SkBitmap bitmap_copy;
+ if (bitmap.isImmutable()) {
+ bitmap_copy = bitmap;
+ } else {
+ bitmap.copyTo(&bitmap_copy, bitmap.config());
+ bitmap_copy.setImmutable();
+ }
+
+ overhang_ui_resource_ = ScopedUIResource::Create(
+ this, UIResourceBitmap(bitmap_copy, UIResourceBitmap::REPEAT));
}
void LayerTreeHost::SetVisible(bool visible) {
@@ -1162,18 +1185,22 @@ void LayerTreeHost::AnimateLayers(base::TimeTicks time) {
UIResourceId LayerTreeHost::CreateUIResource(UIResourceClient* client) {
DCHECK(client);
- UIResourceRequest request;
- bool resource_lost = false;
- request.type = UIResourceRequest::UIResourceCreate;
- request.id = next_ui_resource_id_++;
-
- DCHECK(ui_resource_client_map_.find(request.id) ==
+ UIResourceId next_id = next_ui_resource_id_++;
+ DCHECK(ui_resource_client_map_.find(next_id) ==
ui_resource_client_map_.end());
- request.bitmap = client->GetBitmap(request.id, resource_lost);
+ bool resource_lost = false;
+ UIResourceRequest request(UIResourceRequest::UIResourceCreate,
+ next_id,
+ client->GetBitmap(next_id, resource_lost));
ui_resource_request_queue_.push_back(request);
- ui_resource_client_map_[request.id] = client;
- return request.id;
+
+ UIResourceClientData data;
+ data.client = client;
+ data.size = request.GetBitmap().GetSize();
+
+ ui_resource_client_map_[request.GetId()] = data;
+ return request.GetId();
}
// Deletes a UI resource. May safely be called more than once.
@@ -1182,11 +1209,9 @@ void LayerTreeHost::DeleteUIResource(UIResourceId uid) {
if (iter == ui_resource_client_map_.end())
return;
- UIResourceRequest request;
- request.type = UIResourceRequest::UIResourceDelete;
- request.id = uid;
+ UIResourceRequest request(UIResourceRequest::UIResourceDelete, uid);
ui_resource_request_queue_.push_back(request);
- ui_resource_client_map_.erase(uid);
+ ui_resource_client_map_.erase(iter);
}
void LayerTreeHost::RecreateUIResources() {
@@ -1194,16 +1219,25 @@ void LayerTreeHost::RecreateUIResources() {
iter != ui_resource_client_map_.end();
++iter) {
UIResourceId uid = iter->first;
- UIResourceRequest request;
- request.type = UIResourceRequest::UIResourceCreate;
- request.id = uid;
+ const UIResourceClientData& data = iter->second;
bool resource_lost = true;
- request.bitmap = iter->second->GetBitmap(uid, resource_lost);
- DCHECK(request.bitmap.get());
+ UIResourceRequest request(UIResourceRequest::UIResourceCreate,
+ uid,
+ data.client->GetBitmap(uid, resource_lost));
ui_resource_request_queue_.push_back(request);
}
}
+// Returns the size of a resource given its id.
+gfx::Size LayerTreeHost::GetUIResourceSize(UIResourceId uid) const {
+ UIResourceClientMap::const_iterator iter = ui_resource_client_map_.find(uid);
+ if (iter == ui_resource_client_map_.end())
+ return gfx::Size();
+
+ const UIResourceClientData& data = iter->second;
+ return data.size;
+}
+
void LayerTreeHost::RegisterViewportLayers(
scoped_refptr<Layer> page_scale_layer,
scoped_refptr<Layer> inner_viewport_scroll_layer,
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index fff226a..e2e33d2 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -87,18 +87,35 @@ struct CC_EXPORT RendererCapabilities {
bool using_discard_framebuffer;
};
-struct CC_EXPORT UIResourceRequest {
+class CC_EXPORT UIResourceRequest {
+ public:
enum UIResourceRequestType {
UIResourceCreate,
UIResourceDelete,
UIResourceInvalidRequest
};
- UIResourceRequest();
+ UIResourceRequest(UIResourceRequestType type, UIResourceId id);
+ UIResourceRequest(UIResourceRequestType type,
+ UIResourceId id,
+ const UIResourceBitmap& bitmap);
+ UIResourceRequest(const UIResourceRequest& request);
+
~UIResourceRequest();
- UIResourceRequestType type;
- UIResourceId id;
- scoped_refptr<UIResourceBitmap> bitmap;
+
+ UIResourceRequestType GetType() const { return type_; }
+ UIResourceId GetId() const { return id_; }
+ UIResourceBitmap GetBitmap() const {
+ DCHECK(bitmap_);
+ return *bitmap_.get();
+ }
+
+ UIResourceRequest& operator=(const UIResourceRequest& request);
+
+ private:
+ UIResourceRequestType type_;
+ UIResourceId id_;
+ scoped_ptr<UIResourceBitmap> bitmap_;
};
class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
@@ -295,6 +312,8 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
// were evicted on the impl thread.
void RecreateUIResources();
+ virtual gfx::Size GetUIResourceSize(UIResourceId id) const;
+
bool UsingSharedMemoryResources();
int id() const { return tree_id_; }
@@ -331,7 +350,13 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
bool AnimateLayersRecursive(Layer* current, base::TimeTicks time);
- typedef base::hash_map<UIResourceId, UIResourceClient*> UIResourceClientMap;
+ struct UIResourceClientData {
+ UIResourceClient* client;
+ gfx::Size size;
+ };
+
+ typedef base::hash_map<UIResourceId, UIResourceClientData>
+ UIResourceClientMap;
UIResourceClientMap ui_resource_client_map_;
int next_ui_resource_id_;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 3a95b5b..97ceea5 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2629,14 +2629,13 @@ void LayerTreeHostImpl::SetDebugState(
SetFullRootLayerDamage();
}
-void LayerTreeHostImpl::CreateUIResource(
- UIResourceId uid,
- scoped_refptr<UIResourceBitmap> bitmap) {
+void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
+ const UIResourceBitmap& bitmap) {
DCHECK_GT(uid, 0);
- DCHECK_EQ(bitmap->GetFormat(), UIResourceBitmap::RGBA8);
+ DCHECK_EQ(bitmap.GetFormat(), UIResourceBitmap::RGBA8);
GLint wrap_mode = 0;
- switch (bitmap->GetWrapMode()) {
+ switch (bitmap.GetWrapMode()) {
case UIResourceBitmap::CLAMP_TO_EDGE:
wrap_mode = GL_CLAMP_TO_EDGE;
break;
@@ -2651,16 +2650,16 @@ void LayerTreeHostImpl::CreateUIResource(
if (id)
DeleteUIResource(uid);
id = resource_provider_->CreateResource(
- bitmap->GetSize(),
+ bitmap.GetSize(),
wrap_mode,
ResourceProvider::TextureUsageAny,
resource_provider_->best_texture_format());
ui_resource_map_[uid] = id;
resource_provider_->SetPixels(id,
- reinterpret_cast<uint8_t*>(bitmap->GetPixels()),
- gfx::Rect(bitmap->GetSize()),
- gfx::Rect(bitmap->GetSize()),
+ bitmap.GetPixels(),
+ gfx::Rect(bitmap.GetSize()),
+ gfx::Rect(bitmap.GetSize()),
gfx::Vector2d(0, 0));
MarkUIResourceNotEvicted(uid);
}
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index e747d7b..7ea6cc9 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -50,8 +50,8 @@ class RenderPassDrawQuad;
class TextureMailboxDeleter;
class TopControlsManager;
class UIResourceBitmap;
+class UIResourceRequest;
struct RendererCapabilities;
-struct UIResourceRequest;
// LayerTreeHost->Proxy callback interface.
class LayerTreeHostImplClient {
@@ -400,14 +400,15 @@ class CC_EXPORT LayerTreeHostImpl
bool page_scale_animation_active() const { return !!page_scale_animation_; }
- void CreateUIResource(UIResourceId uid,
- scoped_refptr<UIResourceBitmap> bitmap);
+ virtual void CreateUIResource(UIResourceId uid,
+ const UIResourceBitmap& bitmap);
// Deletes a UI resource. May safely be called more than once.
- void DeleteUIResource(UIResourceId uid);
+ virtual void DeleteUIResource(UIResourceId uid);
void EvictAllUIResources();
bool EvictedUIResourcesExist() const;
- ResourceProvider::ResourceId ResourceIdForUIResource(UIResourceId uid) const;
+ virtual ResourceProvider::ResourceId ResourceIdForUIResource(
+ UIResourceId uid) const;
void DidInitializeVisibleTileForTesting() { DidInitializeVisibleTile(); }
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index d386795..c184c67 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -3075,12 +3075,13 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) {
host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
SetupActiveTreeLayers();
+ SkBitmap skbitmap;
+ skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+ skbitmap.allocPixels();
+ skbitmap.setImmutable();
+
// Specify an overhang bitmap to use.
- scoped_refptr<UIResourceBitmap> ui_resource_bitmap(UIResourceBitmap::Create(
- new uint8_t[4],
- UIResourceBitmap::RGBA8,
- UIResourceBitmap::REPEAT,
- gfx::Size(1, 1)));
+ UIResourceBitmap ui_resource_bitmap(skbitmap, UIResourceBitmap::REPEAT);
UIResourceId ui_resource_id = 12345;
host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap);
host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32));
@@ -6547,12 +6548,13 @@ TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
EXPECT_EQ(0u, context3d->NumTextures());
+ SkBitmap skbitmap;
+ skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
+ skbitmap.allocPixels();
+ skbitmap.setImmutable();
+
UIResourceId ui_resource_id = 1;
- scoped_refptr<UIResourceBitmap> bitmap = UIResourceBitmap::Create(
- new uint8_t[1],
- UIResourceBitmap::RGBA8,
- UIResourceBitmap::CLAMP_TO_EDGE,
- gfx::Size(1, 1));
+ UIResourceBitmap bitmap(skbitmap);
host_impl_->CreateUIResource(ui_resource_id, bitmap);
EXPECT_EQ(1u, context3d->NumTextures());
ResourceProvider::ResourceId id1 =
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 4c1034a..280bdad 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -657,12 +657,12 @@ void LayerTreeImpl::ProcessUIResourceRequestQueue() {
UIResourceRequest req = ui_resource_request_queue_.front();
ui_resource_request_queue_.pop_front();
- switch (req.type) {
+ switch (req.GetType()) {
case UIResourceRequest::UIResourceCreate:
- layer_tree_host_impl_->CreateUIResource(req.id, req.bitmap);
+ layer_tree_host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
break;
case UIResourceRequest::UIResourceDelete:
- layer_tree_host_impl_->DeleteUIResource(req.id);
+ layer_tree_host_impl_->DeleteUIResource(req.GetId());
break;
case UIResourceRequest::UIResourceInvalidRequest:
NOTREACHED();
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 9464d95..7c66759 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -42,8 +42,8 @@ class PaintTimeCounter;
class Proxy;
class ResourceProvider;
class TileManager;
+class UIResourceRequest;
struct RendererCapabilities;
-struct UIResourceRequest;
typedef std::list<UIResourceRequest> UIResourceRequestQueue;
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 313764b..7f4f064 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -22,6 +22,8 @@
#include "cc/output/compositor_frame.h"
#include "cc/output/context_provider.h"
#include "cc/output/output_surface.h"
+#include "cc/resources/scoped_ui_resource.h"
+#include "cc/resources/ui_resource_bitmap.h"
#include "cc/trees/layer_tree_host.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
@@ -233,7 +235,9 @@ void CompositorImpl::SetSurface(jobject surface) {
void CompositorImpl::SetVisible(bool visible) {
if (!visible) {
+ ui_resource_map_.clear();
host_.reset();
+ client_->UIResourcesAreInvalid();
} else if (!host_) {
cc::LayerTreeSettings settings;
settings.refresh_rate = 60.0;
@@ -260,6 +264,9 @@ void CompositorImpl::SetVisible(bool visible) {
host_->SetLayerTreeHostClientReady();
host_->SetViewportSize(size_);
host_->set_has_transparent_background(has_transparent_background_);
+ // Need to recreate the UI resources because a new LayerTreeHost has been
+ // created.
+ client_->DidLoseUIResources();
}
}
@@ -291,6 +298,23 @@ bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
return false;
}
+cc::UIResourceId CompositorImpl::GenerateUIResource(
+ const cc::UIResourceBitmap& bitmap) {
+ if (!host_)
+ return 0;
+ scoped_ptr<cc::ScopedUIResource> ui_resource =
+ cc::ScopedUIResource::Create(host_.get(), bitmap);
+ cc::UIResourceId id = ui_resource->id();
+ ui_resource_map_.set(id, ui_resource.Pass());
+ return id;
+}
+
+void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) {
+ UIResourceMap::iterator it = ui_resource_map_.find(resource_id);
+ if (it != ui_resource_map_.end())
+ ui_resource_map_.erase(it);
+}
+
WebKit::WebGLId CompositorImpl::GenerateTexture(gfx::JavaBitmap& bitmap) {
unsigned int texture_id = BuildBasicTexture();
WebKit::WebGraphicsContext3D* context =
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index 845e830a..58e44c8 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -7,8 +7,10 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/containers/scoped_ptr_hash_map.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "cc/resources/ui_resource_client.h"
#include "cc/trees/layer_tree_host_client.h"
#include "content/browser/renderer_host/image_transport_factory_android.h"
#include "content/common/content_export.h"
@@ -21,6 +23,7 @@ namespace cc {
class InputHandlerClient;
class Layer;
class LayerTreeHost;
+class ScopedUIResource;
}
namespace content {
@@ -60,6 +63,9 @@ class CONTENT_EXPORT CompositorImpl
void *pixels, const gfx::Rect& rect) OVERRIDE;
virtual void SetNeedsRedraw() OVERRIDE;
virtual void Composite() OVERRIDE;
+ virtual cc::UIResourceId GenerateUIResource(
+ const cc::UIResourceBitmap& bitmap) OVERRIDE;
+ virtual void DeleteUIResource(cc::UIResourceId resource_id) OVERRIDE;
virtual WebKit::WebGLId GenerateTexture(gfx::JavaBitmap& bitmap) OVERRIDE;
virtual WebKit::WebGLId GenerateCompressedTexture(
gfx::Size& size, int data_size, void* data) OVERRIDE;
@@ -117,6 +123,10 @@ class CONTENT_EXPORT CompositorImpl
scoped_refptr<cc::ContextProvider> null_offscreen_context_provider_;
+ typedef base::ScopedPtrHashMap<cc::UIResourceId, cc::ScopedUIResource>
+ UIResourceMap;
+ UIResourceMap ui_resource_map_;
+
DISALLOW_COPY_AND_ASSIGN(CompositorImpl);
};
diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h
index c1cc997..a7072c4 100644
--- a/content/public/browser/android/compositor.h
+++ b/content/public/browser/android/compositor.h
@@ -6,6 +6,8 @@
#define CONTENT_PUBLIC_BROWSER_ANDROID_COMPOSITOR_H_
#include "base/callback.h"
+#include "cc/resources/ui_resource_bitmap.h"
+#include "cc/resources/ui_resource_client.h"
#include "content/common/content_export.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/rect.h"
@@ -84,6 +86,13 @@ class CONTENT_EXPORT Compositor {
// Composite immediately. Used in single-threaded mode.
virtual void Composite() = 0;
+ // Generates a UIResource and returns a UIResourceId. May return 0.
+ virtual cc::UIResourceId GenerateUIResource(
+ const cc::UIResourceBitmap& bitmap) = 0;
+
+ // Deletes a UIResource.
+ virtual void DeleteUIResource(cc::UIResourceId resource_id) = 0;
+
// Generates an OpenGL texture and returns a texture handle. May return 0
// if the current context is lost.
virtual WebKit::WebGLId GenerateTexture(gfx::JavaBitmap& bitmap) = 0;
diff --git a/content/public/browser/android/compositor_client.h b/content/public/browser/android/compositor_client.h
index d70f0c0..d835de1 100644
--- a/content/public/browser/android/compositor_client.h
+++ b/content/public/browser/android/compositor_client.h
@@ -23,6 +23,12 @@ class CONTENT_EXPORT CompositorClient {
// Tells the client that GL resources were lost and need to be reinitialized.
virtual void DidLoseResources() {}
+ // Tells the client that UI resources were lost and need to be reinitialized.
+ virtual void DidLoseUIResources() {}
+
+ // Mark the UI Resources as being invalid for use.
+ virtual void UIResourcesAreInvalid() {}
+
protected:
CompositorClient() {}
virtual ~CompositorClient() {}
diff --git a/ui/gfx/android/java_bitmap.cc b/ui/gfx/android/java_bitmap.cc
index c3cd94d..6c2eaa8 100644
--- a/ui/gfx/android/java_bitmap.cc
+++ b/ui/gfx/android/java_bitmap.cc
@@ -62,33 +62,20 @@ ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) {
return jbitmap;
}
-static ScopedJavaLocalRef<jobject> CreateJavaBitmapFromResource(
- const char* name, gfx::Size requested_size) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jstring> jname(
- base::android::ConvertUTF8ToJavaString(env, name));
- return ui::Java_BitmapHelper_decodeDrawableResource(env,
- jname.obj(),
- requested_size.width(),
- requested_size.height());
-}
-
-static SkBitmap ConvertToSkBitmap(ScopedJavaLocalRef<jobject> jbitmap) {
- if (jbitmap.is_null())
- return SkBitmap();
+SkBitmap CreateSkBitmapFromJavaBitmap(JavaBitmap& jbitmap) {
+ DCHECK_EQ(jbitmap.format(), ANDROID_BITMAP_FORMAT_RGBA_8888);
- JavaBitmap src_lock(jbitmap.obj());
- DCHECK_EQ(src_lock.format(), ANDROID_BITMAP_FORMAT_RGBA_8888);
-
- gfx::Size src_size = src_lock.size();
+ gfx::Size src_size = jbitmap.size();
SkBitmap skbitmap;
skbitmap.setConfig(SkBitmap::kARGB_8888_Config,
- src_size.width(), src_size.height(), src_lock.stride());
+ src_size.width(),
+ src_size.height(),
+ jbitmap.stride());
skbitmap.allocPixels();
SkAutoLockPixels dst_lock(skbitmap);
- void* src_pixels = src_lock.pixels();
+ void* src_pixels = jbitmap.pixels();
void* dst_pixels = skbitmap.getPixels();
memcpy(dst_pixels, src_pixels, skbitmap.getSize());
@@ -98,14 +85,17 @@ static SkBitmap ConvertToSkBitmap(ScopedJavaLocalRef<jobject> jbitmap) {
SkBitmap CreateSkBitmapFromResource(const char* name, gfx::Size size) {
DCHECK(!size.IsEmpty());
- SkBitmap bitmap =
- ConvertToSkBitmap(CreateJavaBitmapFromResource(name, size));
- if (bitmap.isNull())
- return bitmap;
- // RESIZE_BOX has sufficient downsampling quality with minimal runtime cost.
- return skia::ImageOperations::Resize(bitmap,
- skia::ImageOperations::RESIZE_BOX,
- size.width(), size.height());
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jname(env, env->NewStringUTF(name));
+ ScopedJavaLocalRef<jobject> jobj(ui::Java_BitmapHelper_decodeDrawableResource(
+ env, jname.obj(), size.width(), size.height()));
+ if (jobj.is_null())
+ return SkBitmap();
+
+ JavaBitmap jbitmap(jobj.obj());
+ SkBitmap bitmap = CreateSkBitmapFromJavaBitmap(jbitmap);
+ return skia::ImageOperations::Resize(
+ bitmap, skia::ImageOperations::RESIZE_BOX, size.width(), size.height());
}
} // namespace gfx
diff --git a/ui/gfx/android/java_bitmap.h b/ui/gfx/android/java_bitmap.h
index 14bfc990..319ad79 100644
--- a/ui/gfx/android/java_bitmap.h
+++ b/ui/gfx/android/java_bitmap.h
@@ -44,6 +44,8 @@ class UI_EXPORT JavaBitmap {
UI_EXPORT base::android::ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(
const SkBitmap* skbitmap);
+UI_EXPORT SkBitmap CreateSkBitmapFromJavaBitmap(JavaBitmap& jbitmap);
+
// If the resource loads successfully, it will be resized to |size|.
// Note: If the source resource is smaller than |size|, quality may suffer.
UI_EXPORT SkBitmap CreateSkBitmapFromResource(const char* name, gfx::Size size);