OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "android_webview/native/aw_contents.h" | 5 #include "android_webview/native/aw_contents.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "android_webview/browser/aw_browser_context.h" | 9 #include "android_webview/browser/aw_browser_context.h" |
10 #include "android_webview/browser/aw_browser_main_parts.h" | 10 #include "android_webview/browser/aw_browser_main_parts.h" |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 jint GetNativeInstanceCount(JNIEnv* env, jclass) { | 319 jint GetNativeInstanceCount(JNIEnv* env, jclass) { |
320 return base::subtle::NoBarrier_Load(&g_instance_count); | 320 return base::subtle::NoBarrier_Load(&g_instance_count); |
321 } | 321 } |
322 | 322 |
323 jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { | 323 jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { |
324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
325 return reinterpret_cast<intptr_t>(this); | 325 return reinterpret_cast<intptr_t>(this); |
326 } | 326 } |
327 | 327 |
328 void AwContents::DrawGL(AwDrawGLInfo* draw_info) { | 328 void AwContents::DrawGL(AwDrawGLInfo* draw_info) { |
329 GLViewRendererManager::GetInstance()->DidDrawGL(renderer_manager_key_); | 329 { |
| 330 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); |
| 331 base::AutoLock lock(render_thread_lock_); |
| 332 if (renderer_manager_key_ != manager->NullKey()) { |
| 333 manager->DidDrawGL(renderer_manager_key_); |
| 334 } |
| 335 } |
330 | 336 |
331 ScopedAppGLStateRestore state_restore( | 337 ScopedAppGLStateRestore state_restore( |
332 draw_info->mode == AwDrawGLInfo::kModeDraw | 338 draw_info->mode == AwDrawGLInfo::kModeDraw |
333 ? ScopedAppGLStateRestore::MODE_DRAW | 339 ? ScopedAppGLStateRestore::MODE_DRAW |
334 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | 340 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); |
335 ScopedAllowGL allow_gl; | 341 ScopedAllowGL allow_gl; |
336 | 342 |
337 for (base::Closure c = shared_renderer_state_.PopFrontClosure(); !c.is_null(); | 343 if (!shared_renderer_state_.IsHardwareAllowed()) { |
338 c = shared_renderer_state_.PopFrontClosure()) { | 344 hardware_renderer_.reset(); |
339 c.Run(); | 345 shared_renderer_state_.SetHardwareInitialized(false); |
| 346 return; |
340 } | 347 } |
341 | 348 |
342 if (!hardware_renderer_) | 349 if (draw_info->mode != AwDrawGLInfo::kModeDraw) |
343 return; | 350 return; |
344 | 351 |
345 // TODO(boliu): Make this a task as well. | 352 if (!hardware_renderer_) { |
| 353 DCHECK(!shared_renderer_state_.IsHardwareInitialized()); |
| 354 hardware_renderer_.reset(new HardwareRenderer(&shared_renderer_state_)); |
| 355 shared_renderer_state_.SetHardwareInitialized(true); |
| 356 } |
| 357 |
346 DrawGLResult result; | 358 DrawGLResult result; |
347 if (hardware_renderer_->DrawGL(state_restore.stencil_enabled(), | 359 if (hardware_renderer_->DrawGL(state_restore.stencil_enabled(), |
348 state_restore.framebuffer_binding_ext(), | 360 state_restore.framebuffer_binding_ext(), |
349 draw_info, | 361 draw_info, |
350 &result)) { | 362 &result)) { |
351 browser_view_renderer_.DidDrawGL(result); | 363 browser_view_renderer_.DidDrawGL(result); |
352 } | 364 } |
353 } | 365 } |
354 | 366 |
355 namespace { | 367 namespace { |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 if (cvc) { | 782 if (cvc) { |
771 cvc->PauseOrResumeGeolocation(paused); | 783 cvc->PauseOrResumeGeolocation(paused); |
772 if (paused) { | 784 if (paused) { |
773 cvc->PauseVideo(); | 785 cvc->PauseVideo(); |
774 } | 786 } |
775 } | 787 } |
776 } | 788 } |
777 | 789 |
778 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { | 790 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { |
779 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 792 shared_renderer_state_.SetHardwareAllowed(true); |
780 browser_view_renderer_.OnAttachedToWindow(w, h); | 793 browser_view_renderer_.OnAttachedToWindow(w, h); |
781 } | 794 } |
782 | 795 |
783 void AwContents::InitializeHardwareDrawIfNeeded() { | 796 void AwContents::InitializeHardwareDrawIfNeeded() { |
784 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); | 797 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); |
| 798 |
| 799 base::AutoLock lock(render_thread_lock_); |
785 if (renderer_manager_key_ == manager->NullKey()) { | 800 if (renderer_manager_key_ == manager->NullKey()) { |
786 // Add task but don't schedule it. It will run when DrawGL is called for | |
787 // the first time. | |
788 shared_renderer_state_.AppendClosure( | |
789 base::Bind(&AwContents::InitializeHardwareDrawOnRenderThread, | |
790 base::Unretained(this))); | |
791 renderer_manager_key_ = manager->PushBack(&shared_renderer_state_); | 801 renderer_manager_key_ = manager->PushBack(&shared_renderer_state_); |
792 DeferredGpuCommandService::SetInstance(); | 802 DeferredGpuCommandService::SetInstance(); |
793 } | 803 } |
794 } | 804 } |
795 | 805 |
796 void AwContents::InitializeHardwareDrawOnRenderThread() { | |
797 DCHECK(!hardware_renderer_); | |
798 DCHECK(!shared_renderer_state_.IsHardwareInitialized()); | |
799 hardware_renderer_.reset(new HardwareRenderer(&shared_renderer_state_)); | |
800 shared_renderer_state_.SetHardwareInitialized(true); | |
801 } | |
802 | |
803 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { | 806 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { |
804 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 807 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 808 shared_renderer_state_.SetHardwareAllowed(false); |
805 | 809 |
806 shared_renderer_state_.ClearClosureQueue(); | 810 bool hardware_initialized = shared_renderer_state_.IsHardwareInitialized(); |
807 shared_renderer_state_.AppendClosure(base::Bind( | 811 if (hardware_initialized) { |
808 &AwContents::ReleaseHardwareDrawOnRenderThread, base::Unretained(this))); | 812 bool draw_functor_succeeded = RequestDrawGL(NULL, true); |
809 bool draw_functor_succeeded = RequestDrawGL(NULL, true); | 813 if (!draw_functor_succeeded && hardware_initialized) { |
810 if (!draw_functor_succeeded && | 814 LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?"; |
811 shared_renderer_state_.IsHardwareInitialized()) { | 815 // Calling release on wrong thread intentionally. |
812 LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?"; | 816 AwDrawGLInfo info; |
813 // Calling release on wrong thread intentionally. | 817 info.mode = AwDrawGLInfo::kModeProcess; |
814 AwDrawGLInfo info; | 818 DrawGL(&info); |
815 info.mode = AwDrawGLInfo::kModeProcess; | 819 } |
816 DrawGL(&info); | |
817 } else { | |
818 shared_renderer_state_.ClearClosureQueue(); | |
819 } | 820 } |
820 | 821 |
| 822 DCHECK(!hardware_renderer_); |
821 browser_view_renderer_.OnDetachedFromWindow(); | 823 browser_view_renderer_.OnDetachedFromWindow(); |
822 | 824 |
823 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); | 825 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); |
824 if (renderer_manager_key_ != manager->NullKey()) { | 826 |
825 manager->Remove(renderer_manager_key_); | 827 { |
826 renderer_manager_key_ = manager->NullKey(); | 828 base::AutoLock lock(render_thread_lock_); |
| 829 if (renderer_manager_key_ != manager->NullKey()) { |
| 830 manager->Remove(renderer_manager_key_); |
| 831 renderer_manager_key_ = manager->NullKey(); |
| 832 } |
| 833 } |
| 834 |
| 835 if (hardware_initialized) { |
| 836 // Flush any invoke functors that's caused by OnDetachedFromWindow. |
| 837 RequestDrawGL(NULL, true); |
827 } | 838 } |
828 } | 839 } |
829 | 840 |
830 void AwContents::ReleaseHardwareDrawOnRenderThread() { | |
831 // No point in running any other commands if we released hardware already. | |
832 shared_renderer_state_.ClearClosureQueue(); | |
833 if (!shared_renderer_state_.IsHardwareInitialized()) | |
834 return; | |
835 | |
836 hardware_renderer_.reset(); | |
837 shared_renderer_state_.SetHardwareInitialized(false); | |
838 } | |
839 | |
840 base::android::ScopedJavaLocalRef<jbyteArray> | 841 base::android::ScopedJavaLocalRef<jbyteArray> |
841 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { | 842 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { |
842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 843 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
843 // Required optimization in WebViewClassic to not save any state if | 844 // Required optimization in WebViewClassic to not save any state if |
844 // there has been no navigations. | 845 // there has been no navigations. |
845 if (!web_contents_->GetController().GetEntryCount()) | 846 if (!web_contents_->GetController().GetEntryCount()) |
846 return ScopedJavaLocalRef<jbyteArray>(); | 847 return ScopedJavaLocalRef<jbyteArray>(); |
847 | 848 |
848 Pickle pickle; | 849 Pickle pickle; |
849 if (!WriteToPickle(*web_contents_, &pickle)) { | 850 if (!WriteToPickle(*web_contents_, &pickle)) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 return; | 1084 return; |
1084 | 1085 |
1085 browser_view_renderer_.TrimMemory(level, visible); | 1086 browser_view_renderer_.TrimMemory(level, visible); |
1086 } | 1087 } |
1087 | 1088 |
1088 void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) { | 1089 void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) { |
1089 g_should_download_favicons = true; | 1090 g_should_download_favicons = true; |
1090 } | 1091 } |
1091 | 1092 |
1092 } // namespace android_webview | 1093 } // namespace android_webview |
OLD | NEW |