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

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

Issue 22799011: [WIP] Import all canvas layers, rather than just topmost (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleaner version (but larger diff) 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
« no previous file with comments | « no previous file | android_webview/public/browser/draw_sw.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 return RenderViaAuxilaryBitmapIfNeeded( 416 return RenderViaAuxilaryBitmapIfNeeded(
417 java_canvas, 417 java_canvas,
418 java_helper_, 418 java_helper_,
419 scroll_at_start_of_frame_, 419 scroll_at_start_of_frame_,
420 clip, 420 clip,
421 base::Bind(&InProcessViewRenderer::CompositeSW, 421 base::Bind(&InProcessViewRenderer::CompositeSW,
422 base::Unretained(this)), 422 base::Unretained(this)),
423 web_contents_); 423 web_contents_);
424 } 424 }
425 425
426 // static 426 namespace {
427 bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
428 jobject java_canvas,
429 BrowserViewRenderer::JavaHelper* java_helper,
430 const gfx::Vector2d& scroll_correction,
431 const gfx::Rect& clip,
432 InProcessViewRenderer::RenderMethod render_source,
433 void* owner_key) {
434 TRACE_EVENT0("android_webview",
435 "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded");
436 427
437 JNIEnv* env = AttachCurrentThread(); 428 struct LayerImportState {
429 bool SetBitmap(const AwBitmapInfo& info) {
430 SkBitmap::Config config =
431 info.config == AwConfig_ARGB_8888 ? SkBitmap::kARGB_8888_Config :
432 info.config == AwConfig_RGB_565 ? SkBitmap::kRGB_565_Config :
433 SkBitmap::kNo_Config;
434 if (config == SkBitmap::kNo_Config)
435 return false;
436 bitmap.setConfig(config, info.width, info.height, info.row_bytes);
437 bitmap.setPixels(info.pixels);
438
439 LOG(WARNING) << "JOTH decode: " << info.x << ", " << info.y
440 << ", " << info.width << ", " << info.height;
441 return true;
442 }
443 SkBitmap bitmap;
444 bool importing;
445 };
446
447 class LayerImportDevice : public SkDevice {
448 public:
449 LayerImportDevice(const LayerImportState* state)
450 : SkDevice(state->bitmap),
451 state_(state) {
452 DCHECK(state_->importing);
453 }
454
455 SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
456 int width, int height,
457 bool isOpaque,
458 Usage usage) {
459 const SkBitmap& bitmap = state_->bitmap;
460 if (!state_->importing) {
461 DCHECK(bitmap.empty() && state_->bitmap.isNull());
462 return new SkDevice(config, width, height, isOpaque);
463 }
464 DCHECK(usage != SkDevice::kGeneral_Usage);
465 DCHECK(bitmap.config() == config);
466 DCHECK(bitmap.width() == width);
467 DCHECK(bitmap.height() == height);
468 DCHECK(width == 0 || height == 0 || !bitmap.isNull());
469 return new LayerImportDevice(state_);
470 }
471
472 private:
473 const LayerImportState* state_;
474 };
475
476 bool RenderDirectToCanvas(JNIEnv* env,
477 jobject java_canvas,
478 BrowserViewRenderer::JavaHelper* java_helper,
479 const gfx::Vector2d& scroll_correction,
480 InProcessViewRenderer::RenderMethod render_source) {
438 ScopedPixelAccess auto_release_pixels(env, java_canvas); 481 ScopedPixelAccess auto_release_pixels(env, java_canvas);
439 AwPixelInfo* pixels = auto_release_pixels.pixels(); 482 AwPixelInfo* pixels = auto_release_pixels.pixels();
483 if (!pixels)
484 return false;
485
440 SkMatrix matrix; 486 SkMatrix matrix;
441 SkBitmap::Config config(SkBitmap::kNo_Config); 487 for (int i = 0; i < 9; i++) {
442 if (pixels) { 488 matrix.set(i, pixels->matrix[i]);
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 }
451
452 for (int i = 0; i < 9; i++) {
453 matrix.set(i, pixels->matrix[i]);
454 }
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 } 489 }
460 490 // Workarounds for http://crbug.com/271096: SW draw only supports
461 if (config == SkBitmap::kNo_Config) { 491 // translate & scale transforms, and a simple rectangular clip.
462 // Render into an auxiliary bitmap if pixel info is not available. 492 if (matrix.getType() & ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))
463 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); 493 return false;
464 TRACE_EVENT0("android_webview", "RenderToAuxBitmap"); 494 if (pixels->clip_rect_count > 1)
465 ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap( 495 return false;
466 env, clip.width(), clip.height(), jcanvas, owner_key));
467 if (!jbitmap.obj()) {
468 TRACE_EVENT_INSTANT0("android_webview",
469 "EarlyOut_BitmapAllocFail",
470 TRACE_EVENT_SCOPE_THREAD);
471 return false;
472 }
473
474 if (!RasterizeIntoBitmap(env, jbitmap,
475 clip.x() - scroll_correction.x(),
476 clip.y() - scroll_correction.y(),
477 render_source)) {
478 TRACE_EVENT_INSTANT0("android_webview",
479 "EarlyOut_RasterizeFail",
480 TRACE_EVENT_SCOPE_THREAD);
481 return false;
482 }
483
484 java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas,
485 clip.x(), clip.y());
486 return true;
487 }
488 496
489 // Draw in a SkCanvas built over the pixel information. 497 // Draw in a SkCanvas built over the pixel information.
490 SkBitmap bitmap; 498 if (pixels->layer_count < 1)
491 bitmap.setConfig(config, 499 return false;
492 pixels->width, 500 LayerImportState layer;
493 pixels->height, 501 layer.importing = true;
494 pixels->row_bytes); 502 if (!layer.SetBitmap(pixels->layers[0]))
495 bitmap.setPixels(pixels->pixels); 503 return false;
496 SkDevice device(bitmap); 504 LayerImportDevice device(&layer);
497 SkCanvas canvas(&device); 505 SkCanvas canvas(&device);
498 canvas.setMatrix(matrix); 506
507 // Iterate over the layers above the root (hence, starting a 1).
508 for (int i = 1; i < pixels->layer_count; ++i) {
509 const AwBitmapInfo& bitmap = pixels->layers[i];
510 layer.SetBitmap(bitmap);
511 SkRect rect = SkRect::MakeXYWH(bitmap.x, bitmap.y,
512 bitmap.width, bitmap.height);
513 // Use a "dest" xfer so that our shadow-layer stack restore is a no-op.
514 SkPaint dest_mode;
515 dest_mode.setXfermodeMode(SkXfermode::kDst_Mode);
516 canvas.saveLayer(&rect, &dest_mode, SkCanvas::kARGB_NoClipLayer_SaveFlag);
517 DCHECK(canvas.getTopDevice()->getOrigin() ==
518 SkIPoint::Make(bitmap.x, bitmap.y));
519 }
520 layer.bitmap.reset();
521 layer.importing = false;
499 522
500 if (pixels->clip_rect_count) { 523 if (pixels->clip_rect_count) {
501 SkRegion clip; 524 SkRegion clip;
502 for (int i = 0; i < pixels->clip_rect_count; ++i) { 525 for (int i = 0; i < pixels->clip_rect_count; ++i) {
503 clip.op(SkIRect::MakeXYWH(pixels->clip_rects[i + 0], 526 clip.op(SkIRect::MakeXYWH(pixels->clip_rects[i + 0],
504 pixels->clip_rects[i + 1], 527 pixels->clip_rects[i + 1],
505 pixels->clip_rects[i + 2], 528 pixels->clip_rects[i + 2],
506 pixels->clip_rects[i + 3]), 529 pixels->clip_rects[i + 3]),
507 SkRegion::kUnion_Op); 530 SkRegion::kUnion_Op);
508 } 531 }
509 canvas.setClipRegion(clip); 532 canvas.setClipRegion(clip);
510 } 533 }
511 534 canvas.setMatrix(matrix);
512 canvas.translate(scroll_correction.x(), 535 canvas.translate(scroll_correction.x(),
513 scroll_correction.y()); 536 scroll_correction.y());
514 537
515 return render_source.Run(&canvas); 538 return render_source.Run(&canvas);
516 } 539 }
517 540
541 } // namespace
542
543 bool InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded(
544 jobject java_canvas,
545 BrowserViewRenderer::JavaHelper* java_helper,
546 const gfx::Vector2d& scroll_correction,
547 const gfx::Rect& clip,
548 InProcessViewRenderer::RenderMethod render_source,
549 void* owner_key) {
550 TRACE_EVENT0("android_webview",
551 "InProcessViewRenderer::RenderViaAuxilaryBitmapIfNeeded");
552
553 JNIEnv* env = AttachCurrentThread();
554 if (RenderDirectToCanvas(env,
555 java_canvas,
556 java_helper,
557 scroll_correction,
558 render_source)) {
559 return true;
560 }
561 // Render into an auxiliary bitmap if pixel info is not available.
562 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas);
563 TRACE_EVENT0("android_webview", "RenderToAuxBitmap");
564 ScopedJavaLocalRef<jobject> jbitmap(java_helper->CreateBitmap(
565 env, clip.width(), clip.height(), jcanvas, owner_key));
566 if (!jbitmap.obj()) {
567 TRACE_EVENT_INSTANT0("android_webview",
568 "EarlyOut_BitmapAllocFail",
569 TRACE_EVENT_SCOPE_THREAD);
570 return false;
571 }
572
573 if (!RasterizeIntoBitmap(env, jbitmap,
574 clip.x() - scroll_correction.x(),
575 clip.y() - scroll_correction.y(),
576 render_source)) {
577 TRACE_EVENT_INSTANT0("android_webview",
578 "EarlyOut_RasterizeFail",
579 TRACE_EVENT_SCOPE_THREAD);
580 return false;
581 }
582
583 java_helper->DrawBitmapIntoCanvas(env, jbitmap, jcanvas,
584 clip.x(), clip.y());
585 return true;
586 }
587
518 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, 588 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width,
519 int height) { 589 int height) {
520 TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture"); 590 TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture");
521 591
522 // Return empty Picture objects for empty SkPictures. 592 // Return empty Picture objects for empty SkPictures.
523 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); 593 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture);
524 if (width <= 0 || height <= 0) { 594 if (width <= 0 || height <= 0) {
525 return picture; 595 return picture;
526 } 596 }
527 597
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 base::StringAppendF(&str, 890 base::StringAppendF(&str,
821 "surface width height: [%d %d] ", 891 "surface width height: [%d %d] ",
822 draw_info->width, 892 draw_info->width,
823 draw_info->height); 893 draw_info->height);
824 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); 894 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer);
825 } 895 }
826 return str; 896 return str;
827 } 897 }
828 898
829 } // namespace android_webview 899 } // namespace android_webview
OLDNEW
« no previous file with comments | « no previous file | android_webview/public/browser/draw_sw.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698