Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 ConvertBetweenBGRAandRGBA( | 115 ConvertBetweenBGRAandRGBA( |
| 116 src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), | 116 src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), |
| 117 static_cast<int>(src_rect.fTop + y)), | 117 static_cast<int>(src_rect.fTop + y)), |
| 118 src_rect.width(), | 118 src_rect.width(), |
| 119 dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), | 119 dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), |
| 120 static_cast<int>(dest_rect.fTop + y))); | 120 static_cast<int>(dest_rect.fTop + y))); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Scale the rectangle, taking care to round coordinates outward so a | |
| 126 // rectangle scaled down then scaled back up by the inverse scale would | |
| 127 // fully contain the original. | |
|
Wez
2012/07/19 01:33:37
nit: Consider expressing this in terms of the goal
Josh Horwich
2012/07/19 22:22:44
Done.
| |
| 128 void ScaleRectBounds(gfx::Rect& rect, float scale) { | |
|
Wez
2012/07/19 01:33:37
nit: gfx::Rect ScaleRectBounds(const gfx::Rect& ..
Josh Horwich
2012/07/19 22:22:44
Done.
| |
| 129 int left = static_cast<int>(floorf(rect.x() * scale)); | |
| 130 int top = static_cast<int>(floorf(rect.y() * scale)); | |
| 131 int right = static_cast<int>(ceilf((rect.x() + rect.width()) * scale)); | |
| 132 int bottom = static_cast<int>(ceilf((rect.y() + rect.height()) * scale)); | |
| 133 rect.SetRect(left, top, right - left, bottom - top); | |
| 134 } | |
| 135 | |
| 125 } // namespace | 136 } // namespace |
| 126 | 137 |
| 127 struct PPB_Graphics2D_Impl::QueuedOperation { | 138 struct PPB_Graphics2D_Impl::QueuedOperation { |
| 128 enum Type { | 139 enum Type { |
| 129 PAINT, | 140 PAINT, |
| 130 SCROLL, | 141 SCROLL, |
| 131 REPLACE | 142 REPLACE |
| 132 }; | 143 }; |
| 133 | 144 |
| 134 QueuedOperation(Type t) | 145 QueuedOperation(Type t) |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 break; | 354 break; |
| 344 } | 355 } |
| 345 | 356 |
| 346 // For correctness with accelerated compositing, we must issue an invalidate | 357 // For correctness with accelerated compositing, we must issue an invalidate |
| 347 // on the full op_rect even if it is partially or completely off-screen. | 358 // on the full op_rect even if it is partially or completely off-screen. |
| 348 // However, if we issue an invalidate for a clipped-out region, WebKit will | 359 // However, if we issue an invalidate for a clipped-out region, WebKit will |
| 349 // do nothing and we won't get any ViewWillInitiatePaint/ViewFlushedPaint | 360 // do nothing and we won't get any ViewWillInitiatePaint/ViewFlushedPaint |
| 350 // calls, leaving our callback stranded. So we still need to check whether | 361 // calls, leaving our callback stranded. So we still need to check whether |
| 351 // the repainted area is visible to determine how to deal with the callback. | 362 // the repainted area is visible to determine how to deal with the callback. |
| 352 if (bound_instance_ && !op_rect.IsEmpty()) { | 363 if (bound_instance_ && !op_rect.IsEmpty()) { |
| 364 // Convert op_rect from context coordinates to logical pixels, taking care | |
| 365 // to include partially-covered logical pixels (aka DIPs). If the | |
| 366 // operation is a scroll, we also find out if we need to fall back to | |
| 367 // InvalidateRect due to the possibility that the scroll cannot accurately | |
| 368 // be described in logical pixels due to rounding errors | |
|
Wez
2012/07/19 01:33:37
typo: missing .
Josh Horwich
2012/07/19 22:22:44
Done.
| |
| 369 bool scroll = false; | |
| 370 if (operation.type == QueuedOperation::SCROLL) { | |
| 371 scroll = ScaleMetrics(scale_, | |
| 372 op_rect, | |
| 373 &operation.scroll_dx, | |
| 374 &operation.scroll_dy); | |
| 375 } else { | |
| 376 ScaleMetrics(scale_, op_rect, NULL, NULL); | |
|
Wez
2012/07/19 01:33:37
nit: Use ScaleRectBounds explicitly here.
Josh Horwich
2012/07/19 22:22:44
Done.
| |
| 377 } | |
| 353 | 378 |
| 354 // Set |nothing_visible| to false if the change overlaps the visible area. | 379 // Set |nothing_visible| to false if the change overlaps the visible area. |
| 355 gfx::Rect visible_changed_rect = | 380 gfx::Rect visible_changed_rect = |
| 356 PP_ToGfxRect(bound_instance_->view_data().clip_rect). | 381 PP_ToGfxRect(bound_instance_->view_data().clip_rect). |
| 357 Intersect(op_rect); | 382 Intersect(op_rect); |
| 358 if (!visible_changed_rect.IsEmpty()) | 383 if (!visible_changed_rect.IsEmpty()) |
| 359 nothing_visible = false; | 384 nothing_visible = false; |
| 360 | 385 |
| 361 // Notify the plugin of the entire change (op_rect), even if it is | 386 // Notify the plugin of the entire change (op_rect), even if it is |
| 362 // partially or completely off-screen. | 387 // partially or completely off-screen. |
| 363 if (operation.type == QueuedOperation::SCROLL) { | 388 if (scroll) { |
| 364 bound_instance_->ScrollRect(operation.scroll_dx, operation.scroll_dy, | 389 bound_instance_->ScrollRect(operation.scroll_dx, operation.scroll_dy, |
| 365 op_rect); | 390 op_rect); |
| 366 } else { | 391 } else { |
| 367 bound_instance_->InvalidateRect(op_rect); | 392 bound_instance_->InvalidateRect(op_rect); |
| 368 } | 393 } |
| 369 } | 394 } |
| 370 } | 395 } |
| 371 queued_operations_.clear(); | 396 queued_operations_.clear(); |
| 372 | 397 |
| 373 if (nothing_visible) { | 398 if (nothing_visible) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 517 | 542 |
| 518 CGRect bounds; | 543 CGRect bounds; |
| 519 bounds.origin.x = plugin_rect.origin().x(); | 544 bounds.origin.x = plugin_rect.origin().x(); |
| 520 bounds.origin.y = window_height - plugin_rect.origin().y() - | 545 bounds.origin.y = window_height - plugin_rect.origin().y() - |
| 521 plugin_rect.height(); | 546 plugin_rect.height(); |
| 522 bounds.size.width = plugin_rect.width(); | 547 bounds.size.width = plugin_rect.width(); |
| 523 bounds.size.height = plugin_rect.height(); | 548 bounds.size.height = plugin_rect.height(); |
| 524 | 549 |
| 525 CGContextClipToRect(canvas, bounds); | 550 CGContextClipToRect(canvas, bounds); |
| 526 | 551 |
| 552 // TODO(jhorwich) Figure out if this code is even active anymore, and if so | |
| 553 // how to properly handle scaling. | |
| 554 DCHECK_EQ(1.0f, scale_); | |
| 555 | |
| 527 // TODO(brettw) bug 56673: do a direct memcpy instead of going through CG | 556 // TODO(brettw) bug 56673: do a direct memcpy instead of going through CG |
| 528 // if the is_always_opaque_ flag is set. Must ensure bitmap is still clipped. | 557 // if the is_always_opaque_ flag is set. Must ensure bitmap is still clipped. |
| 529 | 558 |
| 530 CGContextDrawImage(canvas, bitmap_rect, image); | 559 CGContextDrawImage(canvas, bitmap_rect, image); |
| 531 CGContextRestoreGState(canvas); | 560 CGContextRestoreGState(canvas); |
| 532 #else | 561 #else |
| 533 SkRect sk_plugin_rect = SkRect::MakeXYWH( | 562 SkRect sk_plugin_rect = SkRect::MakeXYWH( |
| 534 SkIntToScalar(plugin_rect.origin().x()), | 563 SkIntToScalar(plugin_rect.origin().x()), |
| 535 SkIntToScalar(plugin_rect.origin().y()), | 564 SkIntToScalar(plugin_rect.origin().y()), |
| 536 SkIntToScalar(plugin_rect.width()), | 565 SkIntToScalar(plugin_rect.width()), |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 } | 632 } |
| 604 | 633 |
| 605 void PPB_Graphics2D_Impl::ViewFlushedPaint() { | 634 void PPB_Graphics2D_Impl::ViewFlushedPaint() { |
| 606 TRACE_EVENT0("pepper", "PPB_Graphics2D_Impl::ViewFlushedPaint"); | 635 TRACE_EVENT0("pepper", "PPB_Graphics2D_Impl::ViewFlushedPaint"); |
| 607 // Notify any "painted" callback. See |unpainted_flush_callback_| in the | 636 // Notify any "painted" callback. See |unpainted_flush_callback_| in the |
| 608 // header for more. | 637 // header for more. |
| 609 if (!painted_flush_callback_.is_null()) | 638 if (!painted_flush_callback_.is_null()) |
| 610 painted_flush_callback_.Execute(PP_OK); | 639 painted_flush_callback_.Execute(PP_OK); |
| 611 } | 640 } |
| 612 | 641 |
| 642 // static | |
| 643 bool PPB_Graphics2D_Impl::ScaleMetrics(float scale, gfx::Rect& rect, | |
| 644 int* dx, int* dy) { | |
| 645 if (scale != 1.0f && scale > 0.0f) { | |
| 646 gfx::Rect original_rect = rect; | |
| 647 ScaleRectBounds(rect, scale); | |
| 648 if (dx && dy) { | |
| 649 // Ensure that the rectangle and deltas can be scaled and inverse-scaled | |
| 650 // without loss of precision. This check is needed when scrolling to | |
| 651 // determine if we should fall back to InvalidateRect. | |
| 652 gfx::Rect unscaled_rect = rect; | |
| 653 int original_dx = *dx; | |
| 654 int original_dy = *dy; | |
| 655 *dx = static_cast<int>(original_dx * scale); | |
| 656 *dy = static_cast<int>(original_dy * scale); | |
| 657 ScaleRectBounds(unscaled_rect, 1.0f / scale); | |
| 658 if (unscaled_rect != original_rect || | |
| 659 static_cast<int>(*dx / scale) != original_dx || | |
| 660 static_cast<int>(*dy / scale) != original_dy) | |
|
Wez
2012/07/19 01:33:37
It feels like it'd be cleaner to keep the ScaleRec
Josh Horwich
2012/07/19 22:22:44
Done.
I put the ScaleDelta parts back inline abov
| |
| 661 return false; | |
| 662 } | |
| 663 } | |
| 664 | |
| 665 return true; | |
| 666 } | |
| 667 | |
| 613 void PPB_Graphics2D_Impl::ExecutePaintImageData(PPB_ImageData_Impl* image, | 668 void PPB_Graphics2D_Impl::ExecutePaintImageData(PPB_ImageData_Impl* image, |
| 614 int x, int y, | 669 int x, int y, |
| 615 const gfx::Rect& src_rect, | 670 const gfx::Rect& src_rect, |
| 616 gfx::Rect* invalidated_rect) { | 671 gfx::Rect* invalidated_rect) { |
| 617 // Ensure the source image is mapped to read from it. | 672 // Ensure the source image is mapped to read from it. |
| 618 ImageDataAutoMapper auto_mapper(image); | 673 ImageDataAutoMapper auto_mapper(image); |
| 619 if (!auto_mapper.is_valid()) | 674 if (!auto_mapper.is_valid()) |
| 620 return; | 675 return; |
| 621 | 676 |
| 622 // Portion within the source image to cut out. | 677 // Portion within the source image to cut out. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 700 } | 755 } |
| 701 | 756 |
| 702 bool PPB_Graphics2D_Impl::HasPendingFlush() const { | 757 bool PPB_Graphics2D_Impl::HasPendingFlush() const { |
| 703 return !unpainted_flush_callback_.is_null() || | 758 return !unpainted_flush_callback_.is_null() || |
| 704 !painted_flush_callback_.is_null() || | 759 !painted_flush_callback_.is_null() || |
| 705 offscreen_flush_pending_; | 760 offscreen_flush_pending_; |
| 706 } | 761 } |
| 707 | 762 |
| 708 } // namespace ppapi | 763 } // namespace ppapi |
| 709 } // namespace webkit | 764 } // namespace webkit |
| OLD | NEW |