| 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" |
| 11 #include "android_webview/browser/aw_resource_context.h" | 11 #include "android_webview/browser/aw_resource_context.h" |
| 12 #include "android_webview/browser/browser_view_renderer.h" | 12 #include "android_webview/browser/browser_view_renderer.h" |
| 13 #include "android_webview/browser/deferred_gpu_command_service.h" | 13 #include "android_webview/browser/deferred_gpu_command_service.h" |
| 14 #include "android_webview/browser/hardware_renderer.h" | |
| 15 #include "android_webview/browser/net_disk_cache_remover.h" | 14 #include "android_webview/browser/net_disk_cache_remover.h" |
| 16 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele
gate.h" | 15 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele
gate.h" |
| 17 #include "android_webview/browser/scoped_app_gl_state_restore.h" | 16 #include "android_webview/browser/scoped_app_gl_state_restore.h" |
| 18 #include "android_webview/common/aw_hit_test_data.h" | 17 #include "android_webview/common/aw_hit_test_data.h" |
| 19 #include "android_webview/common/devtools_instrumentation.h" | 18 #include "android_webview/common/devtools_instrumentation.h" |
| 20 #include "android_webview/native/aw_autofill_client.h" | 19 #include "android_webview/native/aw_autofill_client.h" |
| 21 #include "android_webview/native/aw_browser_dependency_factory.h" | 20 #include "android_webview/native/aw_browser_dependency_factory.h" |
| 22 #include "android_webview/native/aw_contents_client_bridge.h" | 21 #include "android_webview/native/aw_contents_client_bridge.h" |
| 23 #include "android_webview/native/aw_contents_io_thread_client_impl.h" | 22 #include "android_webview/native/aw_contents_io_thread_client_impl.h" |
| 24 #include "android_webview/native/aw_pdf_exporter.h" | 23 #include "android_webview/native/aw_pdf_exporter.h" |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 258 JNIEnv* env = AttachCurrentThread(); | 257 JNIEnv* env = AttachCurrentThread(); |
| 259 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 258 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 260 if (obj.is_null()) | 259 if (obj.is_null()) |
| 261 return; | 260 return; |
| 262 Java_AwContents_setAwAutofillClient(env, obj.obj(), client); | 261 Java_AwContents_setAwAutofillClient(env, obj.obj(), client); |
| 263 } | 262 } |
| 264 | 263 |
| 265 AwContents::~AwContents() { | 264 AwContents::~AwContents() { |
| 266 DCHECK_EQ(this, AwContents::FromWebContents(web_contents_.get())); | 265 DCHECK_EQ(this, AwContents::FromWebContents(web_contents_.get())); |
| 267 DCHECK(!hardware_renderer_.get()); | |
| 268 web_contents_->RemoveUserData(kAwContentsUserDataKey); | 266 web_contents_->RemoveUserData(kAwContentsUserDataKey); |
| 269 if (find_helper_.get()) | 267 if (find_helper_.get()) |
| 270 find_helper_->SetListener(NULL); | 268 find_helper_->SetListener(NULL); |
| 271 if (icon_helper_.get()) | 269 if (icon_helper_.get()) |
| 272 icon_helper_->SetListener(NULL); | 270 icon_helper_->SetListener(NULL); |
| 273 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, -1); | 271 base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, -1); |
| 274 // When the last WebView is destroyed free all discardable memory allocated by | 272 // When the last WebView is destroyed free all discardable memory allocated by |
| 275 // Chromium, because the app process may continue to run for a long time | 273 // Chromium, because the app process may continue to run for a long time |
| 276 // without ever using another WebView. | 274 // without ever using another WebView. |
| 277 if (base::subtle::NoBarrier_Load(&g_instance_count) == 0) { | 275 if (base::subtle::NoBarrier_Load(&g_instance_count) == 0) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 // static | 331 // static |
| 334 jint GetNativeInstanceCount(JNIEnv* env, jclass) { | 332 jint GetNativeInstanceCount(JNIEnv* env, jclass) { |
| 335 return base::subtle::NoBarrier_Load(&g_instance_count); | 333 return base::subtle::NoBarrier_Load(&g_instance_count); |
| 336 } | 334 } |
| 337 | 335 |
| 338 jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { | 336 jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { |
| 339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 340 return reinterpret_cast<intptr_t>(this); | 338 return reinterpret_cast<intptr_t>(this); |
| 341 } | 339 } |
| 342 | 340 |
| 343 // TODO(hush): move this function to SharedRendererState. | |
| 344 void AwContents::DrawGL(AwDrawGLInfo* draw_info) { | 341 void AwContents::DrawGL(AwDrawGLInfo* draw_info) { |
| 345 if (draw_info->mode == AwDrawGLInfo::kModeSync) { | 342 shared_renderer_state_->DrawGL(draw_info); |
| 346 if (hardware_renderer_) | |
| 347 hardware_renderer_->CommitFrame(); | |
| 348 return; | |
| 349 } | |
| 350 | |
| 351 { | |
| 352 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); | |
| 353 base::AutoLock lock(render_thread_lock_); | |
| 354 if (renderer_manager_key_ != manager->NullKey()) { | |
| 355 manager->DidDrawGL(renderer_manager_key_); | |
| 356 } | |
| 357 } | |
| 358 | |
| 359 ScopedAppGLStateRestore state_restore( | |
| 360 draw_info->mode == AwDrawGLInfo::kModeDraw | |
| 361 ? ScopedAppGLStateRestore::MODE_DRAW | |
| 362 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | |
| 363 ScopedAllowGL allow_gl; | |
| 364 | |
| 365 if (draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { | |
| 366 LOG(ERROR) << "Received unexpected kModeProcessNoContext"; | |
| 367 } | |
| 368 | |
| 369 // kModeProcessNoContext should never happen because we tear down hardware | |
| 370 // in onTrimMemory. However that guarantee is maintained outside of chromium | |
| 371 // code. Not notifying shared state in kModeProcessNoContext can lead to | |
| 372 // immediate deadlock, which is slightly more catastrophic than leaks or | |
| 373 // corruption. | |
| 374 if (draw_info->mode == AwDrawGLInfo::kModeProcess || | |
| 375 draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { | |
| 376 shared_renderer_state_->DidDrawGLProcess(); | |
| 377 } | |
| 378 | |
| 379 if (shared_renderer_state_->IsInsideHardwareRelease()) { | |
| 380 hardware_renderer_.reset(); | |
| 381 // Flush the idle queue in tear down. | |
| 382 DeferredGpuCommandService::GetInstance()->PerformAllIdleWork(); | |
| 383 return; | |
| 384 } | |
| 385 | |
| 386 if (draw_info->mode != AwDrawGLInfo::kModeDraw) { | |
| 387 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { | |
| 388 DeferredGpuCommandService::GetInstance()->PerformIdleWork(true); | |
| 389 } | |
| 390 return; | |
| 391 } | |
| 392 | |
| 393 if (!hardware_renderer_) { | |
| 394 hardware_renderer_.reset(new HardwareRenderer(shared_renderer_state_)); | |
| 395 hardware_renderer_->CommitFrame(); | |
| 396 } | |
| 397 | |
| 398 hardware_renderer_->DrawGL(state_restore.stencil_enabled(), | |
| 399 state_restore.framebuffer_binding_ext(), | |
| 400 draw_info); | |
| 401 DeferredGpuCommandService::GetInstance()->PerformIdleWork(false); | |
| 402 } | 343 } |
| 403 | 344 |
| 404 namespace { | 345 namespace { |
| 405 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message, | 346 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message, |
| 406 bool has_images) { | 347 bool has_images) { |
| 407 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), | 348 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), |
| 408 has_images, | 349 has_images, |
| 409 message.obj()); | 350 message.obj()); |
| 410 } | 351 } |
| 411 } // namespace | 352 } // namespace |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 cvc->PauseOrResumeGeolocation(paused); | 814 cvc->PauseOrResumeGeolocation(paused); |
| 874 } | 815 } |
| 875 } | 816 } |
| 876 | 817 |
| 877 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { | 818 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { |
| 878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 819 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 879 browser_view_renderer_.OnAttachedToWindow(w, h); | 820 browser_view_renderer_.OnAttachedToWindow(w, h); |
| 880 } | 821 } |
| 881 | 822 |
| 882 void AwContents::InitializeHardwareDrawIfNeeded() { | 823 void AwContents::InitializeHardwareDrawIfNeeded() { |
| 883 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); | 824 shared_renderer_state_->InitializeHardwareDrawIfNeededOnUI(); |
| 884 | |
| 885 base::AutoLock lock(render_thread_lock_); | |
| 886 if (renderer_manager_key_ == manager->NullKey()) { | |
| 887 renderer_manager_key_ = manager->PushBack(shared_renderer_state_); | |
| 888 DeferredGpuCommandService::SetInstance(); | |
| 889 } | |
| 890 } | 825 } |
| 891 | 826 |
| 892 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { | 827 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { |
| 893 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 894 ReleaseHardwareDrawIfNeeded(); | 829 ReleaseHardwareDrawIfNeeded(); |
| 895 browser_view_renderer_.OnDetachedFromWindow(); | 830 browser_view_renderer_.OnDetachedFromWindow(); |
| 896 } | 831 } |
| 897 | 832 |
| 898 void AwContents::ReleaseHardwareDrawIfNeeded() { | 833 void AwContents::ReleaseHardwareDrawIfNeeded() { |
| 899 InsideHardwareReleaseReset inside_reset(shared_renderer_state_); | 834 shared_renderer_state_->ReleaseHardwareDrawIfNeededOnUI(); |
| 835 } |
| 900 | 836 |
| 837 void AwContents::InvalidateOnFunctorDestroy() { |
| 901 JNIEnv* env = AttachCurrentThread(); | 838 JNIEnv* env = AttachCurrentThread(); |
| 902 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 839 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 903 if (!obj.is_null()) | 840 if (!obj.is_null()) |
| 904 Java_AwContents_invalidateOnFunctorDestroy(env, obj.obj()); | 841 Java_AwContents_invalidateOnFunctorDestroy(env, obj.obj()); |
| 905 | |
| 906 bool hardware_initialized = browser_view_renderer_.hardware_enabled(); | |
| 907 if (hardware_initialized) { | |
| 908 bool draw_functor_succeeded = RequestDrawGL(true); | |
| 909 if (!draw_functor_succeeded) { | |
| 910 LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?"; | |
| 911 // Calling release on wrong thread intentionally. | |
| 912 AwDrawGLInfo info; | |
| 913 info.mode = AwDrawGLInfo::kModeProcess; | |
| 914 DrawGL(&info); | |
| 915 } | |
| 916 browser_view_renderer_.ReleaseHardware(); | |
| 917 } | |
| 918 DCHECK(!hardware_renderer_); | |
| 919 | |
| 920 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); | |
| 921 | |
| 922 { | |
| 923 base::AutoLock lock(render_thread_lock_); | |
| 924 if (renderer_manager_key_ != manager->NullKey()) { | |
| 925 manager->Remove(renderer_manager_key_); | |
| 926 renderer_manager_key_ = manager->NullKey(); | |
| 927 } | |
| 928 } | |
| 929 | |
| 930 if (hardware_initialized) { | |
| 931 // Flush any invoke functors that's caused by OnDetachedFromWindow. | |
| 932 RequestDrawGL(true); | |
| 933 } | |
| 934 } | 842 } |
| 935 | 843 |
| 936 base::android::ScopedJavaLocalRef<jbyteArray> | 844 base::android::ScopedJavaLocalRef<jbyteArray> |
| 937 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { | 845 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { |
| 938 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 846 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 939 // Required optimization in WebViewClassic to not save any state if | 847 // Required optimization in WebViewClassic to not save any state if |
| 940 // there has been no navigations. | 848 // there has been no navigations. |
| 941 if (!web_contents_->GetController().GetEntryCount()) | 849 if (!web_contents_->GetController().GetEntryCount()) |
| 942 return ScopedJavaLocalRef<jbyteArray>(); | 850 return ScopedJavaLocalRef<jbyteArray>(); |
| 943 | 851 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 } | 1077 } |
| 1170 | 1078 |
| 1171 browser_view_renderer_.TrimMemory(level, visible); | 1079 browser_view_renderer_.TrimMemory(level, visible); |
| 1172 } | 1080 } |
| 1173 | 1081 |
| 1174 void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) { | 1082 void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) { |
| 1175 g_should_download_favicons = true; | 1083 g_should_download_favicons = true; |
| 1176 } | 1084 } |
| 1177 | 1085 |
| 1178 } // namespace android_webview | 1086 } // namespace android_webview |
| OLD | NEW |