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

Side by Side Diff: ui/android/window_android.cc

Issue 2564403002: [android] Make RWHVAndroid a BeginFrameObserver. (Closed)
Patch Set: rebase Created 4 years 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
« no previous file with comments | « ui/android/window_android.h ('k') | ui/android/window_android_compositor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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 "ui/android/window_android.h" 5 #include "ui/android/window_android.h"
6 6
7 #include <unordered_set>
8
7 #include "base/android/context_utils.h" 9 #include "base/android/context_utils.h"
8 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
9 #include "base/android/jni_array.h" 11 #include "base/android/jni_array.h"
10 #include "base/android/jni_string.h" 12 #include "base/android/jni_string.h"
11 #include "base/android/jni_weak_ref.h" 13 #include "base/android/jni_weak_ref.h"
12 #include "base/android/scoped_java_ref.h" 14 #include "base/android/scoped_java_ref.h"
15 #include "base/auto_reset.h"
16 #include "base/observer_list.h"
17 #include "base/stl_util.h"
18 #include "cc/output/begin_frame_args.h"
19 #include "cc/scheduler/begin_frame_source.h"
13 #include "jni/WindowAndroid_jni.h" 20 #include "jni/WindowAndroid_jni.h"
14 #include "ui/android/window_android_compositor.h" 21 #include "ui/android/window_android_compositor.h"
15 #include "ui/android/window_android_observer.h" 22 #include "ui/android/window_android_observer.h"
16 23
17 namespace ui { 24 namespace ui {
18 25
19 using base::android::AttachCurrentThread; 26 using base::android::AttachCurrentThread;
20 using base::android::JavaParamRef; 27 using base::android::JavaParamRef;
21 using base::android::JavaRef; 28 using base::android::JavaRef;
22 using base::android::ScopedJavaLocalRef; 29 using base::android::ScopedJavaLocalRef;
23 30
31 class WindowAndroid::WindowBeginFrameSource : public cc::BeginFrameSource {
32 public:
33 explicit WindowBeginFrameSource(WindowAndroid* window)
34 : window_(window),
35 observer_count_(0),
36 in_on_vsync_(false) {}
37 ~WindowBeginFrameSource() override {}
38
39 // cc::BeginFrameSource implementation.
40 void AddObserver(cc::BeginFrameObserver* obs) override;
41 void RemoveObserver(cc::BeginFrameObserver* obs) override;
42 void DidFinishFrame(cc::BeginFrameObserver* obs,
43 size_t remaining_frames) override {}
44 bool IsThrottled() const override { return true; }
45
46 void OnVSync(base::TimeTicks frame_time,
47 base::TimeDelta vsync_period);
48
49 private:
50 WindowAndroid* const window_;
51 base::ObserverList<cc::BeginFrameObserver> observers_;
52 int observer_count_;
53 cc::BeginFrameArgs last_begin_frame_args_;
54 bool in_on_vsync_;
55 };
56
57 void WindowAndroid::WindowBeginFrameSource::AddObserver(
58 cc::BeginFrameObserver* obs) {
59 DCHECK(obs);
60 DCHECK(!observers_.HasObserver(obs));
61
62 observers_.AddObserver(obs);
63 observer_count_++;
64 obs->OnBeginFrameSourcePausedChanged(false);
65 window_->SetNeedsBeginFrames(true);
66
67 // Send a MISSED BeginFrame if possible and necessary. If an observer is added
68 // during OnVSync(), it will get a NORMAL BeginFrame from OnVSync() instead.
69 if (!in_on_vsync_ && last_begin_frame_args_.IsValid()) {
70 cc::BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
71 if (!last_args.IsValid() ||
72 last_args.frame_time < last_begin_frame_args_.frame_time) {
73 last_begin_frame_args_.type = cc::BeginFrameArgs::MISSED;
74 // TODO(crbug.com/602485): A deadline doesn't make too much sense
75 // for a missed BeginFrame (the intention rather is 'immediately'),
76 // but currently the retro frame logic is very strict in discarding
77 // BeginFrames.
78 last_begin_frame_args_.deadline =
79 base::TimeTicks::Now() + last_begin_frame_args_.interval;
80 obs->OnBeginFrame(last_begin_frame_args_);
81 }
82 }
83 }
84
85 void WindowAndroid::WindowBeginFrameSource::RemoveObserver(
86 cc::BeginFrameObserver* obs) {
87 DCHECK(obs);
88 DCHECK(observers_.HasObserver(obs));
89
90 observers_.RemoveObserver(obs);
91 observer_count_--;
92 if (observer_count_ <= 0)
93 window_->SetNeedsBeginFrames(false);
94 }
95
96 void WindowAndroid::WindowBeginFrameSource::OnVSync(
97 base::TimeTicks frame_time,
98 base::TimeDelta vsync_period) {
99 // frame time is in the past, so give the next vsync period as the deadline.
100 base::TimeTicks deadline = frame_time + vsync_period;
101 last_begin_frame_args_ =
102 cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
103 vsync_period, cc::BeginFrameArgs::NORMAL);
104 DCHECK(last_begin_frame_args_.IsValid());
105
106 // We support adding/removing observers during observer iteration through
107 // base::ObserverList. We also prevent observers that are added during
108 // observer iteration from receiving a MISSED BeginFrame by means of
109 // |in_on_vsync_| - they will receive the current NORMAL one during the
110 // iteration instead. Note that SynchronousCompositorBrowserFilter relies on
111 // this behavior.
112 // TODO(eseckler): Remove SynchronousCompositorBrowserFilter's dependency on
113 // this and replace observers_ by a std::unordered_set, iterate on a copy.
114 base::AutoReset<bool> auto_reset(&in_on_vsync_, true);
115 std::unordered_set<cc::BeginFrameObserver*> notified_observers;
116 for (auto& obs : observers_) {
117 // An observer may remove and add itself during a single OnBeginFrame, in
118 // which case it'd appear twice during the iteration. To deal with this, we
119 // keep track of whether we already notified it.
120 if (!base::ContainsKey(notified_observers, &obs)) {
121 obs.OnBeginFrame(last_begin_frame_args_);
122 notified_observers.insert(&obs);
123 }
124 }
125 }
126
24 WindowAndroid::WindowAndroid(JNIEnv* env, jobject obj, int display_id) 127 WindowAndroid::WindowAndroid(JNIEnv* env, jobject obj, int display_id)
25 : display_id_(display_id), compositor_(NULL) { 128 : display_id_(display_id),
129 compositor_(NULL),
130 begin_frame_source_(new WindowBeginFrameSource(this)),
131 needs_begin_frames_(false) {
26 java_window_.Reset(env, obj); 132 java_window_.Reset(env, obj);
27 } 133 }
28 134
29 void WindowAndroid::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { 135 void WindowAndroid::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
30 delete this; 136 delete this;
31 } 137 }
32 138
33 ScopedJavaLocalRef<jobject> WindowAndroid::GetJavaObject() { 139 ScopedJavaLocalRef<jobject> WindowAndroid::GetJavaObject() {
34 return base::android::ScopedJavaLocalRef<jobject>(java_window_); 140 return base::android::ScopedJavaLocalRef<jobject>(java_window_);
35 } 141 }
(...skipping 26 matching lines...) Expand all
62 168
63 void WindowAndroid::AddObserver(WindowAndroidObserver* observer) { 169 void WindowAndroid::AddObserver(WindowAndroidObserver* observer) {
64 if (!observer_list_.HasObserver(observer)) 170 if (!observer_list_.HasObserver(observer))
65 observer_list_.AddObserver(observer); 171 observer_list_.AddObserver(observer);
66 } 172 }
67 173
68 void WindowAndroid::RemoveObserver(WindowAndroidObserver* observer) { 174 void WindowAndroid::RemoveObserver(WindowAndroidObserver* observer) {
69 observer_list_.RemoveObserver(observer); 175 observer_list_.RemoveObserver(observer);
70 } 176 }
71 177
178 cc::BeginFrameSource* WindowAndroid::GetBeginFrameSource() {
179 return begin_frame_source_.get();
180 }
181
72 void WindowAndroid::AttachCompositor(WindowAndroidCompositor* compositor) { 182 void WindowAndroid::AttachCompositor(WindowAndroidCompositor* compositor) {
73 if (compositor_ && compositor != compositor_) 183 if (compositor_ && compositor != compositor_)
74 DetachCompositor(); 184 DetachCompositor();
75 185
76 compositor_ = compositor; 186 compositor_ = compositor;
77 for (WindowAndroidObserver& observer : observer_list_) 187 for (WindowAndroidObserver& observer : observer_list_)
78 observer.OnAttachCompositor(); 188 observer.OnAttachCompositor();
79 } 189 }
80 190
81 void WindowAndroid::DetachCompositor() { 191 void WindowAndroid::DetachCompositor() {
82 compositor_ = NULL; 192 compositor_ = NULL;
83 for (WindowAndroidObserver& observer : observer_list_) 193 for (WindowAndroidObserver& observer : observer_list_)
84 observer.OnDetachCompositor(); 194 observer.OnDetachCompositor();
85 observer_list_.Clear(); 195 observer_list_.Clear();
86 } 196 }
87 197
88 void WindowAndroid::RequestVSyncUpdate() { 198 void WindowAndroid::RequestVSyncUpdate() {
89 JNIEnv* env = AttachCurrentThread(); 199 JNIEnv* env = AttachCurrentThread();
90 Java_WindowAndroid_requestVSyncUpdate(env, GetJavaObject()); 200 Java_WindowAndroid_requestVSyncUpdate(env, GetJavaObject());
91 } 201 }
92 202
203 void WindowAndroid::SetNeedsBeginFrames(bool needs_begin_frames) {
204 if (needs_begin_frames_ == needs_begin_frames)
205 return;
206
207 needs_begin_frames_ = needs_begin_frames;
208 if (needs_begin_frames_)
209 RequestVSyncUpdate();
210 }
211
93 void WindowAndroid::SetNeedsAnimate() { 212 void WindowAndroid::SetNeedsAnimate() {
94 if (compositor_) 213 if (compositor_)
95 compositor_->SetNeedsAnimate(); 214 compositor_->SetNeedsAnimate();
96 } 215 }
97 216
98 void WindowAndroid::Animate(base::TimeTicks begin_frame_time) { 217 void WindowAndroid::Animate(base::TimeTicks begin_frame_time) {
99 for (WindowAndroidObserver& observer : observer_list_) 218 for (WindowAndroidObserver& observer : observer_list_)
100 observer.OnAnimate(begin_frame_time); 219 observer.OnAnimate(begin_frame_time);
101 } 220 }
102 221
103 void WindowAndroid::OnVSync(JNIEnv* env, 222 void WindowAndroid::OnVSync(JNIEnv* env,
104 const JavaParamRef<jobject>& obj, 223 const JavaParamRef<jobject>& obj,
105 jlong time_micros, 224 jlong time_micros,
106 jlong period_micros) { 225 jlong period_micros) {
107 base::TimeTicks frame_time(base::TimeTicks::FromInternalValue(time_micros)); 226 base::TimeTicks frame_time(base::TimeTicks::FromInternalValue(time_micros));
108 base::TimeDelta vsync_period( 227 base::TimeDelta vsync_period(
109 base::TimeDelta::FromMicroseconds(period_micros)); 228 base::TimeDelta::FromMicroseconds(period_micros));
110 for (WindowAndroidObserver& observer : observer_list_) 229 begin_frame_source_->OnVSync(frame_time, vsync_period);
111 observer.OnVSync(frame_time, vsync_period); 230 if (needs_begin_frames_)
112 if (compositor_) 231 RequestVSyncUpdate();
113 compositor_->OnVSync(frame_time, vsync_period);
114 } 232 }
115 233
116 void WindowAndroid::OnVisibilityChanged(JNIEnv* env, 234 void WindowAndroid::OnVisibilityChanged(JNIEnv* env,
117 const JavaParamRef<jobject>& obj, 235 const JavaParamRef<jobject>& obj,
118 bool visible) { 236 bool visible) {
119 for (WindowAndroidObserver& observer : observer_list_) 237 for (WindowAndroidObserver& observer : observer_list_)
120 observer.OnRootWindowVisibilityChanged(visible); 238 observer.OnRootWindowVisibilityChanged(visible);
121 } 239 }
122 240
123 void WindowAndroid::OnActivityStopped(JNIEnv* env, 241 void WindowAndroid::OnActivityStopped(JNIEnv* env,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // ---------------------------------------------------------------------------- 278 // ----------------------------------------------------------------------------
161 // Native JNI methods 279 // Native JNI methods
162 // ---------------------------------------------------------------------------- 280 // ----------------------------------------------------------------------------
163 281
164 jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj, int sdk_display_id) { 282 jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj, int sdk_display_id) {
165 WindowAndroid* window = new WindowAndroid(env, obj, sdk_display_id); 283 WindowAndroid* window = new WindowAndroid(env, obj, sdk_display_id);
166 return reinterpret_cast<intptr_t>(window); 284 return reinterpret_cast<intptr_t>(window);
167 } 285 }
168 286
169 } // namespace ui 287 } // namespace ui
OLDNEW
« no previous file with comments | « ui/android/window_android.h ('k') | ui/android/window_android_compositor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698