Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: content/browser/android/overscroll_glow.cc

Issue 377013002: android: Use UIResource for overscroll glow (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/android/overscroll_glow.h" 5 #include "content/browser/android/overscroll_glow.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/threading/worker_pool.h" 9 #include "cc/layers/ui_resource_layer.h"
10 #include "cc/layers/image_layer.h"
11 #include "content/browser/android/edge_effect.h" 10 #include "content/browser/android/edge_effect.h"
12 #include "skia/ext/image_operations.h"
13 #include "ui/gfx/android/java_bitmap.h" 11 #include "ui/gfx/android/java_bitmap.h"
14 12
15 using std::max; 13 using std::max;
16 using std::min; 14 using std::min;
17 15
18 namespace content { 16 namespace content {
19 17
20 namespace { 18 namespace {
21 19
22 const float kEpsilon = 1e-3f; 20 const float kEpsilon = 1e-3f;
23 const int kScaledEdgeHeight = 12;
24 const int kScaledGlowHeight = 64;
25 const float kEdgeHeightAtMdpi = 12.f; 21 const float kEdgeHeightAtMdpi = 12.f;
26 const float kGlowHeightAtMdpi = 128.f; 22 const float kGlowHeightAtMdpi = 128.f;
27 23
28 SkBitmap CreateSkBitmapFromAndroidResource(const char* name, gfx::Size size) {
29 base::android::ScopedJavaLocalRef<jobject> jobj =
30 gfx::CreateJavaBitmapFromAndroidResource(name, size);
31 if (jobj.is_null())
32 return SkBitmap();
33
34 SkBitmap bitmap = CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jobj.obj()));
35 if (bitmap.isNull())
36 return bitmap;
37
38 return skia::ImageOperations::Resize(
powei 2014/07/08 19:12:43 I didn't move this over. I thought BitmapHelper.d
jdduke (slow) 2014/07/08 20:10:11 Unfortunately no, if you look at the comments, dec
powei 2014/07/09 20:41:03 This is the only consumer. I can move it to java_
39 bitmap, skia::ImageOperations::RESIZE_BOX, size.width(), size.height());
40 }
41
42 class OverscrollResources {
43 public:
44 OverscrollResources() {
45 TRACE_EVENT0("browser", "OverscrollResources::Create");
46 edge_bitmap_ =
47 CreateSkBitmapFromAndroidResource("android:drawable/overscroll_edge",
48 gfx::Size(128, kScaledEdgeHeight));
49 glow_bitmap_ =
50 CreateSkBitmapFromAndroidResource("android:drawable/overscroll_glow",
51 gfx::Size(128, kScaledGlowHeight));
52 }
53
54 const SkBitmap& edge_bitmap() const { return edge_bitmap_; }
55 const SkBitmap& glow_bitmap() const { return glow_bitmap_; }
56
57 private:
58 SkBitmap edge_bitmap_;
59 SkBitmap glow_bitmap_;
60
61 DISALLOW_COPY_AND_ASSIGN(OverscrollResources);
62 };
63
64 // Leaky to allow access from a worker thread.
65 base::LazyInstance<OverscrollResources>::Leaky g_overscroll_resources =
66 LAZY_INSTANCE_INITIALIZER;
67
68 scoped_refptr<cc::Layer> CreateImageLayer(const SkBitmap& bitmap) {
69 scoped_refptr<cc::ImageLayer> layer = cc::ImageLayer::Create();
70 layer->SetBitmap(bitmap);
71 return layer;
72 }
73
74 bool IsApproxZero(float value) { 24 bool IsApproxZero(float value) {
75 return std::abs(value) < kEpsilon; 25 return std::abs(value) < kEpsilon;
76 } 26 }
77 27
78 gfx::Vector2dF ZeroSmallComponents(gfx::Vector2dF vector) { 28 gfx::Vector2dF ZeroSmallComponents(gfx::Vector2dF vector) {
79 if (IsApproxZero(vector.x())) 29 if (IsApproxZero(vector.x()))
80 vector.set_x(0); 30 vector.set_x(0);
81 if (IsApproxZero(vector.y())) 31 if (IsApproxZero(vector.y()))
82 vector.set_y(0); 32 vector.set_y(0);
83 return vector; 33 return vector;
84 } 34 }
85 35
86 // Force loading of any necessary resources. This function is thread-safe.
87 void EnsureResources() {
88 g_overscroll_resources.Get();
89 }
90
91 } // namespace 36 } // namespace
92 37
93 scoped_ptr<OverscrollGlow> OverscrollGlow::Create(bool enabled) { 38 scoped_ptr<OverscrollGlow> OverscrollGlow::Create(bool enabled) {
94 // Don't block the main thread with effect resource loading during creation.
95 // Effect instantiation is deferred until the effect overscrolls, in which
96 // case the main thread may block until the resource has loaded.
97 if (enabled && g_overscroll_resources == NULL)
98 base::WorkerPool::PostTask(FROM_HERE, base::Bind(EnsureResources), true);
99
100 return make_scoped_ptr(new OverscrollGlow(enabled)); 39 return make_scoped_ptr(new OverscrollGlow(enabled));
101 } 40 }
102 41
103 OverscrollGlow::OverscrollGlow(bool enabled) 42 OverscrollGlow::OverscrollGlow(bool enabled)
104 : enabled_(enabled), initialized_(false) {} 43 : enabled_(enabled), initialized_(false) {}
105 44
106 OverscrollGlow::~OverscrollGlow() { 45 OverscrollGlow::~OverscrollGlow() {
107 Detach(); 46 Detach();
108 } 47 }
109 48
110 void OverscrollGlow::Enable() { 49 void OverscrollGlow::Enable() {
111 enabled_ = true; 50 enabled_ = true;
112 } 51 }
113 52
114 void OverscrollGlow::Disable() { 53 void OverscrollGlow::Disable() {
115 if (!enabled_) 54 if (!enabled_)
116 return; 55 return;
117 enabled_ = false; 56 enabled_ = false;
118 if (!enabled_ && initialized_) { 57 if (!enabled_ && initialized_) {
119 Detach(); 58 Detach();
120 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) 59 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i)
121 edge_effects_[i]->Finish(); 60 edge_effects_[i]->Finish();
122 } 61 }
123 } 62 }
124 63
125 bool OverscrollGlow::OnOverscrolled(cc::Layer* overscrolling_layer, 64 bool OverscrollGlow::OnOverscrolled(cc::Layer* overscrolling_layer,
126 base::TimeTicks current_time, 65 base::TimeTicks current_time,
66 cc::UIResourceId edge_ui_resource,
67 cc::UIResourceId glow_ui_resource,
127 gfx::Vector2dF accumulated_overscroll, 68 gfx::Vector2dF accumulated_overscroll,
128 gfx::Vector2dF overscroll_delta, 69 gfx::Vector2dF overscroll_delta,
129 gfx::Vector2dF velocity) { 70 gfx::Vector2dF velocity) {
130 DCHECK(overscrolling_layer); 71 DCHECK(overscrolling_layer);
131 72
132 if (!enabled_) 73 if (!enabled_)
133 return false; 74 return false;
134 75
135 // The size of the glow determines the relative effect of the inputs; an 76 // The size of the glow determines the relative effect of the inputs; an
136 // empty-sized effect is effectively disabled. 77 // empty-sized effect is effectively disabled.
137 if (display_params_.size.IsEmpty()) 78 if (display_params_.size.IsEmpty())
138 return false; 79 return false;
139 80
140 // Ignore sufficiently small values that won't meaningfuly affect animation. 81 // Ignore sufficiently small values that won't meaningfuly affect animation.
141 overscroll_delta = ZeroSmallComponents(overscroll_delta); 82 overscroll_delta = ZeroSmallComponents(overscroll_delta);
142 if (overscroll_delta.IsZero()) { 83 if (overscroll_delta.IsZero()) {
143 if (initialized_) { 84 if (initialized_) {
144 Release(current_time); 85 Release(current_time);
145 UpdateLayerAttachment(overscrolling_layer); 86 UpdateLayerAttachment(
87 overscrolling_layer, edge_ui_resource, glow_ui_resource);
146 } 88 }
147 return NeedsAnimate(); 89 return NeedsAnimate();
148 } 90 }
149 91
150 if (!InitializeIfNecessary()) 92 if (!InitializeIfNecessary())
151 return false; 93 return false;
152 94
153 gfx::Vector2dF old_overscroll = accumulated_overscroll - overscroll_delta; 95 gfx::Vector2dF old_overscroll = accumulated_overscroll - overscroll_delta;
154 bool x_overscroll_started = 96 bool x_overscroll_started =
155 !IsApproxZero(overscroll_delta.x()) && IsApproxZero(old_overscroll.x()); 97 !IsApproxZero(overscroll_delta.x()) && IsApproxZero(old_overscroll.x());
156 bool y_overscroll_started = 98 bool y_overscroll_started =
157 !IsApproxZero(overscroll_delta.y()) && IsApproxZero(old_overscroll.y()); 99 !IsApproxZero(overscroll_delta.y()) && IsApproxZero(old_overscroll.y());
158 100
159 if (x_overscroll_started) 101 if (x_overscroll_started)
160 ReleaseAxis(AXIS_X, current_time); 102 ReleaseAxis(AXIS_X, current_time);
161 if (y_overscroll_started) 103 if (y_overscroll_started)
162 ReleaseAxis(AXIS_Y, current_time); 104 ReleaseAxis(AXIS_Y, current_time);
163 105
164 velocity = ZeroSmallComponents(velocity); 106 velocity = ZeroSmallComponents(velocity);
165 if (!velocity.IsZero()) 107 if (!velocity.IsZero())
166 Absorb(current_time, velocity, x_overscroll_started, y_overscroll_started); 108 Absorb(current_time, velocity, x_overscroll_started, y_overscroll_started);
167 else 109 else
168 Pull(current_time, overscroll_delta); 110 Pull(current_time, overscroll_delta);
169 111
170 UpdateLayerAttachment(overscrolling_layer); 112 UpdateLayerAttachment(
113 overscrolling_layer, edge_ui_resource, glow_ui_resource);
114
171 return NeedsAnimate(); 115 return NeedsAnimate();
172 } 116 }
173 117
174 bool OverscrollGlow::Animate(base::TimeTicks current_time) { 118 bool OverscrollGlow::Animate(base::TimeTicks current_time) {
175 if (!NeedsAnimate()) { 119 if (!NeedsAnimate()) {
176 Detach(); 120 Detach();
177 return false; 121 return false;
178 } 122 }
179 123
180 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { 124 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
(...skipping 22 matching lines...) Expand all
203 bool OverscrollGlow::NeedsAnimate() const { 147 bool OverscrollGlow::NeedsAnimate() const {
204 if (!enabled_ || !initialized_) 148 if (!enabled_ || !initialized_)
205 return false; 149 return false;
206 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { 150 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
207 if (!edge_effects_[i]->IsFinished()) 151 if (!edge_effects_[i]->IsFinished())
208 return true; 152 return true;
209 } 153 }
210 return false; 154 return false;
211 } 155 }
212 156
213 void OverscrollGlow::UpdateLayerAttachment(cc::Layer* parent) { 157 void OverscrollGlow::UpdateLayerAttachment(cc::Layer* parent,
158 cc::UIResourceId edge_ui_resource,
159 cc::UIResourceId glow_ui_resource) {
214 DCHECK(parent); 160 DCHECK(parent);
215 if (!root_layer_) 161 if (!root_layer_)
216 return; 162 return;
217 163
218 if (!NeedsAnimate()) { 164 if (!NeedsAnimate()) {
219 Detach(); 165 Detach();
220 return; 166 return;
221 } 167 }
222 168
223 if (root_layer_->parent() != parent) 169 if (root_layer_->parent() != parent)
224 parent->AddChild(root_layer_); 170 parent->AddChild(root_layer_);
171
172 // UIResources addition needs to take place after layer attachment.
173 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
174 if (edge_effects_[i])
175 edge_effects_[i]->SetUIResources(edge_ui_resource, glow_ui_resource);
176 }
225 } 177 }
226 178
227 void OverscrollGlow::Detach() { 179 void OverscrollGlow::Detach() {
228 if (root_layer_) 180 if (root_layer_)
229 root_layer_->RemoveFromParent(); 181 root_layer_->RemoveFromParent();
230 } 182 }
231 183
232 bool OverscrollGlow::InitializeIfNecessary() { 184 bool OverscrollGlow::InitializeIfNecessary() {
233 DCHECK(enabled_); 185 DCHECK(enabled_);
234 if (initialized_) 186 if (initialized_)
235 return true; 187 return true;
236 188
237 const SkBitmap& edge = g_overscroll_resources.Get().edge_bitmap();
238 const SkBitmap& glow = g_overscroll_resources.Get().glow_bitmap();
239 if (edge.isNull() || glow.isNull()) {
240 Disable();
241 return false;
242 }
243
244 DCHECK(!root_layer_); 189 DCHECK(!root_layer_);
245 root_layer_ = cc::Layer::Create(); 190 root_layer_ = cc::Layer::Create();
246 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) { 191 for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
247 scoped_refptr<cc::Layer> edge_layer = CreateImageLayer(edge); 192 scoped_refptr<cc::UIResourceLayer> edge_layer =
248 scoped_refptr<cc::Layer> glow_layer = CreateImageLayer(glow); 193 cc::UIResourceLayer::Create();
194 scoped_refptr<cc::UIResourceLayer> glow_layer =
195 cc::UIResourceLayer::Create();
249 root_layer_->AddChild(edge_layer); 196 root_layer_->AddChild(edge_layer);
250 root_layer_->AddChild(glow_layer); 197 root_layer_->AddChild(glow_layer);
251 edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer)); 198 edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer));
252 } 199 }
253 200
254 initialized_ = true; 201 initialized_ = true;
255 return true; 202 return true;
256 } 203 }
257 204
258 void OverscrollGlow::Pull(base::TimeTicks current_time, 205 void OverscrollGlow::Pull(base::TimeTicks current_time,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 DCHECK(initialized_); 278 DCHECK(initialized_);
332 return edge_effects_[(edge_index + 2) % EdgeEffect::EDGE_COUNT].get(); 279 return edge_effects_[(edge_index + 2) % EdgeEffect::EDGE_COUNT].get();
333 } 280 }
334 281
335 OverscrollGlow::DisplayParameters::DisplayParameters() 282 OverscrollGlow::DisplayParameters::DisplayParameters()
336 : device_scale_factor(1) { 283 : device_scale_factor(1) {
337 edge_offsets[0] = edge_offsets[1] = edge_offsets[2] = edge_offsets[3] = 0.f; 284 edge_offsets[0] = edge_offsets[1] = edge_offsets[2] = edge_offsets[3] = 0.f;
338 } 285 }
339 286
340 } // namespace content 287 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698