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

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

Issue 2527283003: cc: Introduce BeginFrame sequence numbers and acknowledgements.
Patch Set: Address Sami's comments, DisplayScheduler observes while BFSObservers exist. 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
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 <stdint.h>
8 #include <unordered_set>
9
7 #include "base/android/context_utils.h" 10 #include "base/android/context_utils.h"
8 #include "base/android/jni_android.h" 11 #include "base/android/jni_android.h"
9 #include "base/android/jni_array.h" 12 #include "base/android/jni_array.h"
10 #include "base/android/jni_string.h" 13 #include "base/android/jni_string.h"
11 #include "base/android/jni_weak_ref.h" 14 #include "base/android/jni_weak_ref.h"
12 #include "base/android/scoped_java_ref.h" 15 #include "base/android/scoped_java_ref.h"
16 #include "base/auto_reset.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), next_sequence_number_(1), in_on_vsync_(false) {}
35 ~WindowBeginFrameSource() override {}
36
37 // cc::BeginFrameSource implementation.
38 void AddObserver(cc::BeginFrameObserver* obs) override;
39 void RemoveObserver(cc::BeginFrameObserver* obs) override;
40 void DidFinishFrame(cc::BeginFrameObserver* obs,
41 const cc::BeginFrameAck& ack) override {}
42 bool IsThrottled() const override { return true; }
43
44 void OnVSync(base::TimeTicks frame_time,
45 base::TimeDelta vsync_period);
46
47 private:
48 WindowAndroid* const window_;
49 std::unordered_set<cc::BeginFrameObserver*> observers_;
50 cc::BeginFrameArgs last_begin_frame_args_;
51 uint64_t next_sequence_number_;
52 bool in_on_vsync_;
53 };
54
55 void WindowAndroid::WindowBeginFrameSource::AddObserver(
56 cc::BeginFrameObserver* obs) {
57 DCHECK(obs);
58 DCHECK(observers_.find(obs) == observers_.end());
59
60 observers_.insert(obs);
61 obs->OnBeginFrameSourcePausedChanged(false);
62 window_->OnNeedsBeginFramesChange(true);
63
64 // Send a MISSED BeginFrame if possible and necessary. If an observer is added
65 // during OnVSync(), it will get a NORMAL BeginFrame from OnVSync() instead.
66 if (!in_on_vsync_ && last_begin_frame_args_.IsValid()) {
67 cc::BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
68 if (!last_args.IsValid() ||
69 last_args.sequence_number < last_begin_frame_args_.sequence_number) {
70 last_begin_frame_args_.type = cc::BeginFrameArgs::MISSED;
71 // TODO(crbug.com/602485): A deadline doesn't make too much sense
72 // for a missed BeginFrame (the intention rather is 'immediately'),
73 // but currently the retro frame logic is very strict in discarding
74 // BeginFrames.
75 last_begin_frame_args_.deadline =
76 base::TimeTicks::Now() + last_begin_frame_args_.interval;
77 obs->OnBeginFrame(last_begin_frame_args_);
78 }
79 }
80 }
81
82 void WindowAndroid::WindowBeginFrameSource::RemoveObserver(
83 cc::BeginFrameObserver* obs) {
84 DCHECK(obs);
85 DCHECK(observers_.find(obs) != observers_.end());
86
87 observers_.erase(obs);
88 if (observers_.empty())
89 window_->OnNeedsBeginFramesChange(false);
90 }
91
92 void WindowAndroid::WindowBeginFrameSource::OnVSync(
93 base::TimeTicks frame_time,
94 base::TimeDelta vsync_period) {
95 base::AutoReset<bool> auto_reset(&in_on_vsync_, true);
96
97 // frame time is in the past, so give the next vsync period as the deadline.
98 base::TimeTicks deadline = frame_time + vsync_period;
99 last_begin_frame_args_ = cc::BeginFrameArgs::Create(
100 BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_++, frame_time,
101 deadline, vsync_period, cc::BeginFrameArgs::NORMAL);
102 DCHECK(last_begin_frame_args_.IsValid());
103
104 // Support SynchronousCompositorBrowserFilter: Observers added during vsync
105 // distribution receive a NORMAL args in addition to the missed ones, after
106 // all current observers were notified. We also have to support observers
107 // removing themselves during OnBeginFrame, so we iterate on set copies until
108 // all observers were notified once.
109 std::unordered_set<cc::BeginFrameObserver*> notified_observers;
110 bool observer_was_notified = true;
111 while (observer_was_notified) {
112 observer_was_notified = false;
113 std::unordered_set<cc::BeginFrameObserver*> observers(observers_);
114 for (auto* obs : observers) {
115 if (notified_observers.find(obs) == notified_observers.end()) {
116 obs->OnBeginFrame(last_begin_frame_args_);
117 notified_observers.insert(obs);
118 observer_was_notified = true;
119 }
120 }
121 }
122 }
123
24 WindowAndroid::WindowAndroid(JNIEnv* env, jobject obj, int display_id) 124 WindowAndroid::WindowAndroid(JNIEnv* env, jobject obj, int display_id)
25 : display_id_(display_id), compositor_(NULL) { 125 : display_id_(display_id),
126 compositor_(NULL),
127 begin_frame_source_(new WindowBeginFrameSource(this)),
128 needs_begin_frames_(false) {
26 java_window_.Reset(env, obj); 129 java_window_.Reset(env, obj);
27 } 130 }
28 131
29 void WindowAndroid::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { 132 void WindowAndroid::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
30 delete this; 133 delete this;
31 } 134 }
32 135
33 ScopedJavaLocalRef<jobject> WindowAndroid::GetJavaObject() { 136 ScopedJavaLocalRef<jobject> WindowAndroid::GetJavaObject() {
34 return base::android::ScopedJavaLocalRef<jobject>(java_window_); 137 return base::android::ScopedJavaLocalRef<jobject>(java_window_);
35 } 138 }
(...skipping 26 matching lines...) Expand all
62 165
63 void WindowAndroid::AddObserver(WindowAndroidObserver* observer) { 166 void WindowAndroid::AddObserver(WindowAndroidObserver* observer) {
64 if (!observer_list_.HasObserver(observer)) 167 if (!observer_list_.HasObserver(observer))
65 observer_list_.AddObserver(observer); 168 observer_list_.AddObserver(observer);
66 } 169 }
67 170
68 void WindowAndroid::RemoveObserver(WindowAndroidObserver* observer) { 171 void WindowAndroid::RemoveObserver(WindowAndroidObserver* observer) {
69 observer_list_.RemoveObserver(observer); 172 observer_list_.RemoveObserver(observer);
70 } 173 }
71 174
175 cc::BeginFrameSource* WindowAndroid::GetBeginFrameSource() {
176 return begin_frame_source_.get();
177 }
178
72 void WindowAndroid::AttachCompositor(WindowAndroidCompositor* compositor) { 179 void WindowAndroid::AttachCompositor(WindowAndroidCompositor* compositor) {
73 if (compositor_ && compositor != compositor_) 180 if (compositor_ && compositor != compositor_)
74 DetachCompositor(); 181 DetachCompositor();
75 182
76 compositor_ = compositor; 183 compositor_ = compositor;
77 for (WindowAndroidObserver& observer : observer_list_) 184 for (WindowAndroidObserver& observer : observer_list_)
78 observer.OnAttachCompositor(); 185 observer.OnAttachCompositor();
79 } 186 }
80 187
81 void WindowAndroid::DetachCompositor() { 188 void WindowAndroid::DetachCompositor() {
(...skipping 18 matching lines...) Expand all
100 observer.OnAnimate(begin_frame_time); 207 observer.OnAnimate(begin_frame_time);
101 } 208 }
102 209
103 void WindowAndroid::OnVSync(JNIEnv* env, 210 void WindowAndroid::OnVSync(JNIEnv* env,
104 const JavaParamRef<jobject>& obj, 211 const JavaParamRef<jobject>& obj,
105 jlong time_micros, 212 jlong time_micros,
106 jlong period_micros) { 213 jlong period_micros) {
107 base::TimeTicks frame_time(base::TimeTicks::FromInternalValue(time_micros)); 214 base::TimeTicks frame_time(base::TimeTicks::FromInternalValue(time_micros));
108 base::TimeDelta vsync_period( 215 base::TimeDelta vsync_period(
109 base::TimeDelta::FromMicroseconds(period_micros)); 216 base::TimeDelta::FromMicroseconds(period_micros));
110 for (WindowAndroidObserver& observer : observer_list_) 217 begin_frame_source_->OnVSync(frame_time, vsync_period);
111 observer.OnVSync(frame_time, vsync_period); 218 if (needs_begin_frames_)
112 if (compositor_) 219 RequestVSyncUpdate();
113 compositor_->OnVSync(frame_time, vsync_period);
114 } 220 }
115 221
116 void WindowAndroid::OnVisibilityChanged(JNIEnv* env, 222 void WindowAndroid::OnVisibilityChanged(JNIEnv* env,
117 const JavaParamRef<jobject>& obj, 223 const JavaParamRef<jobject>& obj,
118 bool visible) { 224 bool visible) {
119 for (WindowAndroidObserver& observer : observer_list_) 225 for (WindowAndroidObserver& observer : observer_list_)
120 observer.OnRootWindowVisibilityChanged(visible); 226 observer.OnRootWindowVisibilityChanged(visible);
121 } 227 }
122 228
123 void WindowAndroid::OnActivityStopped(JNIEnv* env, 229 void WindowAndroid::OnActivityStopped(JNIEnv* env,
(...skipping 15 matching lines...) Expand all
139 base::android::ConvertUTF8ToJavaString(env, permission)); 245 base::android::ConvertUTF8ToJavaString(env, permission));
140 } 246 }
141 247
142 bool WindowAndroid::CanRequestPermission(const std::string& permission) { 248 bool WindowAndroid::CanRequestPermission(const std::string& permission) {
143 JNIEnv* env = AttachCurrentThread(); 249 JNIEnv* env = AttachCurrentThread();
144 return Java_WindowAndroid_canRequestPermission( 250 return Java_WindowAndroid_canRequestPermission(
145 env, GetJavaObject(), 251 env, GetJavaObject(),
146 base::android::ConvertUTF8ToJavaString(env, permission)); 252 base::android::ConvertUTF8ToJavaString(env, permission));
147 } 253 }
148 254
255 void WindowAndroid::OnNeedsBeginFramesChange(bool needs_begin_frames) {
256 if (needs_begin_frames_ == needs_begin_frames)
257 return;
258
259 needs_begin_frames_ = needs_begin_frames;
260 if (needs_begin_frames_)
261 RequestVSyncUpdate();
262 }
263
149 WindowAndroid* WindowAndroid::GetWindowAndroid() const { 264 WindowAndroid* WindowAndroid::GetWindowAndroid() const {
150 DCHECK(parent_ == nullptr); 265 DCHECK(parent_ == nullptr);
151 return const_cast<WindowAndroid*>(this); 266 return const_cast<WindowAndroid*>(this);
152 } 267 }
153 268
154 // ---------------------------------------------------------------------------- 269 // ----------------------------------------------------------------------------
155 // Native JNI methods 270 // Native JNI methods
156 // ---------------------------------------------------------------------------- 271 // ----------------------------------------------------------------------------
157 272
158 jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj, int sdk_display_id) { 273 jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj, int sdk_display_id) {
159 WindowAndroid* window = new WindowAndroid(env, obj, sdk_display_id); 274 WindowAndroid* window = new WindowAndroid(env, obj, sdk_display_id);
160 return reinterpret_cast<intptr_t>(window); 275 return reinterpret_cast<intptr_t>(window);
161 } 276 }
162 277
163 } // namespace ui 278 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698