| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/browser/in_process_view_renderer.h" | 5 #include "android_webview/browser/in_process_view_renderer.h" |
| 6 | 6 |
| 7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
| 8 | 8 |
| 9 #include "android_webview/browser/aw_gl_surface.h" | 9 #include "android_webview/browser/aw_gl_surface.h" |
| 10 #include "android_webview/browser/scoped_app_gl_state_restore.h" | 10 #include "android_webview/browser/scoped_app_gl_state_restore.h" |
| 11 #include "android_webview/common/aw_switches.h" | 11 #include "android_webview/common/aw_switches.h" |
| 12 #include "android_webview/public/browser/draw_gl.h" | 12 #include "android_webview/public/browser/draw_gl.h" |
| 13 #include "android_webview/public/browser/draw_sw.h" | 13 #include "android_webview/public/browser/draw_sw.h" |
| 14 #include "base/android/jni_android.h" | 14 #include "base/android/jni_android.h" |
| 15 #include "base/auto_reset.h" | 15 #include "base/auto_reset.h" |
| 16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 17 #include "base/debug/trace_event.h" | 17 #include "base/debug/trace_event.h" |
| 18 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
| 19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 21 #include "content/public/browser/android/synchronous_compositor.h" | 21 #include "content/public/browser/android/synchronous_compositor.h" |
| 22 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 23 #include "content/public/browser/web_contents.h" | 23 #include "content/public/browser/web_contents.h" |
| 24 #include "gpu/command_buffer/service/in_process_command_buffer.h" | 24 #include "gpu/command_buffer/service/in_process_command_buffer.h" |
| 25 #include "third_party/skia/include/core/SkBitmap.h" | 25 #include "third_party/skia/include/core/SkBitmap.h" |
| 26 #include "third_party/skia/include/core/SkBitmapDevice.h" | 26 #include "third_party/skia/include/core/SkBitmapDevice.h" |
| 27 #include "third_party/skia/include/core/SkCanvas.h" | 27 #include "third_party/skia/include/core/SkCanvas.h" |
| 28 #include "third_party/skia/include/core/SkGraphics.h" | 28 #include "third_party/skia/include/core/SkGraphics.h" |
| 29 #include "third_party/skia/include/core/SkPicture.h" | 29 #include "third_party/skia/include/core/SkPicture.h" |
| 30 #include "third_party/skia/include/utils/SkCanvasStateUtils.h" |
| 30 #include "ui/gfx/skia_util.h" | 31 #include "ui/gfx/skia_util.h" |
| 31 #include "ui/gfx/transform.h" | 32 #include "ui/gfx/transform.h" |
| 32 #include "ui/gfx/vector2d_conversions.h" | 33 #include "ui/gfx/vector2d_conversions.h" |
| 33 #include "ui/gfx/vector2d_f.h" | 34 #include "ui/gfx/vector2d_f.h" |
| 34 | 35 |
| 35 using base::android::AttachCurrentThread; | 36 using base::android::AttachCurrentThread; |
| 36 using base::android::JavaRef; | 37 using base::android::JavaRef; |
| 37 using base::android::ScopedJavaLocalRef; | 38 using base::android::ScopedJavaLocalRef; |
| 38 using content::BrowserThread; | 39 using content::BrowserThread; |
| 39 | 40 |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 const gfx::Vector2d& scroll_correction, | 443 const gfx::Vector2d& scroll_correction, |
| 443 const gfx::Rect& clip, | 444 const gfx::Rect& clip, |
| 444 InProcessViewRenderer::RenderMethod render_source, | 445 InProcessViewRenderer::RenderMethod render_source, |
| 445 void* owner_key) { | 446 void* owner_key) { |
| 446 TRACE_EVENT0("android_webview", | 447 TRACE_EVENT0("android_webview", |
| 447 "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded"); | 448 "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded"); |
| 448 | 449 |
| 449 JNIEnv* env = AttachCurrentThread(); | 450 JNIEnv* env = AttachCurrentThread(); |
| 450 ScopedPixelAccess auto_release_pixels(env, java_canvas); | 451 ScopedPixelAccess auto_release_pixels(env, java_canvas); |
| 451 AwPixelInfo* pixels = auto_release_pixels.pixels(); | 452 AwPixelInfo* pixels = auto_release_pixels.pixels(); |
| 452 SkMatrix matrix; | 453 if (pixels && pixels->state) { |
| 453 SkBitmap::Config config(SkBitmap::kNo_Config); | 454 skia::RefPtr<SkCanvas> canvas = skia::AdoptRef( |
| 454 if (pixels) { | 455 SkCanvasStateUtils::CreateFromCanvasState(pixels->state)); |
| 455 switch (pixels->config) { | 456 |
| 456 case AwConfig_ARGB_8888: | 457 // Workarounds for http://crbug.com/271096: SW draw only supports |
| 457 config = SkBitmap::kARGB_8888_Config; | 458 // translate & scale transforms, and a simple rectangular clip. |
| 458 break; | 459 if (canvas && (!canvas->getTotalClip().isRect() || |
| 459 case AwConfig_RGB_565: | 460 (canvas->getTotalMatrix().getType() & |
| 460 config = SkBitmap::kRGB_565_Config; | 461 ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)))) { |
| 461 break; | 462 canvas.clear(); |
| 462 } | 463 } |
| 463 | 464 if (canvas) |
| 464 for (int i = 0; i < 9; i++) { | 465 return render_source.Run(canvas.get()); |
| 465 matrix.set(i, pixels->matrix[i]); | |
| 466 } | |
| 467 // Workaround for http://crbug.com/271096: SW draw only supports | |
| 468 // translate & scale transforms. | |
| 469 if (matrix.getType() & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) | |
| 470 config = SkBitmap::kNo_Config; | |
| 471 } | 466 } |
| 472 | 467 |
| 473 if (config == SkBitmap::kNo_Config) { | 468 // Render into an auxiliary bitmap if pixel info is not available. |
| 474 // Render into an auxiliary bitmap if pixel info is not available. | 469 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); |
| 475 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); | 470 TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); |
| 476 TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); | 471 ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap( |
| 477 ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap( | 472 env, clip.width(), clip.height(), jcanvas, owner_key)); |
| 478 env, clip.width(), clip.height(), jcanvas, owner_key)); | 473 if (!jbitmap.obj()) { |
| 479 if (!jbitmap.obj()) { | 474 TRACE_EVENT_INSTANT0("android_webview", |
| 480 TRACE_EVENT_INSTANT0("android_webview", | 475 "EarlyOut_BitmapAllocFail", |
| 481 "EarlyOut_BitmapAllocFail", | 476 TRACE_EVENT_SCOPE_THREAD); |
| 482 TRACE_EVENT_SCOPE_THREAD); | 477 return false; |
| 483 return false; | |
| 484 } | |
| 485 | |
| 486 if (!RasterizeIntoBitmap(env, jbitmap, | |
| 487 clip.x() - scroll_correction.x(), | |
| 488 clip.y() - scroll_correction.y(), | |
| 489 render_source)) { | |
| 490 TRACE_EVENT_INSTANT0("android_webview", | |
| 491 "EarlyOut_RasterizeFail", | |
| 492 TRACE_EVENT_SCOPE_THREAD); | |
| 493 return false; | |
| 494 } | |
| 495 | |
| 496 java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas, | |
| 497 clip.x(), clip.y()); | |
| 498 return true; | |
| 499 } | 478 } |
| 500 | 479 |
| 501 // Draw in a SkCanvas built over the pixel information. | 480 if (!RasterizeIntoBitmap(env, jbitmap, |
| 502 SkBitmap bitmap; | 481 clip.x() - scroll_correction.x(), |
| 503 bitmap.setConfig(config, | 482 clip.y() - scroll_correction.y(), |
| 504 pixels->width, | 483 render_source)) { |
| 505 pixels->height, | 484 TRACE_EVENT_INSTANT0("android_webview", |
| 506 pixels->row_bytes); | 485 "EarlyOut_RasterizeFail", |
| 507 bitmap.setPixels(pixels->pixels); | 486 TRACE_EVENT_SCOPE_THREAD); |
| 508 SkBitmapDevice device(bitmap); | 487 return false; |
| 509 SkCanvas canvas(&device); | |
| 510 canvas.setMatrix(matrix); | |
| 511 | |
| 512 if (pixels->clip_rect_count) { | |
| 513 SkRegion clip; | |
| 514 for (int i = 0; i < pixels->clip_rect_count; ++i) { | |
| 515 clip.op(SkIRect::MakeXYWH(pixels->clip_rects[i + 0], | |
| 516 pixels->clip_rects[i + 1], | |
| 517 pixels->clip_rects[i + 2], | |
| 518 pixels->clip_rects[i + 3]), | |
| 519 SkRegion::kUnion_Op); | |
| 520 } | |
| 521 canvas.setClipRegion(clip); | |
| 522 } | 488 } |
| 523 | 489 |
| 524 canvas.translate(scroll_correction.x(), | 490 java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas, |
| 525 scroll_correction.y()); | 491 clip.x(), clip.y()); |
| 526 | 492 return true; |
| 527 return render_source.Run(&canvas); | |
| 528 } | 493 } |
| 529 | 494 |
| 530 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, | 495 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, |
| 531 int height) { | 496 int height) { |
| 532 TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture"); | 497 TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture"); |
| 533 | 498 |
| 534 // Return empty Picture objects for empty SkPictures. | 499 // Return empty Picture objects for empty SkPictures. |
| 535 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); | 500 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); |
| 536 if (width <= 0 || height <= 0) { | 501 if (width <= 0 || height <= 0) { |
| 537 return picture; | 502 return picture; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 base::StringAppendF(&str, | 818 base::StringAppendF(&str, |
| 854 "surface width height: [%d %d] ", | 819 "surface width height: [%d %d] ", |
| 855 draw_info->width, | 820 draw_info->width, |
| 856 draw_info->height); | 821 draw_info->height); |
| 857 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); | 822 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); |
| 858 } | 823 } |
| 859 return str; | 824 return str; |
| 860 } | 825 } |
| 861 | 826 |
| 862 } // namespace android_webview | 827 } // namespace android_webview |
| OLD | NEW |