| 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 |