| 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_context.h" | 10 #include "android_webview/browser/aw_browser_context.h" |
| 10 #include "android_webview/browser/aw_browser_main_parts.h" | 11 #include "android_webview/browser/aw_browser_main_parts.h" |
| 11 #include "android_webview/browser/net_disk_cache_remover.h" | 12 #include "android_webview/browser/net_disk_cache_remover.h" |
| 12 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" | 13 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" |
| 13 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele
gate.h" | 14 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele
gate.h" |
| 14 #include "android_webview/common/aw_hit_test_data.h" | 15 #include "android_webview/common/aw_hit_test_data.h" |
| 15 #include "android_webview/common/renderer_picture_map.h" | 16 #include "android_webview/common/renderer_picture_map.h" |
| 16 #include "android_webview/native/aw_browser_dependency_factory.h" | 17 #include "android_webview/native/aw_browser_dependency_factory.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 32 #include "components/navigation_interception/intercept_navigation_delegate.h" | 33 #include "components/navigation_interception/intercept_navigation_delegate.h" |
| 33 #include "content/public/browser/android/content_view_core.h" | 34 #include "content/public/browser/android/content_view_core.h" |
| 34 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
| 35 #include "content/public/browser/cert_store.h" | 36 #include "content/public/browser/cert_store.h" |
| 36 #include "content/public/browser/navigation_entry.h" | 37 #include "content/public/browser/navigation_entry.h" |
| 37 #include "content/public/browser/render_process_host.h" | 38 #include "content/public/browser/render_process_host.h" |
| 38 #include "content/public/browser/web_contents.h" | 39 #include "content/public/browser/web_contents.h" |
| 39 #include "content/public/common/ssl_status.h" | 40 #include "content/public/common/ssl_status.h" |
| 40 #include "jni/AwContents_jni.h" | 41 #include "jni/AwContents_jni.h" |
| 41 #include "net/base/x509_certificate.h" | 42 #include "net/base/x509_certificate.h" |
| 42 #include "skia/ext/refptr.h" | |
| 43 #include "third_party/skia/include/core/SkBitmap.h" | 43 #include "third_party/skia/include/core/SkBitmap.h" |
| 44 #include "third_party/skia/include/core/SkCanvas.h" | 44 #include "third_party/skia/include/core/SkCanvas.h" |
| 45 #include "third_party/skia/include/core/SkDevice.h" | 45 #include "third_party/skia/include/core/SkDevice.h" |
| 46 #include "third_party/skia/include/core/SkGraphics.h" |
| 46 #include "third_party/skia/include/core/SkPicture.h" | 47 #include "third_party/skia/include/core/SkPicture.h" |
| 47 #include "ui/gfx/android/java_bitmap.h" | 48 #include "ui/gfx/android/java_bitmap.h" |
| 48 #include "ui/gfx/transform.h" | 49 #include "ui/gfx/transform.h" |
| 49 #include "ui/gl/gl_bindings.h" | 50 #include "ui/gl/gl_bindings.h" |
| 50 | 51 |
| 51 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 52 // TODO(leandrogracia): remove when crbug.com/164140 is closed. |
| 52 // Borrowed from gl2ext.h. Cannot be included due to conflicts with | 53 // Borrowed from gl2ext.h. Cannot be included due to conflicts with |
| 53 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). | 54 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). |
| 54 #ifndef GL_TEXTURE_EXTERNAL_OES | 55 #ifndef GL_TEXTURE_EXTERNAL_OES |
| 55 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 | 56 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 75 extern "C" { | 76 extern "C" { |
| 76 static AwDrawGLFunction DrawGLFunction; | 77 static AwDrawGLFunction DrawGLFunction; |
| 77 static void DrawGLFunction(int view_context, | 78 static void DrawGLFunction(int view_context, |
| 78 AwDrawGLInfo* draw_info, | 79 AwDrawGLInfo* draw_info, |
| 79 void* spare) { | 80 void* spare) { |
| 80 // |view_context| is the value that was returned from the java | 81 // |view_context| is the value that was returned from the java |
| 81 // AwContents.onPrepareDrawGL; this cast must match the code there. | 82 // AwContents.onPrepareDrawGL; this cast must match the code there. |
| 82 reinterpret_cast<android_webview::AwContents*>(view_context)->DrawGL( | 83 reinterpret_cast<android_webview::AwContents*>(view_context)->DrawGL( |
| 83 draw_info); | 84 draw_info); |
| 84 } | 85 } |
| 86 |
| 87 typedef base::Callback<bool(SkCanvas*)> RenderMethod; |
| 88 |
| 89 static bool RasterizeIntoBitmap(JNIEnv* env, |
| 90 jobject jbitmap, |
| 91 int scroll_x, |
| 92 int scroll_y, |
| 93 const RenderMethod& renderer) { |
| 94 DCHECK(jbitmap); |
| 95 |
| 96 AndroidBitmapInfo bitmap_info; |
| 97 if (AndroidBitmap_getInfo(env, jbitmap, &bitmap_info) < 0) { |
| 98 LOG(WARNING) << "Error getting java bitmap info."; |
| 99 return false; |
| 100 } |
| 101 |
| 102 void* pixels = NULL; |
| 103 if (AndroidBitmap_lockPixels(env, jbitmap, &pixels) < 0) { |
| 104 LOG(WARNING) << "Error locking java bitmap pixels."; |
| 105 return false; |
| 106 } |
| 107 |
| 108 bool succeeded = false; |
| 109 { |
| 110 SkBitmap bitmap; |
| 111 bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| 112 bitmap_info.width, |
| 113 bitmap_info.height, |
| 114 bitmap_info.stride); |
| 115 bitmap.setPixels(pixels); |
| 116 |
| 117 SkDevice device(bitmap); |
| 118 SkCanvas canvas(&device); |
| 119 canvas.translate(-scroll_x, -scroll_y); |
| 120 succeeded = renderer.Run(&canvas); |
| 121 } |
| 122 |
| 123 if (AndroidBitmap_unlockPixels(env, jbitmap) < 0) { |
| 124 LOG(WARNING) << "Error unlocking java bitmap pixels."; |
| 125 return false; |
| 126 } |
| 127 |
| 128 return succeeded; |
| 129 } |
| 85 } | 130 } |
| 86 | 131 |
| 87 namespace android_webview { | 132 namespace android_webview { |
| 88 | 133 |
| 89 namespace { | 134 namespace { |
| 90 | 135 |
| 91 AwDrawSWFunctionTable* g_draw_sw_functions = NULL; | 136 AwDrawSWFunctionTable* g_draw_sw_functions = NULL; |
| 137 bool g_is_skia_version_compatible = false; |
| 92 | 138 |
| 93 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; | 139 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; |
| 94 | 140 |
| 95 class AwContentsUserData : public base::SupportsUserData::Data { | 141 class AwContentsUserData : public base::SupportsUserData::Data { |
| 96 public: | 142 public: |
| 97 AwContentsUserData(AwContents* ptr) : contents_(ptr) {} | 143 AwContentsUserData(AwContents* ptr) : contents_(ptr) {} |
| 98 | 144 |
| 99 static AwContents* GetContents(WebContents* web_contents) { | 145 static AwContents* GetContents(WebContents* web_contents) { |
| 100 if (!web_contents) | 146 if (!web_contents) |
| 101 return NULL; | 147 return NULL; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 117 | 163 |
| 118 AwContents::AwContents(JNIEnv* env, | 164 AwContents::AwContents(JNIEnv* env, |
| 119 jobject obj, | 165 jobject obj, |
| 120 jobject web_contents_delegate) | 166 jobject web_contents_delegate) |
| 121 : java_ref_(env, obj), | 167 : java_ref_(env, obj), |
| 122 web_contents_delegate_( | 168 web_contents_delegate_( |
| 123 new AwWebContentsDelegate(env, web_contents_delegate)), | 169 new AwWebContentsDelegate(env, web_contents_delegate)), |
| 124 view_visible_(false), | 170 view_visible_(false), |
| 125 compositor_visible_(false), | 171 compositor_visible_(false), |
| 126 is_composite_pending_(false), | 172 is_composite_pending_(false), |
| 173 on_new_picture_mode_(kOnNewPictureDisabled), |
| 127 last_frame_context_(NULL) { | 174 last_frame_context_(NULL) { |
| 128 RendererPictureMap::CreateInstance(); | 175 RendererPictureMap::CreateInstance(); |
| 129 android_webview::AwBrowserDependencyFactory* dependency_factory = | 176 android_webview::AwBrowserDependencyFactory* dependency_factory = |
| 130 android_webview::AwBrowserDependencyFactory::GetInstance(); | 177 android_webview::AwBrowserDependencyFactory::GetInstance(); |
| 131 | 178 |
| 132 // TODO(joth): rather than create and set the WebContents here, expose the | 179 // TODO(joth): rather than create and set the WebContents here, expose the |
| 133 // factory method to java side and have that orchestrate the construction | 180 // factory method to java side and have that orchestrate the construction |
| 134 // order. | 181 // order. |
| 135 SetWebContents(dependency_factory->CreateWebContents()); | 182 SetWebContents(dependency_factory->CreateWebContents()); |
| 136 } | 183 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 167 if (find_helper_.get()) | 214 if (find_helper_.get()) |
| 168 find_helper_->SetListener(NULL); | 215 find_helper_->SetListener(NULL); |
| 169 if (icon_helper_.get()) | 216 if (icon_helper_.get()) |
| 170 icon_helper_->SetListener(NULL); | 217 icon_helper_->SetListener(NULL); |
| 171 } | 218 } |
| 172 | 219 |
| 173 void AwContents::DrawGL(AwDrawGLInfo* draw_info) { | 220 void AwContents::DrawGL(AwDrawGLInfo* draw_info) { |
| 174 | 221 |
| 175 TRACE_EVENT0("AwContents", "AwContents::DrawGL"); | 222 TRACE_EVENT0("AwContents", "AwContents::DrawGL"); |
| 176 | 223 |
| 177 if (!scissor_clip_layer_ || draw_info->mode == AwDrawGLInfo::kModeProcess) | 224 if (view_size_.IsEmpty() || !scissor_clip_layer_ || |
| 225 draw_info->mode == AwDrawGLInfo::kModeProcess) |
| 178 return; | 226 return; |
| 179 | 227 |
| 180 DCHECK_EQ(draw_info->mode, AwDrawGLInfo::kModeDraw); | 228 DCHECK_EQ(draw_info->mode, AwDrawGLInfo::kModeDraw); |
| 181 | 229 |
| 182 SetCompositorVisibility(view_visible_); | 230 SetCompositorVisibility(view_visible_); |
| 183 if (!compositor_visible_) | 231 if (!compositor_visible_) |
| 184 return; | 232 return; |
| 185 | 233 |
| 186 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 234 // TODO(leandrogracia): remove when crbug.com/164140 is closed. |
| 187 // --------------------------------------------------------------------------- | 235 // --------------------------------------------------------------------------- |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 glDisable(GL_SCISSOR_TEST); | 429 glDisable(GL_SCISSOR_TEST); |
| 382 | 430 |
| 383 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], | 431 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], |
| 384 scissor_box[3]); | 432 scissor_box[3]); |
| 385 | 433 |
| 386 glUseProgram(current_program); | 434 glUseProgram(current_program); |
| 387 } | 435 } |
| 388 // --------------------------------------------------------------------------- | 436 // --------------------------------------------------------------------------- |
| 389 } | 437 } |
| 390 | 438 |
| 391 bool AwContents::DrawSW(JNIEnv* env, jobject obj, jobject java_canvas) { | 439 bool AwContents::DrawSW(JNIEnv* env, |
| 392 skia::RefPtr<SkPicture> picture = | 440 jobject obj, |
| 393 RendererPictureMap::GetInstance()->GetRendererPicture( | 441 jobject java_canvas, |
| 394 web_contents_->GetRoutingID()); | 442 jint clip_x, |
| 395 if (!picture) | 443 jint clip_y, |
| 396 return false; | 444 jint clip_w, |
| 445 jint clip_h) { |
| 446 TRACE_EVENT0("AwContents", "AwContents::DrawSW"); |
| 447 |
| 448 if (clip_w <= 0 || clip_h <= 0) |
| 449 return true; |
| 397 | 450 |
| 398 AwPixelInfo* pixels; | 451 AwPixelInfo* pixels; |
| 452 |
| 453 // Render into an auxiliary bitmap if pixel info is not available. |
| 399 if (!g_draw_sw_functions || | 454 if (!g_draw_sw_functions || |
| 400 (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { | 455 (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { |
| 401 // TODO(joth): Fall back to slow path rendering via temporary bitmap. | 456 ScopedJavaLocalRef<jobject> jbitmap(Java_AwContents_createBitmap( |
| 402 return false; | 457 env, clip_w, clip_h)); |
| 458 if (!jbitmap.obj()) |
| 459 return false; |
| 460 |
| 461 if (!RasterizeIntoBitmap(env, jbitmap.obj(), clip_x, clip_y, |
| 462 base::Bind(&AwContents::RenderSW, base::Unretained(this)))) |
| 463 return false; |
| 464 |
| 465 Java_AwContents_drawBitmapIntoCanvas(env, jbitmap.obj(), java_canvas); |
| 466 return true; |
| 403 } | 467 } |
| 404 | 468 |
| 469 // Draw in a SkCanvas built over the pixel information. |
| 470 bool succeeded = false; |
| 405 { | 471 { |
| 406 SkBitmap bitmap; | 472 SkBitmap bitmap; |
| 407 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), | 473 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), |
| 408 pixels->width, | 474 pixels->width, |
| 409 pixels->height, | 475 pixels->height, |
| 410 pixels->row_bytes); | 476 pixels->row_bytes); |
| 411 bitmap.setPixels(pixels->pixels); | 477 bitmap.setPixels(pixels->pixels); |
| 412 SkDevice device(bitmap); | 478 SkDevice device(bitmap); |
| 413 SkCanvas canvas(&device); | 479 SkCanvas canvas(&device); |
| 414 SkMatrix matrix; | 480 SkMatrix matrix; |
| 415 for (int i = 0; i < 9; i++) | 481 for (int i = 0; i < 9; i++) |
| 416 matrix.set(i, pixels->matrix[i]); | 482 matrix.set(i, pixels->matrix[i]); |
| 417 canvas.setMatrix(matrix); | 483 canvas.setMatrix(matrix); |
| 418 | 484 |
| 419 SkRegion clip; | 485 SkRegion clip; |
| 420 if (pixels->clip_region_size) { | 486 if (pixels->clip_region_size) { |
| 421 size_t bytes_read = clip.readFromMemory(pixels->clip_region); | 487 size_t bytes_read = clip.readFromMemory(pixels->clip_region); |
| 422 DCHECK_EQ(pixels->clip_region_size, bytes_read); | 488 DCHECK_EQ(pixels->clip_region_size, bytes_read); |
| 423 canvas.setClipRegion(clip); | 489 canvas.setClipRegion(clip); |
| 424 } else { | 490 } else { |
| 425 clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); | 491 clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); |
| 426 } | 492 } |
| 427 | 493 |
| 428 picture->draw(&canvas); | 494 succeeded = RenderSW(&canvas); |
| 429 } | 495 } |
| 430 | 496 |
| 431 g_draw_sw_functions->release_pixels(pixels); | 497 g_draw_sw_functions->release_pixels(pixels); |
| 432 return true; | 498 return succeeded; |
| 433 } | 499 } |
| 434 | 500 |
| 435 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { | 501 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { |
| 436 return reinterpret_cast<jint>(web_contents_.get()); | 502 return reinterpret_cast<jint>(web_contents_.get()); |
| 437 } | 503 } |
| 438 | 504 |
| 439 void AwContents::DidInitializeContentViewCore(JNIEnv* env, jobject obj, | 505 void AwContents::DidInitializeContentViewCore(JNIEnv* env, jobject obj, |
| 440 jint content_view_core) { | 506 jint content_view_core) { |
| 441 ContentViewCore* core = reinterpret_cast<ContentViewCore*>(content_view_core); | 507 ContentViewCore* core = reinterpret_cast<ContentViewCore*>(content_view_core); |
| 442 DCHECK(core == ContentViewCore::FromWebContents(web_contents_.get())); | 508 DCHECK(core == ContentViewCore::FromWebContents(web_contents_.get())); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 465 } | 531 } |
| 466 | 532 |
| 467 void AwContents::Destroy(JNIEnv* env, jobject obj) { | 533 void AwContents::Destroy(JNIEnv* env, jobject obj) { |
| 468 delete this; | 534 delete this; |
| 469 } | 535 } |
| 470 | 536 |
| 471 // static | 537 // static |
| 472 void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { | 538 void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { |
| 473 g_draw_sw_functions = | 539 g_draw_sw_functions = |
| 474 reinterpret_cast<AwDrawSWFunctionTable*>(function_table); | 540 reinterpret_cast<AwDrawSWFunctionTable*>(function_table); |
| 541 // TODO(leandrogracia): uncomment once the glue layer implements this method. |
| 542 //g_is_skia_version_compatible = |
| 543 // g_draw_sw_functions->is_skia_version_compatible(&SkGraphics::GetVersion); |
| 544 LOG_IF(WARNING, !g_is_skia_version_compatible) << |
| 545 "Skia native versions are not compatible."; |
| 475 } | 546 } |
| 476 | 547 |
| 477 // static | 548 // static |
| 478 jint GetAwDrawGLFunction(JNIEnv* env, jclass) { | 549 jint GetAwDrawGLFunction(JNIEnv* env, jclass) { |
| 479 return reinterpret_cast<jint>(&DrawGLFunction); | 550 return reinterpret_cast<jint>(&DrawGLFunction); |
| 480 } | 551 } |
| 481 | 552 |
| 482 namespace { | 553 namespace { |
| 483 // |message| is passed as base::Owned, so it will automatically be deleted | 554 // |message| is passed as base::Owned, so it will automatically be deleted |
| 484 // when the callback goes out of scope. | 555 // when the callback goes out of scope. |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 is_composite_pending_ = true; | 819 is_composite_pending_ = true; |
| 749 Invalidate(); | 820 Invalidate(); |
| 750 } | 821 } |
| 751 | 822 |
| 752 void AwContents::Invalidate() { | 823 void AwContents::Invalidate() { |
| 753 JNIEnv* env = AttachCurrentThread(); | 824 JNIEnv* env = AttachCurrentThread(); |
| 754 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 825 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 755 if (obj.is_null()) | 826 if (obj.is_null()) |
| 756 return; | 827 return; |
| 757 | 828 |
| 758 Java_AwContents_invalidate(env, obj.obj()); | 829 if (view_visible_) |
| 830 Java_AwContents_invalidate(env, obj.obj()); |
| 831 |
| 832 // When not in invalidation-only mode onNewPicture will be triggered |
| 833 // from the OnPictureUpdated callback. |
| 834 if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) |
| 835 Java_AwContents_onNewPicture(env, obj.obj(), NULL); |
| 759 } | 836 } |
| 760 | 837 |
| 761 void AwContents::SetCompositorVisibility(bool visible) { | 838 void AwContents::SetCompositorVisibility(bool visible) { |
| 762 if (compositor_visible_ != visible) { | 839 if (compositor_visible_ != visible) { |
| 763 compositor_visible_ = visible; | 840 compositor_visible_ = visible; |
| 764 compositor_->SetVisible(compositor_visible_); | 841 compositor_->SetVisible(compositor_visible_); |
| 765 } | 842 } |
| 766 } | 843 } |
| 767 | 844 |
| 768 void AwContents::OnSwapBuffersCompleted() { | 845 void AwContents::OnSwapBuffersCompleted() { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 } | 977 } |
| 901 | 978 |
| 902 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { | 979 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { |
| 903 web_contents_->FocusThroughTabTraversal(false); | 980 web_contents_->FocusThroughTabTraversal(false); |
| 904 } | 981 } |
| 905 | 982 |
| 906 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { | 983 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { |
| 907 return reinterpret_cast<jint>(pending_contents_.release()); | 984 return reinterpret_cast<jint>(pending_contents_.release()); |
| 908 } | 985 } |
| 909 | 986 |
| 987 ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env, |
| 988 jobject obj) { |
| 989 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); |
| 990 if (!picture || !g_draw_sw_functions) |
| 991 return ScopedJavaLocalRef<jobject>(); |
| 992 |
| 993 if (g_is_skia_version_compatible) |
| 994 return ScopedJavaLocalRef<jobject>(env, |
| 995 g_draw_sw_functions->create_picture(env, picture->clone())); |
| 996 |
| 997 // If Skia versions are not compatible, workaround it by rasterizing the |
| 998 // picture into a bitmap and drawing it into a new Java picture. |
| 999 ScopedJavaLocalRef<jobject> jbitmap(Java_AwContents_createBitmap( |
| 1000 env, picture->width(), picture->height())); |
| 1001 if (!jbitmap.obj()) |
| 1002 return ScopedJavaLocalRef<jobject>(); |
| 1003 |
| 1004 if (!RasterizeIntoBitmap(env, jbitmap.obj(), 0, 0, |
| 1005 base::Bind(&AwContents::RenderPicture, base::Unretained(this)))) |
| 1006 return ScopedJavaLocalRef<jobject>(); |
| 1007 |
| 1008 return Java_AwContents_recordBitmapIntoPicture(env, jbitmap.obj()); |
| 1009 } |
| 1010 |
| 1011 bool AwContents::RenderSW(SkCanvas* canvas) { |
| 1012 // TODO(leandrogracia): once Ubercompositor is ready and we support software |
| 1013 // rendering mode, we should avoid this as much as we can, ideally always. |
| 1014 // This includes finding a proper replacement for onDraw calls in hardware |
| 1015 // mode with software canvases. http://crbug.com/170086. |
| 1016 return RenderPicture(canvas); |
| 1017 } |
| 1018 |
| 1019 bool AwContents::RenderPicture(SkCanvas* canvas) { |
| 1020 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); |
| 1021 if (!picture) |
| 1022 return false; |
| 1023 |
| 1024 picture->draw(canvas); |
| 1025 return true; |
| 1026 } |
| 1027 |
| 1028 void AwContents::EnableOnNewPicture(JNIEnv* env, |
| 1029 jobject obj, |
| 1030 jboolean enabled, |
| 1031 jboolean invalidation_only) { |
| 1032 if (enabled) { |
| 1033 on_new_picture_mode_ = invalidation_only ? kOnNewPictureInvalidationOnly : |
| 1034 kOnNewPictureEnabled; |
| 1035 } else { |
| 1036 on_new_picture_mode_ = kOnNewPictureDisabled; |
| 1037 } |
| 1038 |
| 1039 // If onNewPicture is triggered only on invalidation do not capture |
| 1040 // pictures on every new frame. |
| 1041 if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) |
| 1042 enabled = false; |
| 1043 |
| 1044 // TODO(leandrogracia): when SW rendering uses the compositor rather than |
| 1045 // picture rasterization, send update the renderer side with the correct |
| 1046 // listener state. (For now, we always leave render picture listener enabled). |
| 1047 // render_view_host_ext_->EnableCapturePictureCallback(enabled); |
| 1048 } |
| 1049 |
| 910 void AwContents::OnPictureUpdated(int process_id, int render_view_id) { | 1050 void AwContents::OnPictureUpdated(int process_id, int render_view_id) { |
| 911 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); | 1051 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); |
| 912 if (render_view_id != web_contents_->GetRoutingID()) | 1052 if (render_view_id != web_contents_->GetRoutingID()) |
| 913 return; | 1053 return; |
| 914 | 1054 |
| 1055 // TODO(leandrogracia): this can be made unconditional once software rendering |
| 1056 // uses Ubercompositor. Until then this path is required for SW invalidations. |
| 1057 if (on_new_picture_mode_ == kOnNewPictureEnabled) { |
| 1058 JNIEnv* env = AttachCurrentThread(); |
| 1059 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 1060 if (!obj.is_null()) { |
| 1061 ScopedJavaLocalRef<jobject> picture = CapturePicture(env, obj.obj()); |
| 1062 Java_AwContents_onNewPicture(env, obj.obj(), picture.obj()); |
| 1063 } |
| 1064 } |
| 1065 |
| 915 // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. | 1066 // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. |
| 916 // Invalidation should be provided by the compositor only. | 1067 // Invalidation should be provided by the compositor only. |
| 917 Invalidate(); | 1068 Invalidate(); |
| 918 } | 1069 } |
| 919 | 1070 |
| 1071 skia::RefPtr<SkPicture> AwContents::GetLastCapturedPicture() { |
| 1072 // Use the latest available picture if the listener callback is enabled. |
| 1073 skia::RefPtr<SkPicture> picture; |
| 1074 if (on_new_picture_mode_ == kOnNewPictureEnabled) |
| 1075 picture = RendererPictureMap::GetInstance()->GetRendererPicture( |
| 1076 web_contents_->GetRoutingID()); |
| 1077 |
| 1078 // If not available or not in listener mode get it synchronously. |
| 1079 if (!picture) { |
| 1080 render_view_host_ext_->CapturePictureSync(); |
| 1081 picture = RendererPictureMap::GetInstance()->GetRendererPicture( |
| 1082 web_contents_->GetRoutingID()); |
| 1083 } |
| 1084 |
| 1085 return picture; |
| 1086 } |
| 1087 |
| 920 } // namespace android_webview | 1088 } // namespace android_webview |
| OLD | NEW |