OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "webkit/plugins/ppapi/ppb_graphics_2d_impl.h" | 5 #include "webkit/plugins/ppapi/ppb_graphics_2d_impl.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 // actually painted something. By not bothering to schedule an invalidate | 474 // actually painted something. By not bothering to schedule an invalidate |
475 // when an empty device is initially bound, we can save an extra paint for | 475 // when an empty device is initially bound, we can save an extra paint for |
476 // many plugins during the critical page initialization phase. | 476 // many plugins during the critical page initialization phase. |
477 new_instance->InvalidateRect(gfx::Rect()); | 477 new_instance->InvalidateRect(gfx::Rect()); |
478 } | 478 } |
479 | 479 |
480 bound_instance_ = new_instance; | 480 bound_instance_ = new_instance; |
481 return true; | 481 return true; |
482 } | 482 } |
483 | 483 |
| 484 // The |backing_bitmap| must be clipped to the |plugin_rect| to avoid painting |
| 485 // outside the plugin area. This can happen if the plugin has been resized since |
| 486 // PaintImageData verified the image is within the plugin size. |
484 void PPB_Graphics2D_Impl::Paint(WebKit::WebCanvas* canvas, | 487 void PPB_Graphics2D_Impl::Paint(WebKit::WebCanvas* canvas, |
485 const gfx::Rect& plugin_rect, | 488 const gfx::Rect& plugin_rect, |
486 const gfx::Rect& paint_rect) { | 489 const gfx::Rect& paint_rect) { |
487 ImageDataAutoMapper auto_mapper(image_data_); | 490 ImageDataAutoMapper auto_mapper(image_data_); |
488 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); | 491 const SkBitmap& backing_bitmap = *image_data_->GetMappedBitmap(); |
489 | 492 |
490 #if defined(OS_MACOSX) | 493 #if defined(OS_MACOSX) |
491 SkAutoLockPixels lock(backing_bitmap); | 494 SkAutoLockPixels lock(backing_bitmap); |
492 | 495 |
493 base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( | 496 base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( |
494 CGDataProviderCreateWithData( | 497 CGDataProviderCreateWithData( |
495 NULL, backing_bitmap.getAddr32(0, 0), | 498 NULL, backing_bitmap.getAddr32(0, 0), |
496 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); | 499 backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); |
497 base::mac::ScopedCFTypeRef<CGImageRef> image( | 500 base::mac::ScopedCFTypeRef<CGImageRef> image( |
498 CGImageCreate( | 501 CGImageCreate( |
499 backing_bitmap.width(), backing_bitmap.height(), | 502 backing_bitmap.width(), backing_bitmap.height(), |
500 8, 32, backing_bitmap.rowBytes(), | 503 8, 32, backing_bitmap.rowBytes(), |
501 base::mac::GetSystemColorSpace(), | 504 base::mac::GetSystemColorSpace(), |
502 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, | 505 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, |
503 data_provider, NULL, false, kCGRenderingIntentDefault)); | 506 data_provider, NULL, false, kCGRenderingIntentDefault)); |
504 | 507 |
505 // Flip the transform | 508 // Flip the transform |
506 CGContextSaveGState(canvas); | 509 CGContextSaveGState(canvas); |
507 float window_height = static_cast<float>(CGBitmapContextGetHeight(canvas)); | 510 float window_height = static_cast<float>(CGBitmapContextGetHeight(canvas)); |
508 CGContextTranslateCTM(canvas, 0, window_height); | 511 CGContextTranslateCTM(canvas, 0, window_height); |
509 CGContextScaleCTM(canvas, 1.0, -1.0); | 512 CGContextScaleCTM(canvas, 1.0, -1.0); |
510 | 513 |
| 514 // To avoid painting outside the plugin boundaries and clip instead of |
| 515 // scaling, CGContextDrawImage() must draw the full image using |bitmap_rect| |
| 516 // but the context must be clipped to the plugin using |bounds|. |
| 517 |
| 518 CGRect bitmap_rect; |
| 519 bitmap_rect.origin.x = plugin_rect.origin().x(); |
| 520 bitmap_rect.origin.y = window_height - plugin_rect.origin().y() - |
| 521 backing_bitmap.height(); |
| 522 bitmap_rect.size.width = backing_bitmap.width(); |
| 523 bitmap_rect.size.height = backing_bitmap.height(); |
| 524 |
511 CGRect bounds; | 525 CGRect bounds; |
512 bounds.origin.x = plugin_rect.origin().x(); | 526 bounds.origin.x = plugin_rect.origin().x(); |
513 bounds.origin.y = window_height - plugin_rect.origin().y() - | 527 bounds.origin.y = window_height - plugin_rect.origin().y() - |
514 backing_bitmap.height(); | 528 plugin_rect.height(); |
515 bounds.size.width = backing_bitmap.width(); | 529 bounds.size.width = plugin_rect.width(); |
516 bounds.size.height = backing_bitmap.height(); | 530 bounds.size.height = plugin_rect.height(); |
| 531 |
| 532 CGContextClipToRect(canvas, bounds); |
517 | 533 |
518 // TODO(brettw) bug 56673: do a direct memcpy instead of going through CG | 534 // TODO(brettw) bug 56673: do a direct memcpy instead of going through CG |
519 // if the is_always_opaque_ flag is set. | 535 // if the is_always_opaque_ flag is set. Must ensure bitmap is still clipped. |
520 | 536 |
521 CGContextDrawImage(canvas, bounds, image); | 537 CGContextDrawImage(canvas, bitmap_rect, image); |
522 CGContextRestoreGState(canvas); | 538 CGContextRestoreGState(canvas); |
523 #else | 539 #else |
524 SkPaint paint; | 540 SkPaint paint; |
525 if (is_always_opaque_) { | 541 if (is_always_opaque_) { |
526 // When we know the device is opaque, we can disable blending for slightly | 542 // When we know the device is opaque, we can disable blending for slightly |
527 // more optimized painting. | 543 // more optimized painting. |
528 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 544 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
529 } | 545 } |
530 | 546 |
531 gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); | 547 canvas->save(); |
| 548 SkRect clip_rect = SkRect::MakeXYWH(SkIntToScalar(plugin_rect.origin().x()), |
| 549 SkIntToScalar(plugin_rect.origin().y()), |
| 550 SkIntToScalar(plugin_rect.width()), |
| 551 SkIntToScalar(plugin_rect.height())); |
| 552 canvas->clipRect(clip_rect); |
532 canvas->drawBitmap(backing_bitmap, | 553 canvas->drawBitmap(backing_bitmap, |
533 SkIntToScalar(plugin_rect.origin().x()), | 554 SkIntToScalar(plugin_rect.x()), |
534 SkIntToScalar(plugin_rect.origin().y()), | 555 SkIntToScalar(plugin_rect.y()), |
535 &paint); | 556 &paint); |
| 557 canvas->restore(); |
536 #endif | 558 #endif |
537 } | 559 } |
538 | 560 |
539 void PPB_Graphics2D_Impl::ViewInitiatedPaint() { | 561 void PPB_Graphics2D_Impl::ViewInitiatedPaint() { |
540 // Move any "unpainted" callback to the painted state. See | 562 // Move any "unpainted" callback to the painted state. See |
541 // |unpainted_flush_callback_| in the header for more. | 563 // |unpainted_flush_callback_| in the header for more. |
542 if (!unpainted_flush_callback_.is_null()) { | 564 if (!unpainted_flush_callback_.is_null()) { |
543 DCHECK(painted_flush_callback_.is_null()); | 565 DCHECK(painted_flush_callback_.is_null()); |
544 std::swap(painted_flush_callback_, unpainted_flush_callback_); | 566 std::swap(painted_flush_callback_, unpainted_flush_callback_); |
545 } | 567 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 | 666 |
645 bool PPB_Graphics2D_Impl::HasPendingFlush() const { | 667 bool PPB_Graphics2D_Impl::HasPendingFlush() const { |
646 return !unpainted_flush_callback_.is_null() || | 668 return !unpainted_flush_callback_.is_null() || |
647 !painted_flush_callback_.is_null() || | 669 !painted_flush_callback_.is_null() || |
648 offscreen_flush_pending_; | 670 offscreen_flush_pending_; |
649 } | 671 } |
650 | 672 |
651 } // namespace ppapi | 673 } // namespace ppapi |
652 } // namespace webkit | 674 } // namespace webkit |
653 | 675 |
OLD | NEW |