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 | |
brettw
2012/07/23 19:09:52
Nit: need period.
| |
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 |