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 |