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

Side by Side Diff: webkit/plugins/ppapi/ppb_graphics_2d_impl.cc

Issue 6207002: Fixed bug 64847: Graphics2D paints outside plugin boundaries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 11 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 | « chrome/renderer/webplugin_delegate_pepper.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « chrome/renderer/webplugin_delegate_pepper.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698