Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1040)

Side by Side Diff: android_webview/browser/in_process_view_renderer.cc

Issue 22035002: Android WebView: Make a custom Picture subclass (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/scoped_app_gl_state_restore.h" 9 #include "android_webview/browser/scoped_app_gl_state_restore.h"
10 #include "android_webview/public/browser/draw_gl.h" 10 #include "android_webview/public/browser/draw_gl.h"
11 #include "android_webview/public/browser/draw_sw.h" 11 #include "android_webview/public/browser/draw_sw.h"
12 #include "base/android/jni_android.h" 12 #include "base/android/jni_android.h"
13 #include "base/auto_reset.h" 13 #include "base/auto_reset.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/debug/trace_event.h" 15 #include "base/debug/trace_event.h"
16 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "content/public/browser/android/synchronous_compositor.h" 19 #include "content/public/browser/android/synchronous_compositor.h"
20 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/web_contents.h" 21 #include "content/public/browser/web_contents.h"
22 #include "gpu/command_buffer/service/in_process_command_buffer.h" 22 #include "gpu/command_buffer/service/in_process_command_buffer.h"
23 #include "skia/ext/refptr.h"
24 #include "third_party/skia/include/core/SkBitmap.h" 23 #include "third_party/skia/include/core/SkBitmap.h"
25 #include "third_party/skia/include/core/SkCanvas.h" 24 #include "third_party/skia/include/core/SkCanvas.h"
26 #include "third_party/skia/include/core/SkDevice.h" 25 #include "third_party/skia/include/core/SkDevice.h"
27 #include "third_party/skia/include/core/SkGraphics.h" 26 #include "third_party/skia/include/core/SkGraphics.h"
28 #include "third_party/skia/include/core/SkPicture.h" 27 #include "third_party/skia/include/core/SkPicture.h"
29 #include "ui/gfx/skia_util.h" 28 #include "ui/gfx/skia_util.h"
30 #include "ui/gfx/transform.h" 29 #include "ui/gfx/transform.h"
31 #include "ui/gfx/vector2d_conversions.h" 30 #include "ui/gfx/vector2d_conversions.h"
32 #include "ui/gfx/vector2d_f.h" 31 #include "ui/gfx/vector2d_f.h"
33 32
(...skipping 21 matching lines...) Expand all
55 return NULL; 54 return NULL;
56 UserData* data = reinterpret_cast<UserData*>( 55 UserData* data = reinterpret_cast<UserData*>(
57 contents->GetUserData(kUserDataKey)); 56 contents->GetUserData(kUserDataKey));
58 return data ? data->instance_ : NULL; 57 return data ? data->instance_ : NULL;
59 } 58 }
60 59
61 private: 60 private:
62 InProcessViewRenderer* instance_; 61 InProcessViewRenderer* instance_;
63 }; 62 };
64 63
65 typedef base::Callback<bool(SkCanvas*)> RenderMethod;
66
67 bool RasterizeIntoBitmap(JNIEnv* env, 64 bool RasterizeIntoBitmap(JNIEnv* env,
68 const JavaRef<jobject>& jbitmap, 65 const JavaRef<jobject>& jbitmap,
69 int scroll_x, 66 int scroll_x,
70 int scroll_y, 67 int scroll_y,
71 const RenderMethod& renderer) { 68 const InProcessViewRenderer::RenderMethod& renderer) {
72 DCHECK(jbitmap.obj()); 69 DCHECK(jbitmap.obj());
73 70
74 AndroidBitmapInfo bitmap_info; 71 AndroidBitmapInfo bitmap_info;
75 if (AndroidBitmap_getInfo(env, jbitmap.obj(), &bitmap_info) < 0) { 72 if (AndroidBitmap_getInfo(env, jbitmap.obj(), &bitmap_info) < 0) {
76 LOG(ERROR) << "Error getting java bitmap info."; 73 LOG(ERROR) << "Error getting java bitmap info.";
77 return false; 74 return false;
78 } 75 }
79 76
80 void* pixels = NULL; 77 void* pixels = NULL;
81 if (AndroidBitmap_lockPixels(env, jbitmap.obj(), &pixels) < 0) { 78 if (AndroidBitmap_lockPixels(env, jbitmap.obj(), &pixels) < 0) {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 EnsureContinuousInvalidation(draw_info, !drew_full_visible_rect); 354 EnsureContinuousInvalidation(draw_info, !drew_full_visible_rect);
358 } 355 }
359 356
360 void InProcessViewRenderer::SetGlobalVisibleRect( 357 void InProcessViewRenderer::SetGlobalVisibleRect(
361 const gfx::Rect& visible_rect) { 358 const gfx::Rect& visible_rect) {
362 cached_global_visible_rect_ = visible_rect; 359 cached_global_visible_rect_ = visible_rect;
363 } 360 }
364 361
365 bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas, 362 bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas,
366 const gfx::Rect& clip) { 363 const gfx::Rect& clip) {
367 TRACE_EVENT0("android_webview", "InProcessViewRenderer::DrawSW");
368 fallback_tick_.Cancel(); 364 fallback_tick_.Cancel();
369 365
370 if (clip.IsEmpty()) { 366 if (clip.IsEmpty()) {
371 TRACE_EVENT_INSTANT0( 367 TRACE_EVENT_INSTANT0(
372 "android_webview", "EarlyOut_EmptyClip", TRACE_EVENT_SCOPE_THREAD); 368 "android_webview", "EarlyOut_EmptyClip", TRACE_EVENT_SCOPE_THREAD);
373 return true; 369 return true;
374 } 370 }
375 371
376 if (!compositor_) { 372 if (!compositor_) {
377 TRACE_EVENT_INSTANT0( 373 TRACE_EVENT_INSTANT0(
378 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); 374 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD);
379 return false; 375 return false;
380 } 376 }
381 377
378 return RenderViaAuxilaryBitmapIfNeeded(
379 java_canvas,
380 java_helper_,
381 scroll_at_start_of_frame_,
382 clip,
383 base::Bind(&InProcessViewRenderer::CompositeSW,
384 base::Unretained(this)),
385 web_contents_);
386 }
387
388 // static
389 bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
390 jobject java_canvas,
391 BrowserViewRenderer::JavaHelper* java_helper,
392 const gfx::Vector2d& scroll_correction,
393 const gfx::Rect& clip,
394 InProcessViewRenderer::RenderMethod render_source,
395 void* owner_key) {
396 TRACE_EVENT0("android_webview",
397 "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded");
382 JNIEnv* env = AttachCurrentThread(); 398 JNIEnv* env = AttachCurrentThread();
383 399
384 AwDrawSWFunctionTable* sw_functions = GetAwDrawSWFunctionTable(); 400 AwDrawSWFunctionTable* sw_functions = GetAwDrawSWFunctionTable();
385 AwPixelInfo* pixels = sw_functions ? 401 AwPixelInfo* pixels = sw_functions ?
386 sw_functions->access_pixels(env, java_canvas) : NULL; 402 sw_functions->access_pixels(env, java_canvas) : NULL;
387 // Render into an auxiliary bitmap if pixel info is not available.
388 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas);
389 if (pixels == NULL) { 403 if (pixels == NULL) {
404 // Render into an auxiliary bitmap if pixel info is not available.
405 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas);
390 TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); 406 TRACE_EVENT0("android_webview", "RenderToAuxBitmap");
391 ScopedJavaLocalRef<jobject> jbitmap(java_helper_->CreateBitmap( 407 ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap(
392 env, clip.width(), clip.height(), jcanvas, web_contents_)); 408 env, clip.width(), clip.height(), jcanvas, owner_key));
393 if (!jbitmap.obj()) { 409 if (!jbitmap.obj()) {
394 TRACE_EVENT_INSTANT0("android_webview", 410 TRACE_EVENT_INSTANT0("android_webview",
395 "EarlyOut_BitmapAllocFail", 411 "EarlyOut_BitmapAllocFail",
396 TRACE_EVENT_SCOPE_THREAD); 412 TRACE_EVENT_SCOPE_THREAD);
397 return false; 413 return false;
398 } 414 }
399 415
400 if (!RasterizeIntoBitmap(env, jbitmap, 416 if (!RasterizeIntoBitmap(env, jbitmap,
401 clip.x() - scroll_at_start_of_frame_.x(), 417 clip.x() - scroll_correction.x(),
402 clip.y() - scroll_at_start_of_frame_.y(), 418 clip.y() - scroll_correction.y(),
403 base::Bind(&InProcessViewRenderer::CompositeSW, 419 render_source)) {
404 base::Unretained(this)))) {
405 TRACE_EVENT_INSTANT0("android_webview", 420 TRACE_EVENT_INSTANT0("android_webview",
406 "EarlyOut_RasterizeFail", 421 "EarlyOut_RasterizeFail",
407 TRACE_EVENT_SCOPE_THREAD); 422 TRACE_EVENT_SCOPE_THREAD);
408 return false; 423 return false;
409 } 424 }
410 425
411 java_helper_->DrawBitmapIntoCanvas(env, jbitmap, jcanvas, 426 java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas,
412 clip.x(), clip.y()); 427 clip.x(), clip.y());
413 return true; 428 return true;
414 } 429 }
415 430
416 // Draw in a SkCanvas built over the pixel information. 431 // Draw in a SkCanvas built over the pixel information.
417 bool succeeded = false; 432 bool succeeded = false;
418 { 433 {
419 SkBitmap bitmap; 434 SkBitmap bitmap;
420 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), 435 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config),
421 pixels->width, 436 pixels->width,
422 pixels->height, 437 pixels->height,
423 pixels->row_bytes); 438 pixels->row_bytes);
424 bitmap.setPixels(pixels->pixels); 439 bitmap.setPixels(pixels->pixels);
425 SkDevice device(bitmap); 440 SkDevice device(bitmap);
426 SkCanvas canvas(&device); 441 SkCanvas canvas(&device);
427 SkMatrix matrix; 442 SkMatrix matrix;
428 for (int i = 0; i < 9; i++) 443 for (int i = 0; i < 9; i++)
429 matrix.set(i, pixels->matrix[i]); 444 matrix.set(i, pixels->matrix[i]);
430 canvas.setMatrix(matrix); 445 canvas.setMatrix(matrix);
431 446
432 if (pixels->clip_region_size) { 447 if (pixels->clip_region_size) {
433 SkRegion clip_region; 448 SkRegion clip_region;
434 size_t bytes_read = clip_region.readFromMemory(pixels->clip_region); 449 size_t bytes_read = clip_region.readFromMemory(pixels->clip_region);
435 DCHECK_EQ(pixels->clip_region_size, bytes_read); 450 DCHECK_EQ(pixels->clip_region_size, bytes_read);
436 canvas.setClipRegion(clip_region); 451 canvas.setClipRegion(clip_region);
437 } else { 452 } else {
438 canvas.clipRect(gfx::RectToSkRect(clip)); 453 canvas.clipRect(gfx::RectToSkRect(clip));
439 } 454 }
440 canvas.translate(scroll_at_start_of_frame_.x(), 455 canvas.translate(scroll_correction.x(),
441 scroll_at_start_of_frame_.y()); 456 scroll_correction.y());
442 457
443 succeeded = CompositeSW(&canvas); 458 succeeded = render_source.Run(&canvas);
444 } 459 }
445 460
446 sw_functions->release_pixels(pixels); 461 sw_functions->release_pixels(pixels);
447 return succeeded; 462 return succeeded;
448 } 463 }
449 464
450 base::android::ScopedJavaLocalRef<jobject> 465 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width,
451 InProcessViewRenderer::CapturePicture(int width, int height) { 466 int height) {
452 if (!compositor_ || !GetAwDrawSWFunctionTable()) {
453 TRACE_EVENT_INSTANT0(
454 "android_webview", "EarlyOut_CapturePicture", TRACE_EVENT_SCOPE_THREAD);
455 return ScopedJavaLocalRef<jobject>();
456 }
457
458 // Return empty Picture objects for empty SkPictures. 467 // Return empty Picture objects for empty SkPictures.
459 JNIEnv* env = AttachCurrentThread(); 468 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture);
460 if (width <= 0 || height <= 0) { 469 if (width <= 0 || height <= 0) {
461 return java_helper_->RecordBitmapIntoPicture(env, 470 return picture;
462 ScopedJavaLocalRef<jobject>());
463 } 471 }
464 472
465 // Reset scroll back to the origin, will go back to the old 473 // Reset scroll back to the origin, will go back to the old
466 // value when scroll_reset is out of scope. 474 // value when scroll_reset is out of scope.
467 base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_css_, 475 base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_css_,
468 gfx::Vector2d()); 476 gfx::Vector2d());
469 477
470 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture);
471 SkCanvas* rec_canvas = picture->beginRecording(width, height, 0); 478 SkCanvas* rec_canvas = picture->beginRecording(width, height, 0);
472 if (!CompositeSW(rec_canvas)) 479 if (compositor_)
473 return ScopedJavaLocalRef<jobject>(); 480 CompositeSW(rec_canvas);
474 picture->endRecording(); 481 picture->endRecording();
475 482 return picture;
476 if (IsSkiaVersionCompatible()) {
477 // Add a reference that the create_picture() will take ownership of.
478 picture->ref();
479 return ScopedJavaLocalRef<jobject>(env,
480 GetAwDrawSWFunctionTable()->create_picture(env, picture.get()));
481 }
482
483 // If Skia versions are not compatible, workaround it by rasterizing the
484 // picture into a bitmap and drawing it into a new Java picture. Pass null
485 // for |canvas| as we don't have java canvas at this point (and it would be
486 // software anyway).
487 ScopedJavaLocalRef<jobject> jbitmap(java_helper_->CreateBitmap(
488 env, picture->width(), picture->height(), ScopedJavaLocalRef<jobject>(),
489 NULL));
490 if (!jbitmap.obj())
491 return ScopedJavaLocalRef<jobject>();
492
493 if (!RasterizeIntoBitmap(env, jbitmap, 0, 0,
494 base::Bind(&RenderPictureToCanvas,
495 base::Unretained(picture.get())))) {
496 return ScopedJavaLocalRef<jobject>();
497 }
498
499 return java_helper_->RecordBitmapIntoPicture(env, jbitmap);
500 } 483 }
501 484
502 void InProcessViewRenderer::EnableOnNewPicture(bool enabled) { 485 void InProcessViewRenderer::EnableOnNewPicture(bool enabled) {
503 on_new_picture_enable_ = enabled; 486 on_new_picture_enable_ = enabled;
504 } 487 }
505 488
506 void InProcessViewRenderer::OnVisibilityChanged(bool visible) { 489 void InProcessViewRenderer::OnVisibilityChanged(bool visible) {
507 TRACE_EVENT_INSTANT1("android_webview", 490 TRACE_EVENT_INSTANT1("android_webview",
508 "InProcessViewRenderer::OnVisibilityChanged", 491 "InProcessViewRenderer::OnVisibilityChanged",
509 TRACE_EVENT_SCOPE_THREAD, 492 TRACE_EVENT_SCOPE_THREAD,
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 base::StringAppendF(&str, 757 base::StringAppendF(&str,
775 "surface width height: [%d %d] ", 758 "surface width height: [%d %d] ",
776 draw_info->width, 759 draw_info->width,
777 draw_info->height); 760 draw_info->height);
778 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); 761 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer);
779 } 762 }
780 return str; 763 return str;
781 } 764 }
782 765
783 } // namespace android_webview 766 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698