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

Side by Side Diff: content/renderer/render_widget.cc

Issue 7327030: Fixed bug that caused canvas updates to trigger two compositor paints. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 5 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 | « content/renderer/render_widget.h ('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) 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
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
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(&current_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(&current_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
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 }
OLDNEW
« no previous file with comments | « content/renderer/render_widget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698