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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 static_cast<int64>(rect->size.height) > | 65 static_cast<int64>(rect->size.height) > |
66 static_cast<int64>(image_height)) | 66 static_cast<int64>(image_height)) |
67 return false; | 67 return false; |
68 | 68 |
69 *dest = gfx::Rect(rect->point.x, rect->point.y, | 69 *dest = gfx::Rect(rect->point.x, rect->point.y, |
70 rect->size.width, rect->size.height); | 70 rect->size.width, rect->size.height); |
71 } | 71 } |
72 return true; | 72 return true; |
73 } | 73 } |
74 | 74 |
| 75 // Scale the rectangle, taking care to round coordinates outward so a |
| 76 // rectangle scaled down then scaled back up by the inverse scale would |
| 77 // fully contain the entire area affected by the original rectangle. |
| 78 gfx::Rect ScaleRectBounds(const gfx::Rect& rect, float scale) { |
| 79 int left = static_cast<int>(floorf(rect.x() * scale)); |
| 80 int top = static_cast<int>(floorf(rect.y() * scale)); |
| 81 int right = static_cast<int>(ceilf((rect.x() + rect.width()) * scale)); |
| 82 int bottom = static_cast<int>(ceilf((rect.y() + rect.height()) * scale)); |
| 83 return gfx::Rect(left, top, right - left, bottom - top); |
| 84 } |
| 85 |
75 // Converts BGRA <-> RGBA. | 86 // Converts BGRA <-> RGBA. |
76 void ConvertBetweenBGRAandRGBA(const uint32_t* input, | 87 void ConvertBetweenBGRAandRGBA(const uint32_t* input, |
77 int pixel_length, | 88 int pixel_length, |
78 uint32_t* output) { | 89 uint32_t* output) { |
79 for (int i = 0; i < pixel_length; i++) { | 90 for (int i = 0; i < pixel_length; i++) { |
80 const unsigned char* pixel_in = | 91 const unsigned char* pixel_in = |
81 reinterpret_cast<const unsigned char*>(&input[i]); | 92 reinterpret_cast<const unsigned char*>(&input[i]); |
82 unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); | 93 unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); |
83 pixel_out[0] = pixel_in[2]; | 94 pixel_out[0] = pixel_in[2]; |
84 pixel_out[1] = pixel_in[1]; | 95 pixel_out[1] = pixel_in[1]; |
(...skipping 258 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 gfx::Point scroll_delta(operation.scroll_dx, operation.scroll_dy); |
| 365 if (!ConvertToLogicalPixels(scale_, |
| 366 &op_rect, |
| 367 operation.type == QueuedOperation::SCROLL ? |
| 368 &scroll_delta : NULL)) { |
| 369 // Conversion requires falling back to InvalidateRect. |
| 370 operation.type = QueuedOperation::PAINT; |
| 371 } |
353 | 372 |
354 // Set |nothing_visible| to false if the change overlaps the visible area. | 373 // Set |nothing_visible| to false if the change overlaps the visible area. |
355 gfx::Rect visible_changed_rect = | 374 gfx::Rect visible_changed_rect = |
356 PP_ToGfxRect(bound_instance_->view_data().clip_rect). | 375 PP_ToGfxRect(bound_instance_->view_data().clip_rect). |
357 Intersect(op_rect); | 376 Intersect(op_rect); |
358 if (!visible_changed_rect.IsEmpty()) | 377 if (!visible_changed_rect.IsEmpty()) |
359 nothing_visible = false; | 378 nothing_visible = false; |
360 | 379 |
361 // Notify the plugin of the entire change (op_rect), even if it is | 380 // Notify the plugin of the entire change (op_rect), even if it is |
362 // partially or completely off-screen. | 381 // partially or completely off-screen. |
363 if (operation.type == QueuedOperation::SCROLL) { | 382 if (operation.type == QueuedOperation::SCROLL) { |
364 bound_instance_->ScrollRect(operation.scroll_dx, operation.scroll_dy, | 383 bound_instance_->ScrollRect(scroll_delta.x(), scroll_delta.y(), |
365 op_rect); | 384 op_rect); |
366 } else { | 385 } else { |
367 bound_instance_->InvalidateRect(op_rect); | 386 bound_instance_->InvalidateRect(op_rect); |
368 } | 387 } |
369 } | 388 } |
370 } | 389 } |
371 queued_operations_.clear(); | 390 queued_operations_.clear(); |
372 | 391 |
373 if (nothing_visible) { | 392 if (nothing_visible) { |
374 // There's nothing visible to invalidate so just schedule the callback to | 393 // There's nothing visible to invalidate so just schedule the callback to |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 | 536 |
518 CGRect bounds; | 537 CGRect bounds; |
519 bounds.origin.x = plugin_rect.origin().x(); | 538 bounds.origin.x = plugin_rect.origin().x(); |
520 bounds.origin.y = window_height - plugin_rect.origin().y() - | 539 bounds.origin.y = window_height - plugin_rect.origin().y() - |
521 plugin_rect.height(); | 540 plugin_rect.height(); |
522 bounds.size.width = plugin_rect.width(); | 541 bounds.size.width = plugin_rect.width(); |
523 bounds.size.height = plugin_rect.height(); | 542 bounds.size.height = plugin_rect.height(); |
524 | 543 |
525 CGContextClipToRect(canvas, bounds); | 544 CGContextClipToRect(canvas, bounds); |
526 | 545 |
| 546 // TODO(jhorwich) Figure out if this code is even active anymore, and if so |
| 547 // how to properly handle scaling. |
| 548 DCHECK_EQ(1.0f, scale_); |
| 549 |
527 // TODO(brettw) bug 56673: do a direct memcpy instead of going through CG | 550 // 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. | 551 // if the is_always_opaque_ flag is set. Must ensure bitmap is still clipped. |
529 | 552 |
530 CGContextDrawImage(canvas, bitmap_rect, image); | 553 CGContextDrawImage(canvas, bitmap_rect, image); |
531 CGContextRestoreGState(canvas); | 554 CGContextRestoreGState(canvas); |
532 #else | 555 #else |
533 SkRect sk_plugin_rect = SkRect::MakeXYWH( | 556 SkRect sk_plugin_rect = SkRect::MakeXYWH( |
534 SkIntToScalar(plugin_rect.origin().x()), | 557 SkIntToScalar(plugin_rect.origin().x()), |
535 SkIntToScalar(plugin_rect.origin().y()), | 558 SkIntToScalar(plugin_rect.origin().y()), |
536 SkIntToScalar(plugin_rect.width()), | 559 SkIntToScalar(plugin_rect.width()), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 } | 626 } |
604 | 627 |
605 void PPB_Graphics2D_Impl::ViewFlushedPaint() { | 628 void PPB_Graphics2D_Impl::ViewFlushedPaint() { |
606 TRACE_EVENT0("pepper", "PPB_Graphics2D_Impl::ViewFlushedPaint"); | 629 TRACE_EVENT0("pepper", "PPB_Graphics2D_Impl::ViewFlushedPaint"); |
607 // Notify any "painted" callback. See |unpainted_flush_callback_| in the | 630 // Notify any "painted" callback. See |unpainted_flush_callback_| in the |
608 // header for more. | 631 // header for more. |
609 if (!painted_flush_callback_.is_null()) | 632 if (!painted_flush_callback_.is_null()) |
610 painted_flush_callback_.Execute(PP_OK); | 633 painted_flush_callback_.Execute(PP_OK); |
611 } | 634 } |
612 | 635 |
| 636 // static |
| 637 bool PPB_Graphics2D_Impl::ConvertToLogicalPixels(float scale, |
| 638 gfx::Rect* op_rect, |
| 639 gfx::Point* delta) { |
| 640 if (scale == 1.0f || scale <= 0.0f) |
| 641 return true; |
| 642 |
| 643 gfx::Rect original_rect = *op_rect; |
| 644 *op_rect = ScaleRectBounds(*op_rect, scale); |
| 645 if (delta) { |
| 646 gfx::Point original_delta = *delta; |
| 647 float inverse_scale = 1.0f / scale; |
| 648 *delta = delta->Scale(scale); |
| 649 if (original_rect != ScaleRectBounds(*op_rect, inverse_scale) || |
| 650 original_delta != delta->Scale(inverse_scale)) { |
| 651 return false; |
| 652 } |
| 653 } |
| 654 |
| 655 return true; |
| 656 } |
| 657 |
613 void PPB_Graphics2D_Impl::ExecutePaintImageData(PPB_ImageData_Impl* image, | 658 void PPB_Graphics2D_Impl::ExecutePaintImageData(PPB_ImageData_Impl* image, |
614 int x, int y, | 659 int x, int y, |
615 const gfx::Rect& src_rect, | 660 const gfx::Rect& src_rect, |
616 gfx::Rect* invalidated_rect) { | 661 gfx::Rect* invalidated_rect) { |
617 // Ensure the source image is mapped to read from it. | 662 // Ensure the source image is mapped to read from it. |
618 ImageDataAutoMapper auto_mapper(image); | 663 ImageDataAutoMapper auto_mapper(image); |
619 if (!auto_mapper.is_valid()) | 664 if (!auto_mapper.is_valid()) |
620 return; | 665 return; |
621 | 666 |
622 // Portion within the source image to cut out. | 667 // Portion within the source image to cut out. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 } | 745 } |
701 | 746 |
702 bool PPB_Graphics2D_Impl::HasPendingFlush() const { | 747 bool PPB_Graphics2D_Impl::HasPendingFlush() const { |
703 return !unpainted_flush_callback_.is_null() || | 748 return !unpainted_flush_callback_.is_null() || |
704 !painted_flush_callback_.is_null() || | 749 !painted_flush_callback_.is_null() || |
705 offscreen_flush_pending_; | 750 offscreen_flush_pending_; |
706 } | 751 } |
707 | 752 |
708 } // namespace ppapi | 753 } // namespace ppapi |
709 } // namespace webkit | 754 } // namespace webkit |
OLD | NEW |