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(gfx::PointF top_left, gfx::PointF bottom_right) {
76  if (uv_top_left_ == top_left && uv_bottom_right_ == bottom_right)
77    return;
78  uv_top_left_ = top_left;
79  uv_bottom_right_ = bottom_right;
80  SetNeedsCommit();
81}
82
83void UIResourceLayer::SetVertexOpacity(float bottom_left,
84                                       float top_left,
85                                       float top_right,
86                                       float bottom_right) {
87  // Indexing according to the quad vertex generation:
88  // 1--2
89  // |  |
90  // 0--3
91  if (vertex_opacity_[0] == bottom_left &&
92      vertex_opacity_[1] == top_left &&
93      vertex_opacity_[2] == top_right &&
94      vertex_opacity_[3] == bottom_right)
95    return;
96  vertex_opacity_[0] = bottom_left;
97  vertex_opacity_[1] = top_left;
98  vertex_opacity_[2] = top_right;
99  vertex_opacity_[3] = bottom_right;
100  SetNeedsCommit();
101}
102
103void UIResourceLayer::SetLayerTreeHost(LayerTreeHost* host) {
104  if (host == layer_tree_host())
105    return;
106
107  Layer::SetLayerTreeHost(host);
108
109  // Recreate the resource hold against the new LTH.
110  RecreateUIResourceHolder();
111}
112
113void UIResourceLayer::RecreateUIResourceHolder() {
114  ui_resource_holder_.reset();
115  if (!layer_tree_host() || bitmap_.empty())
116    return;
117
118  ui_resource_holder_ =
119    ScopedUIResourceHolder::Create(layer_tree_host(), bitmap_);
120}
121
122void UIResourceLayer::SetBitmap(const SkBitmap& skbitmap) {
123  bitmap_ = skbitmap;
124
125  RecreateUIResourceHolder();
126  SetNeedsCommit();
127}
128
129void UIResourceLayer::SetUIResourceId(UIResourceId resource_id) {
130  if (ui_resource_holder_ && ui_resource_holder_->id() == resource_id)
131    return;
132
133  if (resource_id) {
134    ui_resource_holder_ = SharedUIResourceHolder::Create(resource_id);
135  } else {
136    ui_resource_holder_.reset();
137  }
138
139  SetNeedsCommit();
140}
141
142bool UIResourceLayer::DrawsContent() const {
143  return ui_resource_holder_ && ui_resource_holder_->id() &&
144         Layer::DrawsContent();
145}
146
147void UIResourceLayer::PushPropertiesTo(LayerImpl* layer) {
148  Layer::PushPropertiesTo(layer);
149  UIResourceLayerImpl* layer_impl = static_cast<UIResourceLayerImpl*>(layer);
150
151  if (!ui_resource_holder_) {
152    layer_impl->SetUIResourceId(0);
153  } else {
154    DCHECK(layer_tree_host());
155
156    gfx::Size image_size =
157        layer_tree_host()->GetUIResourceSize(ui_resource_holder_->id());
158    layer_impl->SetUIResourceId(ui_resource_holder_->id());
159    layer_impl->SetImageBounds(image_size);
160    layer_impl->SetUV(uv_top_left_, uv_bottom_right_);
161    layer_impl->SetVertexOpacity(vertex_opacity_);
162  }
163}
164
165}  // namespace cc
166