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

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell.cc

Issue 2570553004: Clean up some VrShell threading issues and remove unnecessary WeakPtr types. (Closed)
Patch Set: 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "chrome/browser/android/vr_shell/vr_shell.h" 5 #include "chrome/browser/android/vr_shell/vr_shell.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "base/threading/platform_thread.h" 8 #include "base/threading/platform_thread.h"
9 #include "base/threading/thread.h" 9 #include "base/threading/thread.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
(...skipping 24 matching lines...) Expand all
35 35
36 namespace vr_shell { 36 namespace vr_shell {
37 37
38 namespace { 38 namespace {
39 vr_shell::VrShell* g_instance; 39 vr_shell::VrShell* g_instance;
40 40
41 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; 41 static const char kVrShellUIURL[] = "chrome://vr-shell-ui";
42 42
43 class GLThread : public base::Thread { 43 class GLThread : public base::Thread {
44 public: 44 public:
45 GLThread(VrShell* vr_shell, const base::WeakPtr<VrShell>& weak_vr_shell, 45 GLThread(VrShell* vr_shell, const base::WeakPtr<VrShell>& weak_vr_shell,
bshe 2016/12/14 16:06:46 looks like you can remove vr_shell too?
mthiesse 2016/12/14 16:20:43 Done.
46 const base::WeakPtr<VrInputManager>& content_input_manager, 46 const base::WeakPtr<VrInputManager>& content_input_manager,
47 const base::WeakPtr<VrInputManager>& ui_input_manager, 47 const base::WeakPtr<VrInputManager>& ui_input_manager,
48 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, 48 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
49 gvr_context* gvr_api) 49 gvr_context* gvr_api,
50 bool initially_web_vr)
50 : base::Thread("VrShellGL"), 51 : base::Thread("VrShellGL"),
51 vr_shell_(vr_shell),
52 weak_vr_shell_(weak_vr_shell), 52 weak_vr_shell_(weak_vr_shell),
53 content_input_manager_(content_input_manager), 53 content_input_manager_(content_input_manager),
54 ui_input_manager_(ui_input_manager), 54 ui_input_manager_(ui_input_manager),
55 main_thread_task_runner_(std::move(main_thread_task_runner)), 55 main_thread_task_runner_(std::move(main_thread_task_runner)),
56 gvr_api_(gvr_api) {} 56 gvr_api_(gvr_api),
57 initially_web_vr_(initially_web_vr) {}
57 58
58 ~GLThread() override { 59 ~GLThread() override {
59 Stop(); 60 Stop();
60 } 61 }
61 base::WeakPtr<VrShellGl> GetVrShellGl() { return weak_vr_shell_gl_; } 62 base::WeakPtr<VrShellGl> GetVrShellGl() { return weak_vr_shell_gl_; }
62 VrShellGl* GetVrShellGlUnsafe() { return vr_shell_gl_.get(); } 63 VrShellGl* GetVrShellGlUnsafe() { return vr_shell_gl_.get(); }
63 64
64 protected: 65 protected:
65 void Init() override { 66 void Init() override {
66 vr_shell_gl_.reset(new VrShellGl(vr_shell_, 67 vr_shell_gl_.reset(new VrShellGl(std::move(weak_vr_shell_),
67 std::move(weak_vr_shell_),
68 std::move(content_input_manager_), 68 std::move(content_input_manager_),
69 std::move(ui_input_manager_), 69 std::move(ui_input_manager_),
70 std::move(main_thread_task_runner_), 70 std::move(main_thread_task_runner_),
71 gvr_api_)); 71 gvr_api_,
72 initially_web_vr_));
72 weak_vr_shell_gl_ = vr_shell_gl_->GetWeakPtr(); 73 weak_vr_shell_gl_ = vr_shell_gl_->GetWeakPtr();
73 if (!vr_shell_gl_->Initialize()) { 74 if (!vr_shell_gl_->Initialize()) {
74 vr_shell_gl_.reset(); 75 vr_shell_gl_.reset();
75 } 76 }
76 } 77 }
77 void CleanUp() override { 78 void CleanUp() override {
78 vr_shell_gl_.reset(); 79 vr_shell_gl_.reset();
79 } 80 }
80 81
81 private: 82 private:
82 // Created on GL thread. 83 // Created on GL thread.
83 std::unique_ptr<VrShellGl> vr_shell_gl_; 84 std::unique_ptr<VrShellGl> vr_shell_gl_;
84 base::WeakPtr<VrShellGl> weak_vr_shell_gl_; 85 base::WeakPtr<VrShellGl> weak_vr_shell_gl_;
85 86
86 // Created on main thread.
87 // TODO(mthiesse): Remove vr_shell_.
88 VrShell* vr_shell_;
89 base::WeakPtr<VrShell> weak_vr_shell_; 87 base::WeakPtr<VrShell> weak_vr_shell_;
90 base::WeakPtr<VrInputManager> content_input_manager_; 88 base::WeakPtr<VrInputManager> content_input_manager_;
91 base::WeakPtr<VrInputManager> ui_input_manager_; 89 base::WeakPtr<VrInputManager> ui_input_manager_;
92 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; 90 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
93 gvr_context* gvr_api_; 91 gvr_context* gvr_api_;
92 bool initially_web_vr_;
94 }; 93 };
95 94
96 } // namespace 95 } // namespace
97 96
98 VrShell::VrShell(JNIEnv* env, 97 VrShell::VrShell(JNIEnv* env,
99 jobject obj, 98 jobject obj,
100 content::WebContents* main_contents, 99 content::WebContents* main_contents,
101 ui::WindowAndroid* content_window, 100 ui::WindowAndroid* content_window,
102 content::WebContents* ui_contents, 101 content::WebContents* ui_contents,
103 ui::WindowAndroid* ui_window, 102 ui::WindowAndroid* ui_window,
(...skipping 11 matching lines...) Expand all
115 g_instance = this; 114 g_instance = this;
116 j_vr_shell_.Reset(env, obj); 115 j_vr_shell_.Reset(env, obj);
117 116
118 content_input_manager_.reset(new VrInputManager(main_contents_)); 117 content_input_manager_.reset(new VrInputManager(main_contents_));
119 ui_input_manager_.reset(new VrInputManager(ui_contents_)); 118 ui_input_manager_.reset(new VrInputManager(ui_contents_));
120 119
121 gl_thread_.reset(new GLThread(this, weak_ptr_factory_.GetWeakPtr(), 120 gl_thread_.reset(new GLThread(this, weak_ptr_factory_.GetWeakPtr(),
122 content_input_manager_->GetWeakPtr(), 121 content_input_manager_->GetWeakPtr(),
123 ui_input_manager_->GetWeakPtr(), 122 ui_input_manager_->GetWeakPtr(),
124 main_thread_task_runner_, 123 main_thread_task_runner_,
125 gvr_api)); 124 gvr_api,
125 for_web_vr));
126 126
127 base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0); 127 base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0);
128 options.priority = base::ThreadPriority::DISPLAY; 128 options.priority = base::ThreadPriority::DISPLAY;
129 gl_thread_->StartWithOptions(options); 129 gl_thread_->StartWithOptions(options);
130 130
131 if (for_web_vr) 131 if (for_web_vr)
132 metrics_helper_->SetWebVREnabled(true); 132 metrics_helper_->SetWebVREnabled(true);
133 html_interface_.reset(new UiInterface( 133 html_interface_.reset(new UiInterface(
134 for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD, 134 for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD,
135 main_contents_->IsFullscreen())); 135 main_contents_->IsFullscreen()));
136
136 content_compositor_.reset(new VrCompositor(content_window, false)); 137 content_compositor_.reset(new VrCompositor(content_window, false));
137 content_compositor_->SetLayer(main_contents_); 138 content_compositor_->SetLayer(main_contents_);
138 ui_compositor_.reset(new VrCompositor(ui_window, true)); 139 ui_compositor_.reset(new VrCompositor(ui_window, true));
139 ui_compositor_->SetLayer(ui_contents_); 140 ui_compositor_->SetLayer(ui_contents_);
140 vr_web_contents_observer_.reset(new VrWebContentsObserver( 141 vr_web_contents_observer_.reset(new VrWebContentsObserver(
141 main_contents, html_interface_.get(), this)); 142 main_contents, html_interface_.get(), this));
142 143
143 SetShowingOverscrollGlow(false); 144 SetShowingOverscrollGlow(false);
144 } 145 }
145 146
(...skipping 25 matching lines...) Expand all
171 // regarding jank in this case, because we're switching from 3D to 2D, 172 // regarding jank in this case, because we're switching from 3D to 2D,
172 // adding/removing a bunch of Java views, and probably changing device 173 // adding/removing a bunch of Java views, and probably changing device
173 // orientation here. 174 // orientation here.
174 base::ThreadRestrictions::ScopedAllowIO allow_io; 175 base::ThreadRestrictions::ScopedAllowIO allow_io;
175 gl_thread_.reset(); 176 gl_thread_.reset();
176 } 177 }
177 delegate_->RemoveDelegate(); 178 delegate_->RemoveDelegate();
178 g_instance = nullptr; 179 g_instance = nullptr;
179 } 180 }
180 181
182 void VrShell::PostToGlThreadWhenReady(const base::Closure& task) {
183 // TODO(mthiesse): Remove this blocking wait. Queue up events if thread isn't
184 // finished starting?
185 gl_thread_->WaitUntilThreadStarted();
186 gl_thread_->task_runner()->PostTask(FROM_HERE, task);
187 }
188
181 void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) { 189 void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) {
182 GLThread* thread = static_cast<GLThread*>(gl_thread_.get()); 190 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
183 if (thread->GetVrShellGlUnsafe()) { 191 if (thread->GetVrShellGlUnsafe()) {
184 thread->GetVrShellGlUnsafe()->SetGvrPoseForWebVr(pose, pose_num); 192 thread->GetVrShellGlUnsafe()->SetGvrPoseForWebVr(pose, pose_num);
185 } 193 }
186 } 194 }
187 195
188 void VrShell::SetWebVRRenderSurfaceSize(int width, int height) { 196 void VrShell::SetWebVRRenderSurfaceSize(int width, int height) {
189 GLThread* thread = static_cast<GLThread*>(gl_thread_.get()); 197 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
190 if (thread->GetVrShellGlUnsafe()) { 198 if (thread->GetVrShellGlUnsafe()) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 void VrShell::OnDomContentsLoaded() { 253 void VrShell::OnDomContentsLoaded() {
246 html_interface_->SetURL(main_contents_->GetVisibleURL()); 254 html_interface_->SetURL(main_contents_->GetVisibleURL());
247 html_interface_->SetLoading(main_contents_->IsLoading()); 255 html_interface_->SetLoading(main_contents_->IsLoading());
248 html_interface_->OnDomContentsLoaded(); 256 html_interface_->OnDomContentsLoaded();
249 } 257 }
250 258
251 void VrShell::SetWebVrMode(JNIEnv* env, 259 void VrShell::SetWebVrMode(JNIEnv* env,
252 const base::android::JavaParamRef<jobject>& obj, 260 const base::android::JavaParamRef<jobject>& obj,
253 bool enabled) { 261 bool enabled) {
254 metrics_helper_->SetWebVREnabled(enabled); 262 metrics_helper_->SetWebVREnabled(enabled);
263 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
264 PostToGlThreadWhenReady(
265 base::Bind(&VrShellGl::SetWebVrMode, thread->GetVrShellGl(), enabled));
bshe 2016/12/14 16:06:46 is thread->GetVrShellGl() evaluated when the task
mthiesse 2016/12/14 16:20:43 If the WeakPtr at thread->GetVrShellGl() is null,
bshe 2016/12/14 17:36:51 For optional tasks, I would prefer to use IsRunnin
mthiesse 2016/12/14 21:25:36 Done.
255 if (enabled) { 266 if (enabled) {
256 html_interface_->SetMode(UiInterface::Mode::WEB_VR); 267 html_interface_->SetMode(UiInterface::Mode::WEB_VR);
257 } else { 268 } else {
258 html_interface_->SetMode(UiInterface::Mode::STANDARD); 269 html_interface_->SetMode(UiInterface::Mode::STANDARD);
259 } 270 }
260 } 271 }
261 272
262 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { 273 void VrShell::SetWebVRSecureOrigin(bool secure_origin) {
263 // TODO(cjgrant): Align this state with the logic that drives the omnibox. 274 // TODO(cjgrant): Align this state with the logic that drives the omnibox.
264 html_interface_->SetWebVRSecureOrigin(secure_origin); 275 html_interface_->SetWebVRSecureOrigin(secure_origin);
(...skipping 20 matching lines...) Expand all
285 CHECK(false); 296 CHECK(false);
286 return nullptr; 297 return nullptr;
287 } 298 }
288 299
289 void VrShell::SurfacesChanged(jobject content_surface, jobject ui_surface) { 300 void VrShell::SurfacesChanged(jobject content_surface, jobject ui_surface) {
290 content_compositor_->SurfaceChanged(content_surface); 301 content_compositor_->SurfaceChanged(content_surface);
291 ui_compositor_->SurfaceChanged(ui_surface); 302 ui_compositor_->SurfaceChanged(ui_surface);
292 } 303 }
293 304
294 void VrShell::GvrDelegateReady() { 305 void VrShell::GvrDelegateReady() {
295 delegate_->SetDelegate(weak_ptr_factory_.GetWeakPtr()); 306 delegate_->SetDelegate(this);
307 }
308
309 void VrShell::AppButtonPressed() {
310 #if defined(ENABLE_VR_SHELL)
311 html_interface_->SetMenuMode(!html_interface_->GetMenuMode());
312
313 // TODO(mthiesse): The page is no longer visible when in menu mode. We
314 // should unfocus or otherwise let it know it's hidden.
315 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) {
316 if (delegate_->device_provider()) {
317 if (html_interface_->GetMenuMode()) {
318 delegate_->device_provider()->OnDisplayBlur();
319 } else {
320 delegate_->device_provider()->OnDisplayFocus();
321 }
322 }
323 }
324 #endif
296 } 325 }
297 326
298 void VrShell::ContentBoundsChanged(JNIEnv* env, 327 void VrShell::ContentBoundsChanged(JNIEnv* env,
299 const JavaParamRef<jobject>& object, 328 const JavaParamRef<jobject>& object,
300 jint width, jint height, jfloat dpr) { 329 jint width, jint height, jfloat dpr) {
301 TRACE_EVENT0("gpu", "VrShell::ContentBoundsChanged"); 330 TRACE_EVENT0("gpu", "VrShell::ContentBoundsChanged");
302 GLThread* thread = static_cast<GLThread*>(gl_thread_.get()); 331 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
303 // TODO(mthiesse): Remove this blocking wait. Queue up events if thread isn't 332 PostToGlThreadWhenReady(base::Bind(&VrShellGl::ContentPhysicalBoundsChanged,
304 // finished starting? 333 thread->GetVrShellGl(), width, height));
305 thread->WaitUntilThreadStarted();
306 CHECK(thread->task_runner()->PostTask(
307 FROM_HERE, base::Bind(&VrShellGl::ContentPhysicalBoundsChanged,
308 thread->GetVrShellGl(),
309 width, height)));
310 content_compositor_->SetWindowBounds(width, height); 334 content_compositor_->SetWindowBounds(width, height);
311 } 335 }
312 336
313 void VrShell::UIBoundsChanged(JNIEnv* env, 337 void VrShell::UIBoundsChanged(JNIEnv* env,
314 const JavaParamRef<jobject>& object, 338 const JavaParamRef<jobject>& object,
315 jint width, jint height, jfloat dpr) { 339 jint width, jint height, jfloat dpr) {
316 GLThread* thread = static_cast<GLThread*>(gl_thread_.get()); 340 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
317 // TODO(mthiesse): Remove this blocking wait. Queue up events if thread isn't 341 PostToGlThreadWhenReady(base::Bind(&VrShellGl::UIPhysicalBoundsChanged,
318 // finished starting? 342 thread->GetVrShellGl(), width, height));
319 thread->WaitUntilThreadStarted();
320 thread->task_runner()->PostTask(
321 FROM_HERE, base::Bind(&VrShellGl::UIPhysicalBoundsChanged,
322 thread->GetVrShellGl(),
323 width, height));
324 ui_compositor_->SetWindowBounds(width, height); 343 ui_compositor_->SetWindowBounds(width, height);
325 } 344 }
326 345
327 UiScene* VrShell::GetScene() { 346 UiScene* VrShell::GetScene() {
328 GLThread* thread = static_cast<GLThread*>(gl_thread_.get()); 347 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
329 // TODO(mthiesse): Remove this blocking wait. Queue up events if thread isn't 348 // TODO(mthiesse): Remove this blocking wait. Queue up events if thread isn't
330 // finished starting? 349 // finished starting?
331 thread->WaitUntilThreadStarted(); 350 thread->WaitUntilThreadStarted();
332 if (thread->GetVrShellGlUnsafe()) { 351 if (thread->GetVrShellGlUnsafe()) {
333 return thread->GetVrShellGlUnsafe()->GetScene(); 352 return thread->GetVrShellGlUnsafe()->GetScene();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 397
379 void VrShell::RenderViewHostChanged(content::RenderViewHost* old_host, 398 void VrShell::RenderViewHostChanged(content::RenderViewHost* old_host,
380 content::RenderViewHost* new_host) { 399 content::RenderViewHost* new_host) {
381 new_host->GetWidget()->GetView()->SetBackgroundColor(SK_ColorTRANSPARENT); 400 new_host->GetWidget()->GetView()->SetBackgroundColor(SK_ColorTRANSPARENT);
382 } 401 }
383 402
384 void VrShell::MainFrameWasResized(bool width_changed) { 403 void VrShell::MainFrameWasResized(bool width_changed) {
385 display::Display display = display::Screen::GetScreen() 404 display::Display display = display::Screen::GetScreen()
386 ->GetDisplayNearestWindow(ui_contents_->GetNativeView()); 405 ->GetDisplayNearestWindow(ui_contents_->GetNativeView());
387 GLThread* thread = static_cast<GLThread*>(gl_thread_.get()); 406 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
388 // TODO(mthiesse): Remove this blocking wait. Queue up events if thread isn't 407 PostToGlThreadWhenReady(
389 // finished starting? 408 base::Bind(&VrShellGl::UIBoundsChanged, thread->GetVrShellGl(),
390 thread->WaitUntilThreadStarted(); 409 display.size().width(), display.size().height()));
391 thread->task_runner()->PostTask(
392 FROM_HERE, base::Bind(&VrShellGl::UIBoundsChanged,
393 thread->GetVrShellGl(),
394 display.size().width(), display.size().height()));
395 } 410 }
396 411
397 void VrShell::ContentFrameWasResized(bool width_changed) { 412 void VrShell::ContentFrameWasResized(bool width_changed) {
398 display::Display display = display::Screen::GetScreen() 413 display::Display display = display::Screen::GetScreen()
399 ->GetDisplayNearestWindow(main_contents_->GetNativeView()); 414 ->GetDisplayNearestWindow(main_contents_->GetNativeView());
400 GLThread* thread = static_cast<GLThread*>(gl_thread_.get()); 415 GLThread* thread = static_cast<GLThread*>(gl_thread_.get());
401 // TODO(mthiesse): Remove this blocking wait. Queue up events if thread isn't 416 PostToGlThreadWhenReady(
402 // finished starting? 417 base::Bind(&VrShellGl::ContentBoundsChanged, thread->GetVrShellGl(),
403 thread->WaitUntilThreadStarted(); 418 display.size().width(), display.size().height()));
404 thread->task_runner()->PostTask(
405 FROM_HERE, base::Bind(&VrShellGl::ContentBoundsChanged,
406 thread->GetVrShellGl(),
407 display.size().width(), display.size().height()));
408 } 419 }
409 420
410 void VrShell::WebContentsDestroyed() { 421 void VrShell::WebContentsDestroyed() {
411 ui_input_manager_.reset(); 422 ui_input_manager_.reset();
412 ui_contents_ = nullptr; 423 ui_contents_ = nullptr;
413 // TODO(mthiesse): Handle web contents being destroyed. 424 // TODO(mthiesse): Handle web contents being destroyed.
414 ForceExitVR(); 425 ForceExitVR();
415 } 426 }
416 427
417 void VrShell::ContentWebContentsDestroyed() { 428 void VrShell::ContentWebContentsDestroyed() {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 return reinterpret_cast<intptr_t>(new VrShell( 468 return reinterpret_cast<intptr_t>(new VrShell(
458 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), 469 env, obj, content::WebContents::FromJavaWebContents(content_web_contents),
459 reinterpret_cast<ui::WindowAndroid*>(content_window_android), 470 reinterpret_cast<ui::WindowAndroid*>(content_window_android),
460 content::WebContents::FromJavaWebContents(ui_web_contents), 471 content::WebContents::FromJavaWebContents(ui_web_contents),
461 reinterpret_cast<ui::WindowAndroid*>(ui_window_android), 472 reinterpret_cast<ui::WindowAndroid*>(ui_window_android),
462 for_web_vr, VrShellDelegate::GetNativeDelegate(env, delegate), 473 for_web_vr, VrShellDelegate::GetNativeDelegate(env, delegate),
463 reinterpret_cast<gvr_context*>(gvr_api))); 474 reinterpret_cast<gvr_context*>(gvr_api)));
464 } 475 }
465 476
466 } // namespace vr_shell 477 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698