OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 <android/bitmap.h> |
7 #include <sys/system_properties.h> | 8 #include <sys/system_properties.h> |
8 | 9 |
9 #include "android_webview/browser/aw_browser_main_parts.h" | 10 #include "android_webview/browser/aw_browser_main_parts.h" |
10 #include "android_webview/browser/net_disk_cache_remover.h" | 11 #include "android_webview/browser/net_disk_cache_remover.h" |
11 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" | 12 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" |
12 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele
gate.h" | 13 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele
gate.h" |
13 #include "android_webview/common/aw_hit_test_data.h" | 14 #include "android_webview/common/aw_hit_test_data.h" |
14 #include "android_webview/common/renderer_picture_map.h" | 15 #include "android_webview/common/renderer_picture_map.h" |
15 #include "android_webview/native/aw_browser_dependency_factory.h" | 16 #include "android_webview/native/aw_browser_dependency_factory.h" |
16 #include "android_webview/native/aw_contents_io_thread_client_impl.h" | 17 #include "android_webview/native/aw_contents_io_thread_client_impl.h" |
(...skipping 13 matching lines...) Expand all Loading... |
30 #include "content/components/navigation_interception/intercept_navigation_delega
te.h" | 31 #include "content/components/navigation_interception/intercept_navigation_delega
te.h" |
31 #include "content/public/browser/android/content_view_core.h" | 32 #include "content/public/browser/android/content_view_core.h" |
32 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
33 #include "content/public/browser/cert_store.h" | 34 #include "content/public/browser/cert_store.h" |
34 #include "content/public/browser/navigation_entry.h" | 35 #include "content/public/browser/navigation_entry.h" |
35 #include "content/public/browser/render_process_host.h" | 36 #include "content/public/browser/render_process_host.h" |
36 #include "content/public/browser/web_contents.h" | 37 #include "content/public/browser/web_contents.h" |
37 #include "content/public/common/ssl_status.h" | 38 #include "content/public/common/ssl_status.h" |
38 #include "jni/AwContents_jni.h" | 39 #include "jni/AwContents_jni.h" |
39 #include "net/base/x509_certificate.h" | 40 #include "net/base/x509_certificate.h" |
40 #include "skia/ext/refptr.h" | |
41 #include "third_party/skia/include/core/SkBitmap.h" | 41 #include "third_party/skia/include/core/SkBitmap.h" |
42 #include "third_party/skia/include/core/SkCanvas.h" | 42 #include "third_party/skia/include/core/SkCanvas.h" |
43 #include "third_party/skia/include/core/SkDevice.h" | 43 #include "third_party/skia/include/core/SkDevice.h" |
44 #include "third_party/skia/include/core/SkPicture.h" | 44 #include "third_party/skia/include/core/SkGraphics.h" |
45 #include "ui/gfx/transform.h" | 45 #include "ui/gfx/transform.h" |
46 #include "ui/gl/gl_bindings.h" | 46 #include "ui/gl/gl_bindings.h" |
47 | 47 |
48 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 48 // TODO(leandrogracia): remove when crbug.com/164140 is closed. |
49 // Borrowed from gl2ext.h. Cannot be included due to conflicts with | 49 // Borrowed from gl2ext.h. Cannot be included due to conflicts with |
50 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). | 50 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). |
51 #ifndef GL_TEXTURE_EXTERNAL_OES | 51 #ifndef GL_TEXTURE_EXTERNAL_OES |
52 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 | 52 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 |
53 #endif | 53 #endif |
54 | 54 |
(...skipping 24 matching lines...) Expand all Loading... |
79 reinterpret_cast<android_webview::AwContents*>(view_context)->DrawGL( | 79 reinterpret_cast<android_webview::AwContents*>(view_context)->DrawGL( |
80 draw_info); | 80 draw_info); |
81 } | 81 } |
82 } | 82 } |
83 | 83 |
84 namespace android_webview { | 84 namespace android_webview { |
85 | 85 |
86 namespace { | 86 namespace { |
87 | 87 |
88 AwDrawSWFunctionTable* g_draw_sw_functions = NULL; | 88 AwDrawSWFunctionTable* g_draw_sw_functions = NULL; |
| 89 bool g_is_skia_version_compatible = false; |
89 | 90 |
90 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; | 91 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; |
91 | 92 |
92 class AwContentsUserData : public base::SupportsUserData::Data { | 93 class AwContentsUserData : public base::SupportsUserData::Data { |
93 public: | 94 public: |
94 AwContentsUserData(AwContents* ptr) : contents_(ptr) {} | 95 AwContentsUserData(AwContents* ptr) : contents_(ptr) {} |
95 | 96 |
96 static AwContents* GetContents(WebContents* web_contents) { | 97 static AwContents* GetContents(WebContents* web_contents) { |
97 if (!web_contents) | 98 if (!web_contents) |
98 return NULL; | 99 return NULL; |
(...skipping 15 matching lines...) Expand all Loading... |
114 | 115 |
115 AwContents::AwContents(JNIEnv* env, | 116 AwContents::AwContents(JNIEnv* env, |
116 jobject obj, | 117 jobject obj, |
117 jobject web_contents_delegate) | 118 jobject web_contents_delegate) |
118 : java_ref_(env, obj), | 119 : java_ref_(env, obj), |
119 web_contents_delegate_( | 120 web_contents_delegate_( |
120 new AwWebContentsDelegate(env, web_contents_delegate)), | 121 new AwWebContentsDelegate(env, web_contents_delegate)), |
121 view_visible_(false), | 122 view_visible_(false), |
122 compositor_visible_(false), | 123 compositor_visible_(false), |
123 is_composite_pending_(false), | 124 is_composite_pending_(false), |
| 125 on_new_picture_mode_(kOnNewPictureDisabled), |
124 last_frame_context_(NULL) { | 126 last_frame_context_(NULL) { |
125 RendererPictureMap::CreateInstance(); | 127 RendererPictureMap::CreateInstance(); |
126 android_webview::AwBrowserDependencyFactory* dependency_factory = | 128 android_webview::AwBrowserDependencyFactory* dependency_factory = |
127 android_webview::AwBrowserDependencyFactory::GetInstance(); | 129 android_webview::AwBrowserDependencyFactory::GetInstance(); |
128 | 130 |
129 // TODO(joth): rather than create and set the WebContents here, expose the | 131 // TODO(joth): rather than create and set the WebContents here, expose the |
130 // factory method to java side and have that orchestrate the construction | 132 // factory method to java side and have that orchestrate the construction |
131 // order. | 133 // order. |
132 SetWebContents(dependency_factory->CreateWebContents()); | 134 SetWebContents(dependency_factory->CreateWebContents()); |
133 } | 135 } |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 | 374 |
373 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], | 375 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], |
374 scissor_box[3]); | 376 scissor_box[3]); |
375 | 377 |
376 glUseProgram(current_program); | 378 glUseProgram(current_program); |
377 } | 379 } |
378 // --------------------------------------------------------------------------- | 380 // --------------------------------------------------------------------------- |
379 } | 381 } |
380 | 382 |
381 bool AwContents::DrawSW(JNIEnv* env, jobject obj, jobject java_canvas) { | 383 bool AwContents::DrawSW(JNIEnv* env, jobject obj, jobject java_canvas) { |
382 skia::RefPtr<SkPicture> picture = | 384 // TODO(leandrogracia): once Ubercompositor is ready and we support software |
383 RendererPictureMap::GetInstance()->GetRendererPicture( | 385 // rendering mode, we should avoid this as much as we can, ideally always. |
384 web_contents_->GetRoutingID()); | 386 // This includes finding a proper replacement for onDraw calls in hardware |
| 387 // mode with software canvases. http://crbug.com/170086. |
| 388 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); |
385 if (!picture) | 389 if (!picture) |
386 return false; | 390 return false; |
387 | 391 |
388 AwPixelInfo* pixels; | 392 AwPixelInfo* pixels; |
389 if (!g_draw_sw_functions || | 393 if (!g_draw_sw_functions || |
390 (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { | 394 (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { |
391 // TODO(joth): Fall back to slow path rendering via temporary bitmap. | 395 // TODO(joth): Fall back to slow path rendering via temporary bitmap. |
392 return false; | 396 return false; |
393 } | 397 } |
394 | 398 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 } | 459 } |
456 | 460 |
457 void AwContents::Destroy(JNIEnv* env, jobject obj) { | 461 void AwContents::Destroy(JNIEnv* env, jobject obj) { |
458 delete this; | 462 delete this; |
459 } | 463 } |
460 | 464 |
461 // static | 465 // static |
462 void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { | 466 void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { |
463 g_draw_sw_functions = | 467 g_draw_sw_functions = |
464 reinterpret_cast<AwDrawSWFunctionTable*>(function_table); | 468 reinterpret_cast<AwDrawSWFunctionTable*>(function_table); |
| 469 // TODO(leandrogracia): uncomment once the glue layer implements this method. |
| 470 //g_is_skia_version_compatible = |
| 471 // g_draw_sw_functions->is_skia_version_compatible(&SkGraphics::GetVersion); |
| 472 if (!g_is_skia_version_compatible) |
| 473 LOG(WARNING) << "Skia native versions are not compatible."; |
465 } | 474 } |
466 | 475 |
467 // static | 476 // static |
468 jint GetAwDrawGLFunction(JNIEnv* env, jclass) { | 477 jint GetAwDrawGLFunction(JNIEnv* env, jclass) { |
469 return reinterpret_cast<jint>(&DrawGLFunction); | 478 return reinterpret_cast<jint>(&DrawGLFunction); |
470 } | 479 } |
471 | 480 |
472 namespace { | 481 namespace { |
473 // |message| is passed as base::Owned, so it will automatically be deleted | 482 // |message| is passed as base::Owned, so it will automatically be deleted |
474 // when the callback goes out of scope. | 483 // when the callback goes out of scope. |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 is_composite_pending_ = true; | 698 is_composite_pending_ = true; |
690 Invalidate(); | 699 Invalidate(); |
691 } | 700 } |
692 | 701 |
693 void AwContents::Invalidate() { | 702 void AwContents::Invalidate() { |
694 JNIEnv* env = AttachCurrentThread(); | 703 JNIEnv* env = AttachCurrentThread(); |
695 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 704 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
696 if (obj.is_null()) | 705 if (obj.is_null()) |
697 return; | 706 return; |
698 | 707 |
699 Java_AwContents_invalidate(env, obj.obj()); | 708 if (view_visible_) |
| 709 Java_AwContents_invalidate(env, obj.obj()); |
| 710 |
| 711 // When not in invalidation-only mode onNewPicture will be triggered |
| 712 // from the OnPictureUpdated callback. |
| 713 if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) |
| 714 Java_AwContents_onNewPicture(env, obj.obj(), NULL); |
700 } | 715 } |
701 | 716 |
702 void AwContents::SetCompositorVisibility(bool visible) { | 717 void AwContents::SetCompositorVisibility(bool visible) { |
703 if (compositor_visible_ != visible) { | 718 if (compositor_visible_ != visible) { |
704 compositor_visible_ = visible; | 719 compositor_visible_ = visible; |
705 compositor_->SetVisible(compositor_visible_); | 720 compositor_->SetVisible(compositor_visible_); |
706 } | 721 } |
707 } | 722 } |
708 | 723 |
709 void AwContents::OnSwapBuffersCompleted() { | 724 void AwContents::OnSwapBuffersCompleted() { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 } | 856 } |
842 | 857 |
843 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { | 858 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { |
844 web_contents_->FocusThroughTabTraversal(false); | 859 web_contents_->FocusThroughTabTraversal(false); |
845 } | 860 } |
846 | 861 |
847 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { | 862 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { |
848 return reinterpret_cast<jint>(pending_contents_.release()); | 863 return reinterpret_cast<jint>(pending_contents_.release()); |
849 } | 864 } |
850 | 865 |
| 866 ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env, |
| 867 jobject obj) { |
| 868 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); |
| 869 if (!picture || !g_draw_sw_functions) |
| 870 return ScopedJavaLocalRef<jobject>(); |
| 871 |
| 872 if (g_is_skia_version_compatible) |
| 873 return ScopedJavaLocalRef<jobject>(env, |
| 874 g_draw_sw_functions->create_picture(env, picture->clone())); |
| 875 |
| 876 // If Skia versions are not compatible, workaround it by rasterizing the |
| 877 // picture into a bitmap and drawing it into a new Java picture. |
| 878 return ScopedJavaLocalRef<jobject>( |
| 879 Java_AwContents_rasterizeIntoPicture(env, obj, |
| 880 reinterpret_cast<jint>(picture.get()), |
| 881 picture->width(), picture->height())); |
| 882 } |
| 883 |
| 884 // static |
| 885 jboolean RasterizePicture(JNIEnv* env, |
| 886 jclass clazz, |
| 887 jobject jbitmap, |
| 888 jint native_picture) { |
| 889 DCHECK(jbitmap); |
| 890 DCHECK(native_picture); |
| 891 |
| 892 AndroidBitmapInfo bitmap_info; |
| 893 if (AndroidBitmap_getInfo(env, jbitmap, &bitmap_info) < 0) { |
| 894 LOG(WARNING) << "Error getting java bitmap info."; |
| 895 return false; |
| 896 } |
| 897 |
| 898 void* pixels = NULL; |
| 899 if (AndroidBitmap_lockPixels(env, jbitmap, &pixels) < 0) { |
| 900 LOG(WARNING) << "Error locking java bitmap pixels."; |
| 901 return false; |
| 902 } |
| 903 |
| 904 { |
| 905 SkBitmap bitmap; |
| 906 bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| 907 bitmap_info.width, |
| 908 bitmap_info.height, |
| 909 bitmap_info.stride); |
| 910 bitmap.setPixels(pixels); |
| 911 |
| 912 SkDevice device(bitmap); |
| 913 SkCanvas canvas(&device); |
| 914 SkPicture* picture = reinterpret_cast<SkPicture*>(native_picture); |
| 915 picture->draw(&canvas); |
| 916 } |
| 917 |
| 918 if (AndroidBitmap_unlockPixels(env, jbitmap) < 0) { |
| 919 LOG(WARNING) << "Error unlocking java bitmap pixels."; |
| 920 return false; |
| 921 } |
| 922 |
| 923 return true; |
| 924 } |
| 925 |
| 926 void AwContents::EnableOnNewPicture(JNIEnv* env, |
| 927 jobject obj, |
| 928 jboolean enabled, |
| 929 jboolean invalidation_only) { |
| 930 if (enabled) { |
| 931 on_new_picture_mode_ = invalidation_only ? kOnNewPictureInvalidationOnly : |
| 932 kOnNewPictureEnabled; |
| 933 } else { |
| 934 on_new_picture_mode_ = kOnNewPictureDisabled; |
| 935 } |
| 936 |
| 937 // If onNewPicture is triggered only on invalidation do not capture |
| 938 // pictures on every new frame. |
| 939 if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) |
| 940 enabled = false; |
| 941 |
| 942 // TODO(leandrogracia): uncomment when sw rendering uses Ubercompositor. |
| 943 // Until then we need the callback enabled for SW mode invalidation. |
| 944 // render_view_host_ext_->EnableCapturePictureCallback(enabled); |
| 945 } |
| 946 |
851 void AwContents::OnPictureUpdated(int process_id, int render_view_id) { | 947 void AwContents::OnPictureUpdated(int process_id, int render_view_id) { |
852 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); | 948 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); |
853 if (render_view_id != web_contents_->GetRoutingID()) | 949 if (render_view_id != web_contents_->GetRoutingID()) |
854 return; | 950 return; |
855 | 951 |
| 952 // TODO(leandrogracia): this can be made unconditional once software rendering |
| 953 // uses Ubercompositor. Until then this path is required for SW invalidations. |
| 954 if (on_new_picture_mode_ == kOnNewPictureEnabled) { |
| 955 JNIEnv* env = AttachCurrentThread(); |
| 956 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 957 if (!obj.is_null()) { |
| 958 ScopedJavaLocalRef<jobject> picture = CapturePicture(env, obj.obj()); |
| 959 Java_AwContents_onNewPicture(env, obj.obj(), picture.obj()); |
| 960 } |
| 961 } |
| 962 |
856 // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. | 963 // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. |
857 // Invalidation should be provided by the compositor only. | 964 // Invalidation should be provided by the compositor only. |
858 Invalidate(); | 965 Invalidate(); |
859 } | 966 } |
860 | 967 |
| 968 skia::RefPtr<SkPicture> AwContents::GetLastCapturedPicture() { |
| 969 // Use the latest available picture if the listener callback is enabled. |
| 970 skia::RefPtr<SkPicture> picture; |
| 971 if (on_new_picture_mode_ == kOnNewPictureEnabled) |
| 972 picture = RendererPictureMap::GetInstance()->GetRendererPicture( |
| 973 web_contents_->GetRoutingID()); |
| 974 |
| 975 // If not available or not in listener mode get it synchronously. |
| 976 if (!picture) { |
| 977 render_view_host_ext_->CapturePictureSync(); |
| 978 picture = RendererPictureMap::GetInstance()->GetRendererPicture( |
| 979 web_contents_->GetRoutingID()); |
| 980 } |
| 981 |
| 982 return picture; |
| 983 } |
| 984 |
861 } // namespace android_webview | 985 } // namespace android_webview |
OLD | NEW |