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" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 } | 103 } |
104 | 104 |
105 return succeeded; | 105 return succeeded; |
106 } | 106 } |
107 | 107 |
108 bool RenderPictureToCanvas(SkPicture* picture, SkCanvas* canvas) { | 108 bool RenderPictureToCanvas(SkPicture* picture, SkCanvas* canvas) { |
109 canvas->drawPicture(*picture); | 109 canvas->drawPicture(*picture); |
110 return true; | 110 return true; |
111 } | 111 } |
112 | 112 |
| 113 class ScopedPixelAccess { |
| 114 public: |
| 115 ScopedPixelAccess(JNIEnv* env, jobject java_canvas) { |
| 116 AwDrawSWFunctionTable* sw_functions = |
| 117 BrowserViewRenderer::GetAwDrawSWFunctionTable(); |
| 118 pixels_ = sw_functions ? |
| 119 sw_functions->access_pixels(env, java_canvas) : NULL; |
| 120 } |
| 121 ~ScopedPixelAccess() { |
| 122 if (pixels_) |
| 123 BrowserViewRenderer::GetAwDrawSWFunctionTable()->release_pixels(pixels_); |
| 124 } |
| 125 AwPixelInfo* pixels() { return pixels_; } |
| 126 |
| 127 private: |
| 128 AwPixelInfo* pixels_; |
| 129 |
| 130 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPixelAccess); |
| 131 }; |
| 132 |
113 bool HardwareEnabled() { | 133 bool HardwareEnabled() { |
114 static bool g_hw_enabled = !CommandLine::ForCurrentProcess()->HasSwitch( | 134 static bool g_hw_enabled = !CommandLine::ForCurrentProcess()->HasSwitch( |
115 switches::kDisableWebViewGLMode); | 135 switches::kDisableWebViewGLMode); |
116 return g_hw_enabled; | 136 return g_hw_enabled; |
117 } | 137 } |
118 | 138 |
119 // Provides software rendering functions from the Android glue layer. | 139 // Provides software rendering functions from the Android glue layer. |
120 // Allows preventing extra copies of data when rendering. | 140 // Allows preventing extra copies of data when rendering. |
121 AwDrawSWFunctionTable* g_sw_draw_functions = NULL; | 141 AwDrawSWFunctionTable* g_sw_draw_functions = NULL; |
122 | 142 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 // static | 426 // static |
407 bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded( | 427 bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded( |
408 jobject java_canvas, | 428 jobject java_canvas, |
409 BrowserViewRenderer::JavaHelper* java_helper, | 429 BrowserViewRenderer::JavaHelper* java_helper, |
410 const gfx::Vector2d& scroll_correction, | 430 const gfx::Vector2d& scroll_correction, |
411 const gfx::Rect& clip, | 431 const gfx::Rect& clip, |
412 InProcessViewRenderer::RenderMethod render_source, | 432 InProcessViewRenderer::RenderMethod render_source, |
413 void* owner_key) { | 433 void* owner_key) { |
414 TRACE_EVENT0("android_webview", | 434 TRACE_EVENT0("android_webview", |
415 "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded"); | 435 "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded"); |
| 436 |
416 JNIEnv* env = AttachCurrentThread(); | 437 JNIEnv* env = AttachCurrentThread(); |
| 438 ScopedPixelAccess auto_release_pixels(env, java_canvas); |
| 439 AwPixelInfo* pixels = auto_release_pixels.pixels(); |
| 440 SkMatrix matrix; |
| 441 SkBitmap::Config config(SkBitmap::kNo_Config); |
| 442 if (pixels) { |
| 443 switch (pixels->config) { |
| 444 case AwConfig_ARGB_8888: |
| 445 config = SkBitmap::kARGB_8888_Config; |
| 446 break; |
| 447 case AwConfig_RGB_565: |
| 448 config = SkBitmap::kRGB_565_Config; |
| 449 break; |
| 450 } |
417 | 451 |
418 AwDrawSWFunctionTable* sw_functions = GetAwDrawSWFunctionTable(); | 452 for (int i = 0; i < 9; i++) { |
419 AwPixelInfo* pixels = sw_functions ? | 453 matrix.set(i, pixels->matrix[i]); |
420 sw_functions->access_pixels(env, java_canvas) : NULL; | 454 } |
421 if (pixels == NULL) { | 455 // Workaround for http://crbug.com/271096: SW draw only supports |
| 456 // translate & scale transforms. |
| 457 if (matrix.getType() & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) |
| 458 config = SkBitmap::kNo_Config; |
| 459 } |
| 460 |
| 461 if (config == SkBitmap::kNo_Config) { |
422 // Render into an auxiliary bitmap if pixel info is not available. | 462 // Render into an auxiliary bitmap if pixel info is not available. |
423 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); | 463 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); |
424 TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); | 464 TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); |
425 ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap( | 465 ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap( |
426 env, clip.width(), clip.height(), jcanvas, owner_key)); | 466 env, clip.width(), clip.height(), jcanvas, owner_key)); |
427 if (!jbitmap.obj()) { | 467 if (!jbitmap.obj()) { |
428 TRACE_EVENT_INSTANT0("android_webview", | 468 TRACE_EVENT_INSTANT0("android_webview", |
429 "EarlyOut_BitmapAllocFail", | 469 "EarlyOut_BitmapAllocFail", |
430 TRACE_EVENT_SCOPE_THREAD); | 470 TRACE_EVENT_SCOPE_THREAD); |
431 return false; | 471 return false; |
432 } | 472 } |
433 | 473 |
434 if (!RasterizeIntoBitmap(env, jbitmap, | 474 if (!RasterizeIntoBitmap(env, jbitmap, |
435 clip.x() - scroll_correction.x(), | 475 clip.x() - scroll_correction.x(), |
436 clip.y() - scroll_correction.y(), | 476 clip.y() - scroll_correction.y(), |
437 render_source)) { | 477 render_source)) { |
438 TRACE_EVENT_INSTANT0("android_webview", | 478 TRACE_EVENT_INSTANT0("android_webview", |
439 "EarlyOut_RasterizeFail", | 479 "EarlyOut_RasterizeFail", |
440 TRACE_EVENT_SCOPE_THREAD); | 480 TRACE_EVENT_SCOPE_THREAD); |
441 return false; | 481 return false; |
442 } | 482 } |
443 | 483 |
444 java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas, | 484 java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas, |
445 clip.x(), clip.y()); | 485 clip.x(), clip.y()); |
446 return true; | 486 return true; |
447 } | 487 } |
448 | 488 |
449 // Draw in a SkCanvas built over the pixel information. | 489 // Draw in a SkCanvas built over the pixel information. |
450 bool succeeded = false; | 490 SkBitmap bitmap; |
451 { | 491 bitmap.setConfig(config, |
452 SkBitmap bitmap; | 492 pixels->width, |
453 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), | 493 pixels->height, |
454 pixels->width, | 494 pixels->row_bytes); |
455 pixels->height, | 495 bitmap.setPixels(pixels->pixels); |
456 pixels->row_bytes); | 496 SkDevice device(bitmap); |
457 bitmap.setPixels(pixels->pixels); | 497 SkCanvas canvas(&device); |
458 SkDevice device(bitmap); | 498 canvas.setMatrix(matrix); |
459 SkCanvas canvas(&device); | |
460 SkMatrix matrix; | |
461 for (int i = 0; i < 9; i++) | |
462 matrix.set(i, pixels->matrix[i]); | |
463 canvas.setMatrix(matrix); | |
464 | 499 |
465 if (pixels->clip_region_size) { | 500 if (pixels->clip_region) { |
466 SkRegion clip_region; | 501 SkRegion clip_region; |
467 size_t bytes_read = clip_region.readFromMemory(pixels->clip_region); | 502 size_t bytes_read = clip_region.readFromMemory(pixels->clip_region); |
468 DCHECK_EQ(pixels->clip_region_size, bytes_read); | 503 DCHECK_EQ(pixels->clip_region_size, bytes_read); |
469 canvas.setClipRegion(clip_region); | 504 canvas.setClipRegion(clip_region); |
470 } else { | 505 } else if (pixels->clip_rect_count) { |
471 canvas.clipRect(gfx::RectToSkRect(clip)); | 506 SkRegion clip; |
| 507 for (int i = 0; i < pixels->clip_rect_count; ++i) { |
| 508 clip.op(SkIRect::MakeXYWH(pixels->clip_rects[i + 0], |
| 509 pixels->clip_rects[i + 1], |
| 510 pixels->clip_rects[i + 2], |
| 511 pixels->clip_rects[i + 3]), |
| 512 SkRegion::kUnion_Op); |
472 } | 513 } |
473 canvas.translate(scroll_correction.x(), | 514 canvas.setClipRegion(clip); |
474 scroll_correction.y()); | |
475 | |
476 succeeded = render_source.Run(&canvas); | |
477 } | 515 } |
478 | 516 |
479 sw_functions->release_pixels(pixels); | 517 canvas.translate(scroll_correction.x(), |
480 return succeeded; | 518 scroll_correction.y()); |
| 519 |
| 520 return render_source.Run(&canvas); |
481 } | 521 } |
482 | 522 |
483 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, | 523 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, |
484 int height) { | 524 int height) { |
| 525 TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture"); |
| 526 |
485 // Return empty Picture objects for empty SkPictures. | 527 // Return empty Picture objects for empty SkPictures. |
486 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); | 528 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); |
487 if (width <= 0 || height <= 0) { | 529 if (width <= 0 || height <= 0) { |
488 return picture; | 530 return picture; |
489 } | 531 } |
490 | 532 |
491 // Reset scroll back to the origin, will go back to the old | 533 // Reset scroll back to the origin, will go back to the old |
492 // value when scroll_reset is out of scope. | 534 // value when scroll_reset is out of scope. |
493 base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_css_, | 535 base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_css_, |
494 gfx::Vector2d()); | 536 gfx::Vector2d()); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 base::StringAppendF(&str, | 825 base::StringAppendF(&str, |
784 "surface width height: [%d %d] ", | 826 "surface width height: [%d %d] ", |
785 draw_info->width, | 827 draw_info->width, |
786 draw_info->height); | 828 draw_info->height); |
787 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); | 829 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); |
788 } | 830 } |
789 return str; | 831 return str; |
790 } | 832 } |
791 | 833 |
792 } // namespace android_webview | 834 } // namespace android_webview |
OLD | NEW |