1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/layers/ui_resource_layer.h"
6
7#include "cc/layers/ui_resource_layer_impl.h"
8#include "cc/resources/prioritized_resource.h"
9#include "cc/resources/resource_update.h"
10#include "cc/resources/resource_update_queue.h"
11#include "cc/resources/scoped_ui_resource.h"
12#include "cc/resources/ui_resource_bitmap.h"
13#include "cc/trees/layer_tree_host.h"
14
15namespace cc {
16
17
18namespace {
19
20class ScopedUIResourceHolder : public UIResourceLayer::UIResourceHolder {
21 public:
22  static scoped_ptr<ScopedUIResourceHolder> Create(LayerTreeHost* host,
23                                            const SkBitmap& skbitmap) {
24    return make_scoped_ptr(new ScopedUIResourceHolder(host, skbitmap));
25  }
26  virtual UIResourceId id() OVERRIDE { return resource_->id(); }
27
28 private:
29  ScopedUIResourceHolder(LayerTreeHost* host, const SkBitmap& skbitmap) {
30    resource_ = ScopedUIResource::Create(host, UIResourceBitmap(skbitmap));
31  }
32
33  scoped_ptr<ScopedUIResource> resource_;
34};
35
36class SharedUIResourceHolder : public UIResourceLayer::UIResourceHolder {
37 public:
38  static scoped_ptr<SharedUIResourceHolder> Create(UIResourceId id) {
39    return make_scoped_ptr(new SharedUIResourceHolder(id));
40  }
41
42  virtual UIResourceId id() OVERRIDE { return id_; }
43
44 private:
45  explicit SharedUIResourceHolder(UIResourceId id) : id_(id) {}
46
47  UIResourceId id_;
48};
49
50}  // anonymous namespace
51
52UIResourceLayer::UIResourceHolder::~UIResourceHolder() {}
53
54scoped_refptr<UIResourceLayer> UIResourceLayer::Create() {
55  return make_scoped_refptr(new UIResourceLayer());
56}
57
58UIResourceLayer::UIResourceLayer()
59    : Layer(),
60      uv_top_left_(0.f, 0.f),
61      uv_bottom_right_(1.f, 1.f) {
62  vertex_opacity_[0] = 1.0f;
63  vertex_opacity_[1] = 1.0f;
64  vertex_opacity_[2] = 1.0f;
65  vertex_opacity_[3] = 1.0f;
66}
67
68UIResourceLayer::~UIResourceLayer() {}
69
70scoped_ptr<LayerImpl> UIResourceLayer::CreateLayerImpl(
71    LayerTreeImpl* tree_impl) {
72  return UIResourceLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
73}
74
75void UIResourceLayer::SetUV(const gfx::PointF& top_left,
76                            const gfx::PointF& bottom_right) {
77  if (uv_top_left_ == top_left && uv_bottom_right_ == bottom_right)
78    return;
79  uv_top_left_ = top_left;
80  uv_bottom_right_ = bottom_right;
81  SetNeedsCommit();
82}
83
84void UIResourceLayer::SetVertexOpacity(float bottom_left,
85                                       float top_left,
86                                       float top_right,
87                                       float bottom_right) {
88  // Indexing according to the quad vertex generation:
89  // 1--2
90  // |  |
91  // 0--3
92  if (vertex_opacity_[0] == bottom_left &&
93      vertex_opacity_[1] == top_left &&
94      vertex_opacity_[2] == top_right &&
95      vertex_opacity_[3] == bottom_right)
96    return;
97  vertex_opacity_[0] = bottom_left;
98  vertex_opacity_[1] = top_left;
99  vertex_opacity_[2] = top_right;
100  vertex_opacity_[3] = bottom_right;
101  SetNeedsCommit();
102}
103
104void UIResourceLayer::SetLayerTreeHost(LayerTreeHost* host) {
105  if (host == layer_tree_host())
106    return;
107
108  Layer::SetLayerTreeHost(host);
109
110  // Recreate the resource hold against the new LTH.
111  RecreateUIResourceHolder();
112}
113
114void UIResourceLayer::RecreateUIResourceHolder() {
115  ui_resource_holder_.reset();
116  if (layer_tree_host() && !bitmap_.empty()) {
117    ui_resource_holder_ =
118        ScopedUIResourceHolder::Create(layer_tree_host(), bitmap_);
119  }
120  UpdateDrawsContent(HasDrawableContent());
121}
122
123void UIResourceLayer::SetBitmap(const SkBitmap& skbitmap) {
124  bitmap_ = skbitmap;
125
126  RecreateUIResourceHolder();
127  SetNeedsCommit();
128}
129
130void UIResourceLayer::SetUIResourceId(UIResourceId resource_id) {
131  if (ui_resource_holder_ && ui_resource_holder_->id() == resource_id)
132    return;
133
134  if (resource_id) {
135    ui_resource_holder_ = SharedUIResourceHolder::Create(resource_id);
136  } else {
137    ui_resource_holder_.reset();
138  }
139
140  UpdateDrawsContent(HasDrawableContent());
141  SetNeedsCommit();
142}
143
144bool UIResourceLayer::HasDrawableContent() const {
145  return ui_resource_holder_ && ui_resource_holder_->id() &&
146         Layer::HasDrawableContent();
147}
148
149void UIResourceLayer::PushPropertiesTo(LayerImpl* layer) {
150  Layer::PushPropertiesTo(layer);
151  UIResourceLayerImpl* layer_impl = static_cast<UIResourceLayerImpl*>(layer);
152
153  if (!ui_resource_holder_) {
154    layer_impl->SetUIResourceId(0);
155  } else {
156    DCHECK(layer_tree_host());
157
158    gfx::Size image_size =
159        layer_tree_host()->GetUIResourceSize(ui_resource_holder_->id());
160    layer_impl->SetUIResourceId(ui_resource_holder_->id());
161    layer_impl->SetImageBounds(image_size);
162    layer_impl->SetUV(uv_top_left_, uv_bottom_right_);
163    layer_impl->SetVertexOpacity(vertex_opacity_);
164  }
165}
166
167}  // namespace cc
168