OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/renderer/render_widget.h" | 5 #include "content/renderer/render_widget.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
666 DoDeferredUpdateAndSendInputAck(); | 666 DoDeferredUpdateAndSendInputAck(); |
667 } | 667 } |
668 | 668 |
669 void RenderWidget::DoDeferredUpdateAndSendInputAck() { | 669 void RenderWidget::DoDeferredUpdateAndSendInputAck() { |
670 DoDeferredUpdate(); | 670 DoDeferredUpdate(); |
671 | 671 |
672 if (pending_input_event_ack_.get()) | 672 if (pending_input_event_ack_.get()) |
673 Send(pending_input_event_ack_.release()); | 673 Send(pending_input_event_ack_.release()); |
674 } | 674 } |
675 | 675 |
676 void RenderWidget::popPendingUpdate() { | |
677 // Save off the pending update now since painting may cause more | |
678 // invalidation. Some WebCore rendering objects only layout when painted. | |
679 paint_aggregator_.PopPendingUpdate(&paint_aggregator_update_); | |
680 } | |
681 | |
676 void RenderWidget::DoDeferredUpdate() { | 682 void RenderWidget::DoDeferredUpdate() { |
677 TRACE_EVENT0("renderer", "RenderWidget::DoDeferredUpdate"); | 683 TRACE_EVENT0("renderer", "RenderWidget::DoDeferredUpdate"); |
678 | 684 |
679 if (!webwidget_) | 685 if (!webwidget_) |
680 return; | 686 return; |
681 if (update_reply_pending()) { | 687 if (update_reply_pending()) { |
682 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); | 688 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); |
683 return; | 689 return; |
684 } | 690 } |
685 if (is_accelerated_compositing_active_ && | 691 if (is_accelerated_compositing_active_ && |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
727 base::TimeDelta::FromMilliseconds(60), | 733 base::TimeDelta::FromMilliseconds(60), |
728 30); | 734 30); |
729 | 735 |
730 // Calculate filtered time per frame: | 736 // Calculate filtered time per frame: |
731 float frame_time_elapsed = static_cast<float>(delay.InSecondsF()); | 737 float frame_time_elapsed = static_cast<float>(delay.InSecondsF()); |
732 filtered_time_per_frame_ = | 738 filtered_time_per_frame_ = |
733 0.9f * filtered_time_per_frame_ + 0.1f * frame_time_elapsed; | 739 0.9f * filtered_time_per_frame_ + 0.1f * frame_time_elapsed; |
734 } | 740 } |
735 last_do_deferred_update_time_ = frame_begin_ticks; | 741 last_do_deferred_update_time_ = frame_begin_ticks; |
736 | 742 |
737 // OK, save the pending update to a local since painting may cause more | 743 gfx::Rect scroll_damage; |
738 // invalidation. Some WebCore rendering objects only layout when painted. | 744 gfx::Rect bounds; |
739 PaintAggregator::PendingUpdate update; | |
740 paint_aggregator_.PopPendingUpdate(&update); | |
741 | |
742 gfx::Rect scroll_damage = update.GetScrollDamage(); | |
743 gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage); | |
744 | 745 |
745 // Compositing the page may disable accelerated compositing. | 746 // Compositing the page may disable accelerated compositing. |
746 bool accelerated_compositing_was_active = is_accelerated_compositing_active_; | 747 bool accelerated_compositing_was_active = is_accelerated_compositing_active_; |
747 | 748 |
748 // A plugin may be able to do an optimized paint. First check this, in which | 749 // A plugin may be able to do an optimized paint. First check this, in which |
749 // case we can skip all of the bitmap generation and regular paint code. | 750 // case we can skip all of the bitmap generation and regular paint code. |
750 // This optimization allows PPAPI plugins that declare themselves on top of | 751 // This optimization allows PPAPI plugins that declare themselves on top of |
751 // the page (like a traditional windowed plugin) to be able to animate (think | 752 // the page (like a traditional windowed plugin) to be able to animate (think |
752 // movie playing) without repeatedly re-painting the page underneath, or | 753 // movie playing) without repeatedly re-painting the page underneath, or |
753 // copying the plugin backing store (since we can send the plugin's backing | 754 // copying the plugin backing store (since we can send the plugin's backing |
754 // store directly to the browser). | 755 // store directly to the browser). |
755 // | 756 // |
756 // This optimization only works when the entire invalid region is contained | 757 // This optimization only works when the entire invalid region is contained |
757 // within the plugin. There is a related optimization in PaintRect for the | 758 // within the plugin. There is a related optimization in PaintRect for the |
758 // case where there may be multiple invalid regions. | 759 // case where there may be multiple invalid regions. |
759 TransportDIB::Id dib_id = TransportDIB::Id(); | 760 TransportDIB::Id dib_id = TransportDIB::Id(); |
760 TransportDIB* dib = NULL; | 761 TransportDIB* dib = NULL; |
761 std::vector<gfx::Rect> copy_rects; | 762 std::vector<gfx::Rect> copy_rects; |
762 gfx::Rect optimized_copy_rect, optimized_copy_location; | 763 gfx::Rect optimized_copy_rect, optimized_copy_location; |
763 if (update.scroll_rect.IsEmpty() && | 764 if (!is_accelerated_compositing_active_) { |
764 !is_accelerated_compositing_active_ && | 765 popPendingUpdate(); |
765 GetBitmapForOptimizedPluginPaint(bounds, &dib, &optimized_copy_location, | 766 scroll_damage = paint_aggregator_update_.GetScrollDamage(); |
766 &optimized_copy_rect)) { | 767 bounds = paint_aggregator_update_.GetPaintBounds().Union(scroll_damage); |
767 // Only update the part of the plugin that actually changed. | 768 |
768 optimized_copy_rect = optimized_copy_rect.Intersect(bounds); | 769 if (paint_aggregator_update_.scroll_rect.IsEmpty() && |
769 bounds = optimized_copy_location; | 770 GetBitmapForOptimizedPluginPaint(bounds, &dib, &optimized_copy_location, |
770 copy_rects.push_back(optimized_copy_rect); | 771 &optimized_copy_rect)) { |
771 dib_id = dib->id(); | 772 // Only update the part of the plugin that actually changed. |
772 } else if (!is_accelerated_compositing_active_) { | 773 optimized_copy_rect = optimized_copy_rect.Intersect(bounds); |
773 // Compute a buffer for painting and cache it. | 774 bounds = optimized_copy_location; |
774 scoped_ptr<skia::PlatformCanvas> canvas( | 775 copy_rects.push_back(optimized_copy_rect); |
775 RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_, | 776 dib_id = dib->id(); |
776 bounds)); | 777 } else { |
777 if (!canvas.get()) { | 778 // Compute a buffer for painting and cache it. |
778 NOTREACHED(); | 779 scoped_ptr<skia::PlatformCanvas> canvas( |
779 return; | 780 RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_, |
781 bounds)); | |
782 if (!canvas.get()) { | |
783 NOTREACHED(); | |
784 return; | |
785 } | |
786 | |
787 // We may get back a smaller canvas than we asked for. | |
788 // TODO(darin): This seems like it could cause painting problems! | |
789 DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); | |
790 DCHECK_EQ(bounds.height(), canvas->getDevice()->height()); | |
791 bounds.set_width(canvas->getDevice()->width()); | |
792 bounds.set_height(canvas->getDevice()->height()); | |
793 | |
794 HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", | |
795 paint_aggregator_update_.paint_rects.size()); | |
796 | |
797 // The scroll damage is just another rectangle to paint and copy. | |
798 copy_rects.swap(paint_aggregator_update_.paint_rects); | |
799 if (!scroll_damage.IsEmpty()) | |
800 copy_rects.push_back(scroll_damage); | |
801 | |
802 for (size_t i = 0; i < copy_rects.size(); ++i) | |
803 PaintRect(copy_rects[i], bounds.origin(), canvas.get()); | |
804 | |
805 dib_id = current_paint_buf_->id(); | |
780 } | 806 } |
781 | |
782 // We may get back a smaller canvas than we asked for. | |
783 // TODO(darin): This seems like it could cause painting problems! | |
784 DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); | |
785 DCHECK_EQ(bounds.height(), canvas->getDevice()->height()); | |
786 bounds.set_width(canvas->getDevice()->width()); | |
787 bounds.set_height(canvas->getDevice()->height()); | |
788 | |
789 HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size()); | |
jbates
2011/07/09 02:06:22
None of this code block has changed - it's just mo
| |
790 | |
791 // The scroll damage is just another rectangle to paint and copy. | |
792 copy_rects.swap(update.paint_rects); | |
793 if (!scroll_damage.IsEmpty()) | |
794 copy_rects.push_back(scroll_damage); | |
795 | |
796 for (size_t i = 0; i < copy_rects.size(); ++i) | |
797 PaintRect(copy_rects[i], bounds.origin(), canvas.get()); | |
798 | |
799 dib_id = current_paint_buf_->id(); | |
800 } else { // Accelerated compositing path | 807 } else { // Accelerated compositing path |
801 // Begin painting. | 808 // Begin painting. |
802 webwidget_->composite(false); | 809 webwidget_->composite(false); |
803 if (using_asynchronous_swapbuffers_) | 810 if (using_asynchronous_swapbuffers_) |
804 num_swapbuffers_complete_pending_++; | 811 num_swapbuffers_complete_pending_++; |
812 | |
813 // paint_aggregator_update_ was updated during composite. | |
814 scroll_damage = paint_aggregator_update_.GetScrollDamage(); | |
815 bounds = paint_aggregator_update_.GetPaintBounds().Union(scroll_damage); | |
805 } | 816 } |
806 | 817 |
807 // sending an ack to browser process that the paint is complete... | 818 // sending an ack to browser process that the paint is complete... |
808 ViewHostMsg_UpdateRect_Params params; | 819 ViewHostMsg_UpdateRect_Params params; |
809 params.bitmap = dib_id; | 820 params.bitmap = dib_id; |
810 params.bitmap_rect = bounds; | 821 params.bitmap_rect = bounds; |
811 params.dx = update.scroll_delta.x(); | 822 params.dx = paint_aggregator_update_.scroll_delta.x(); |
812 params.dy = update.scroll_delta.y(); | 823 params.dy = paint_aggregator_update_.scroll_delta.y(); |
813 if (accelerated_compositing_was_active) { | 824 if (accelerated_compositing_was_active) { |
814 // If painting is done via the gpu process then we clear out all damage | 825 // If painting is done via the gpu process then we clear out all damage |
815 // rects to save the browser process from doing unecessary work. | 826 // rects to save the browser process from doing unecessary work. |
816 params.scroll_rect = gfx::Rect(); | 827 params.scroll_rect = gfx::Rect(); |
817 params.copy_rects.clear(); | 828 params.copy_rects.clear(); |
818 } else { | 829 } else { |
819 params.scroll_rect = update.scroll_rect; | 830 params.scroll_rect = paint_aggregator_update_.scroll_rect; |
820 params.copy_rects.swap(copy_rects); // TODO(darin): clip to bounds? | 831 params.copy_rects.swap(copy_rects); // TODO(darin): clip to bounds? |
821 } | 832 } |
822 params.view_size = size_; | 833 params.view_size = size_; |
823 params.resizer_rect = resizer_rect_; | 834 params.resizer_rect = resizer_rect_; |
824 params.plugin_window_moves.swap(plugin_window_moves_); | 835 params.plugin_window_moves.swap(plugin_window_moves_); |
825 params.flags = next_paint_flags_; | 836 params.flags = next_paint_flags_; |
826 params.scroll_offset = GetScrollOffset(); | 837 params.scroll_offset = GetScrollOffset(); |
827 | 838 |
828 update_reply_pending_ = true; | 839 update_reply_pending_ = true; |
829 Send(new ViewHostMsg_UpdateRect(routing_id_, params)); | 840 Send(new ViewHostMsg_UpdateRect(routing_id_, params)); |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1374 | 1385 |
1375 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { | 1386 void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) { |
1376 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); | 1387 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin(); |
1377 i != plugin_window_moves_.end(); ++i) { | 1388 i != plugin_window_moves_.end(); ++i) { |
1378 if (i->window == window) { | 1389 if (i->window == window) { |
1379 plugin_window_moves_.erase(i); | 1390 plugin_window_moves_.erase(i); |
1380 break; | 1391 break; |
1381 } | 1392 } |
1382 } | 1393 } |
1383 } | 1394 } |
OLD | NEW |