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

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

Issue 8498036: Delay UpdateRect until the SwapBuffers callback when accelerated compositing is on. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: allow multiple update messages in flight Created 9 years 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/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/stl_util.h"
14 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
15 #include "build/build_config.h" 16 #include "build/build_config.h"
16 #include "content/common/swapped_out_messages.h" 17 #include "content/common/swapped_out_messages.h"
17 #include "content/common/view_messages.h" 18 #include "content/common/view_messages.h"
18 #include "content/public/common/content_switches.h" 19 #include "content/public/common/content_switches.h"
19 #include "content/renderer/gpu/compositor_thread.h" 20 #include "content/renderer/gpu/compositor_thread.h"
20 #include "content/renderer/render_process.h" 21 #include "content/renderer/render_process.h"
21 #include "content/renderer/render_thread_impl.h" 22 #include "content/renderer/render_thread_impl.h"
22 #include "content/renderer/renderer_webkitplatformsupport_impl.h" 23 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
23 #include "ipc/ipc_sync_message.h" 24 #include "ipc/ipc_sync_message.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 animation_task_posted_(false), 97 animation_task_posted_(false),
97 invalidation_task_posted_(false) { 98 invalidation_task_posted_(false) {
98 RenderProcess::current()->AddRefProcess(); 99 RenderProcess::current()->AddRefProcess();
99 DCHECK(RenderThread::Get()); 100 DCHECK(RenderThread::Get());
100 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( 101 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch(
101 switches::kDisableGpuVsync); 102 switches::kDisableGpuVsync);
102 } 103 }
103 104
104 RenderWidget::~RenderWidget() { 105 RenderWidget::~RenderWidget() {
105 DCHECK(!webwidget_) << "Leaking our WebWidget!"; 106 DCHECK(!webwidget_) << "Leaking our WebWidget!";
107 STLDeleteElements(&updates_pending_swap_);
106 if (current_paint_buf_) { 108 if (current_paint_buf_) {
107 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); 109 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
108 current_paint_buf_ = NULL; 110 current_paint_buf_ = NULL;
109 } 111 }
110 // If we are swapped out, we have released already. 112 // If we are swapped out, we have released already.
111 if (!is_swapped_out_) 113 if (!is_swapped_out_)
112 RenderProcess::current()->ReleaseProcess(); 114 RenderProcess::current()->ReleaseProcess();
113 } 115 }
114 116
115 // static 117 // static
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 RenderProcess::current()->ReleaseProcess(); 350 RenderProcess::current()->ReleaseProcess();
349 } 351 }
350 352
351 void RenderWidget::OnRequestMoveAck() { 353 void RenderWidget::OnRequestMoveAck() {
352 DCHECK(pending_window_rect_count_); 354 DCHECK(pending_window_rect_count_);
353 pending_window_rect_count_--; 355 pending_window_rect_count_--;
354 } 356 }
355 357
356 void RenderWidget::OnUpdateRectAck() { 358 void RenderWidget::OnUpdateRectAck() {
357 TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck"); 359 TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck");
358 DCHECK(update_reply_pending()); 360 DCHECK(update_reply_pending_);
359 update_reply_pending_ = false; 361 update_reply_pending_ = false;
360 362
361 // If we sent an UpdateRect message with a zero-sized bitmap, then we should 363 // If we sent an UpdateRect message with a zero-sized bitmap, then we should
362 // have no current paint buffer. 364 // have no current paint buffer.
363 if (current_paint_buf_) { 365 if (current_paint_buf_) {
364 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); 366 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
365 current_paint_buf_ = NULL; 367 current_paint_buf_ = NULL;
366 } 368 }
367 369
368 // If swapbuffers is still pending, then defer the update until the 370 // If swapbuffers is still pending, then defer the update until the
(...skipping 12 matching lines...) Expand all
381 } 383 }
382 384
383 bool RenderWidget::SupportsAsynchronousSwapBuffers() 385 bool RenderWidget::SupportsAsynchronousSwapBuffers()
384 { 386 {
385 return false; 387 return false;
386 } 388 }
387 389
388 void RenderWidget::OnSwapBuffersAborted() 390 void RenderWidget::OnSwapBuffersAborted()
389 { 391 {
390 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); 392 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted");
393 while (!updates_pending_swap_.empty()) {
394 ViewHostMsg_UpdateRect* msg = updates_pending_swap_.front();
395 updates_pending_swap_.pop_front();
396 // msg can be NULL if the swap doesn't correspond to an DoDeferredUpdate
397 // compositing pass, hence doesn't require an UpdateRect message.
398 if (msg)
399 Send(msg);
400 }
391 num_swapbuffers_complete_pending_ = 0; 401 num_swapbuffers_complete_pending_ = 0;
392 using_asynchronous_swapbuffers_ = false; 402 using_asynchronous_swapbuffers_ = false;
393 // Schedule another frame so the compositor learns about it. 403 // Schedule another frame so the compositor learns about it.
394 scheduleComposite(); 404 scheduleComposite();
395 } 405 }
396 406
397 void RenderWidget::OnSwapBuffersPosted() { 407 void RenderWidget::OnSwapBuffersPosted() {
398 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); 408 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted");
399 if (using_asynchronous_swapbuffers_) 409
410 if (using_asynchronous_swapbuffers_) {
411 ViewHostMsg_UpdateRect* msg = NULL;
412 // pending_update_params_ can be NULL if the swap doesn't correspond to an
413 // DoDeferredUpdate compositing pass, hence doesn't require an UpdateRect
414 // message.
415 if (pending_update_params_.get()) {
416 msg = new ViewHostMsg_UpdateRect(routing_id_, *pending_update_params_);
417 pending_update_params_.reset();
418 }
419 updates_pending_swap_.push_back(msg);
400 num_swapbuffers_complete_pending_++; 420 num_swapbuffers_complete_pending_++;
421 }
401 } 422 }
402 423
403 void RenderWidget::OnSwapBuffersComplete() { 424 void RenderWidget::OnSwapBuffersComplete() {
404 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete"); 425 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete");
405 // When compositing deactivates, we reset the swapbuffers pending count. The 426 // When compositing deactivates, we reset the swapbuffers pending count. The
406 // swapbuffers acks may still arrive, however. 427 // swapbuffers acks may still arrive, however.
407 if (num_swapbuffers_complete_pending_ == 0) { 428 if (num_swapbuffers_complete_pending_ == 0) {
408 TRACE_EVENT0("renderer", "EarlyOut_ZeroSwapbuffersPending"); 429 TRACE_EVENT0("renderer", "EarlyOut_ZeroSwapbuffersPending");
409 return; 430 return;
410 } 431 }
432 DCHECK(!updates_pending_swap_.empty());
433 ViewHostMsg_UpdateRect* msg = updates_pending_swap_.front();
434 updates_pending_swap_.pop_front();
435 // msg can be NULL if the swap doesn't correspond to an DoDeferredUpdate
436 // compositing pass, hence doesn't require an UpdateRect message.
437 if (msg)
438 Send(msg);
411 num_swapbuffers_complete_pending_--; 439 num_swapbuffers_complete_pending_--;
412 440
413 // If update reply is still pending, then defer the update until that reply 441 // If update reply is still pending, then defer the update until that reply
414 // occurs. 442 // occurs.
415 if (update_reply_pending_){ 443 if (update_reply_pending_){
416 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); 444 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending");
417 return; 445 return;
418 } 446 }
419 447
420 // If we are not accelerated rendering, then this is a stale swapbuffers from 448 // If we are not accelerated rendering, then this is a stale swapbuffers from
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 715
688 if (pending_input_event_ack_.get()) 716 if (pending_input_event_ack_.get())
689 Send(pending_input_event_ack_.release()); 717 Send(pending_input_event_ack_.release());
690 } 718 }
691 719
692 void RenderWidget::DoDeferredUpdate() { 720 void RenderWidget::DoDeferredUpdate() {
693 TRACE_EVENT0("renderer", "RenderWidget::DoDeferredUpdate"); 721 TRACE_EVENT0("renderer", "RenderWidget::DoDeferredUpdate");
694 722
695 if (!webwidget_) 723 if (!webwidget_)
696 return; 724 return;
697 if (update_reply_pending()) { 725 if (update_reply_pending_) {
698 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); 726 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending");
699 return; 727 return;
700 } 728 }
701 if (is_accelerated_compositing_active_ && 729 if (is_accelerated_compositing_active_ &&
702 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) { 730 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) {
703 TRACE_EVENT0("renderer", "EarlyOut_MaxSwapBuffersPending"); 731 TRACE_EVENT0("renderer", "EarlyOut_MaxSwapBuffersPending");
704 return; 732 return;
705 } 733 }
706 734
707 // Suppress updating when we are hidden. 735 // Suppress updating when we are hidden.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 last_do_deferred_update_time_ = frame_begin_ticks; 779 last_do_deferred_update_time_ = frame_begin_ticks;
752 780
753 // OK, save the pending update to a local since painting may cause more 781 // OK, save the pending update to a local since painting may cause more
754 // invalidation. Some WebCore rendering objects only layout when painted. 782 // invalidation. Some WebCore rendering objects only layout when painted.
755 PaintAggregator::PendingUpdate update; 783 PaintAggregator::PendingUpdate update;
756 paint_aggregator_.PopPendingUpdate(&update); 784 paint_aggregator_.PopPendingUpdate(&update);
757 785
758 gfx::Rect scroll_damage = update.GetScrollDamage(); 786 gfx::Rect scroll_damage = update.GetScrollDamage();
759 gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage); 787 gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage);
760 788
761 // Compositing the page may disable accelerated compositing.
762 bool accelerated_compositing_was_active = is_accelerated_compositing_active_;
763
764 // A plugin may be able to do an optimized paint. First check this, in which 789 // A plugin may be able to do an optimized paint. First check this, in which
765 // case we can skip all of the bitmap generation and regular paint code. 790 // case we can skip all of the bitmap generation and regular paint code.
766 // This optimization allows PPAPI plugins that declare themselves on top of 791 // This optimization allows PPAPI plugins that declare themselves on top of
767 // the page (like a traditional windowed plugin) to be able to animate (think 792 // the page (like a traditional windowed plugin) to be able to animate (think
768 // movie playing) without repeatedly re-painting the page underneath, or 793 // movie playing) without repeatedly re-painting the page underneath, or
769 // copying the plugin backing store (since we can send the plugin's backing 794 // copying the plugin backing store (since we can send the plugin's backing
770 // store directly to the browser). 795 // store directly to the browser).
771 // 796 //
772 // This optimization only works when the entire invalid region is contained 797 // This optimization only works when the entire invalid region is contained
773 // within the plugin. There is a related optimization in PaintRect for the 798 // within the plugin. There is a related optimization in PaintRect for the
774 // case where there may be multiple invalid regions. 799 // case where there may be multiple invalid regions.
775 TransportDIB::Id dib_id = TransportDIB::Id();
776 TransportDIB* dib = NULL; 800 TransportDIB* dib = NULL;
777 std::vector<gfx::Rect> copy_rects;
778 gfx::Rect optimized_copy_rect, optimized_copy_location; 801 gfx::Rect optimized_copy_rect, optimized_copy_location;
802 DCHECK(!pending_update_params_.get());
803 pending_update_params_.reset(new ViewHostMsg_UpdateRect_Params);
804 pending_update_params_->dx = update.scroll_delta.x();
805 pending_update_params_->dy = update.scroll_delta.y();
806 pending_update_params_->scroll_rect = update.scroll_rect;
807 pending_update_params_->view_size = size_;
808 pending_update_params_->resizer_rect = resizer_rect_;
809 pending_update_params_->plugin_window_moves.swap(plugin_window_moves_);
810 pending_update_params_->flags = next_paint_flags_;
811 pending_update_params_->scroll_offset = GetScrollOffset();
812 pending_update_params_->needs_ack = true;
813 next_paint_flags_ = 0;
814
779 if (update.scroll_rect.IsEmpty() && 815 if (update.scroll_rect.IsEmpty() &&
780 !is_accelerated_compositing_active_ && 816 !is_accelerated_compositing_active_ &&
781 GetBitmapForOptimizedPluginPaint(bounds, &dib, &optimized_copy_location, 817 GetBitmapForOptimizedPluginPaint(bounds, &dib, &optimized_copy_location,
782 &optimized_copy_rect)) { 818 &optimized_copy_rect)) {
783 // Only update the part of the plugin that actually changed. 819 // Only update the part of the plugin that actually changed.
784 optimized_copy_rect = optimized_copy_rect.Intersect(bounds); 820 optimized_copy_rect = optimized_copy_rect.Intersect(bounds);
785 bounds = optimized_copy_location; 821 pending_update_params_->bitmap = dib->id();
786 copy_rects.push_back(optimized_copy_rect); 822 pending_update_params_->bitmap_rect = optimized_copy_location;
787 dib_id = dib->id(); 823 pending_update_params_->copy_rects.push_back(optimized_copy_rect);
788 } else if (!is_accelerated_compositing_active_) { 824 } else if (!is_accelerated_compositing_active_) {
789 // Compute a buffer for painting and cache it. 825 // Compute a buffer for painting and cache it.
790 scoped_ptr<skia::PlatformCanvas> canvas( 826 scoped_ptr<skia::PlatformCanvas> canvas(
791 RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_, 827 RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_,
792 bounds)); 828 bounds));
793 if (!canvas.get()) { 829 if (!canvas.get()) {
794 NOTREACHED(); 830 NOTREACHED();
795 return; 831 return;
796 } 832 }
797 833
798 // We may get back a smaller canvas than we asked for. 834 // We may get back a smaller canvas than we asked for.
799 // TODO(darin): This seems like it could cause painting problems! 835 // TODO(darin): This seems like it could cause painting problems!
800 DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); 836 DCHECK_EQ(bounds.width(), canvas->getDevice()->width());
801 DCHECK_EQ(bounds.height(), canvas->getDevice()->height()); 837 DCHECK_EQ(bounds.height(), canvas->getDevice()->height());
802 bounds.set_width(canvas->getDevice()->width()); 838 bounds.set_width(canvas->getDevice()->width());
803 bounds.set_height(canvas->getDevice()->height()); 839 bounds.set_height(canvas->getDevice()->height());
804 840
805 HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size()); 841 HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size());
806 842
843 pending_update_params_->bitmap = current_paint_buf_->id();
844 pending_update_params_->bitmap_rect = bounds;
845
846 std::vector<gfx::Rect>& copy_rects = pending_update_params_->copy_rects;
807 // The scroll damage is just another rectangle to paint and copy. 847 // The scroll damage is just another rectangle to paint and copy.
808 copy_rects.swap(update.paint_rects); 848 copy_rects.swap(update.paint_rects);
809 if (!scroll_damage.IsEmpty()) 849 if (!scroll_damage.IsEmpty())
810 copy_rects.push_back(scroll_damage); 850 copy_rects.push_back(scroll_damage);
811 851
812 for (size_t i = 0; i < copy_rects.size(); ++i) 852 for (size_t i = 0; i < copy_rects.size(); ++i)
813 PaintRect(copy_rects[i], bounds.origin(), canvas.get()); 853 PaintRect(copy_rects[i], bounds.origin(), canvas.get());
814
815 dib_id = current_paint_buf_->id();
816 } else { // Accelerated compositing path 854 } else { // Accelerated compositing path
817 // Begin painting. 855 // Begin painting.
856 // If painting is done via the gpu process then we don't set any damage
857 // rects to save the browser process from doing unecessary work.
858 pending_update_params_->bitmap_rect = bounds;
859 pending_update_params_->scroll_rect = gfx::Rect();
860 // We don't need an ack, because we're not sharing a DIB with the browser.
861 // If it needs to (e.g. composited UI), the GPU process does its own ACK
862 // with the browser for the GPU surface.
863 pending_update_params_->needs_ack = false;
818 webwidget_->composite(false); 864 webwidget_->composite(false);
819 } 865 }
820 866
821 // sending an ack to browser process that the paint is complete... 867 // If composite() called SwapBuffers, pending_update_params_ will be reset (in
822 ViewHostMsg_UpdateRect_Params params; 868 // OnSwapBuffersPosted), meaning a message has been added to the
823 params.bitmap = dib_id; 869 // updates_pending_swap_ queue, that will be sent later. Otherwise, we send
824 params.bitmap_rect = bounds; 870 // the message now.
825 params.dx = update.scroll_delta.x(); 871 if (pending_update_params_.get()) {
826 params.dy = update.scroll_delta.y(); 872 // sending an ack to browser process that the paint is complete...
827 if (accelerated_compositing_was_active) { 873 update_reply_pending_ = pending_update_params_->needs_ack;
828 // If painting is done via the gpu process then we clear out all damage 874 Send(new ViewHostMsg_UpdateRect(routing_id_, *pending_update_params_));
829 // rects to save the browser process from doing unecessary work. 875 pending_update_params_.reset();
830 params.scroll_rect = gfx::Rect();
831 params.copy_rects.clear();
832 } else {
833 params.scroll_rect = update.scroll_rect;
834 params.copy_rects.swap(copy_rects); // TODO(darin): clip to bounds?
835 } 876 }
836 params.view_size = size_;
837 params.resizer_rect = resizer_rect_;
838 params.plugin_window_moves.swap(plugin_window_moves_);
839 params.flags = next_paint_flags_;
840 params.scroll_offset = GetScrollOffset();
841
842 update_reply_pending_ = true;
843 Send(new ViewHostMsg_UpdateRect(routing_id_, params));
844 next_paint_flags_ = 0;
845 877
846 UpdateTextInputState(); 878 UpdateTextInputState();
847 UpdateSelectionBounds(); 879 UpdateSelectionBounds();
848 880
849 // Let derived classes know we've painted. 881 // Let derived classes know we've painted.
850 DidInitiatePaint(); 882 DidInitiatePaint();
851 } 883 }
852 884
853 /////////////////////////////////////////////////////////////////////////////// 885 ///////////////////////////////////////////////////////////////////////////////
854 // WebWidgetClient 886 // WebWidgetClient
855 887
856 void RenderWidget::didInvalidateRect(const WebRect& rect) { 888 void RenderWidget::didInvalidateRect(const WebRect& rect) {
857 // The invalidated rect might be outside the bounds of the view. 889 // The invalidated rect might be outside the bounds of the view.
858 gfx::Rect view_rect(size_); 890 gfx::Rect view_rect(size_);
859 gfx::Rect damaged_rect = view_rect.Intersect(rect); 891 gfx::Rect damaged_rect = view_rect.Intersect(rect);
860 if (damaged_rect.IsEmpty()) 892 if (damaged_rect.IsEmpty())
861 return; 893 return;
862 894
863 paint_aggregator_.InvalidateRect(damaged_rect); 895 paint_aggregator_.InvalidateRect(damaged_rect);
864 896
865 // We may not need to schedule another call to DoDeferredUpdate. 897 // We may not need to schedule another call to DoDeferredUpdate.
866 if (invalidation_task_posted_) 898 if (invalidation_task_posted_)
867 return; 899 return;
868 if (!paint_aggregator_.HasPendingUpdate()) 900 if (!paint_aggregator_.HasPendingUpdate())
869 return; 901 return;
870 if (update_reply_pending() || 902 if (update_reply_pending_ ||
871 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) 903 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending)
872 return; 904 return;
873 905
874 // When GPU rendering, combine pending animations and invalidations into 906 // When GPU rendering, combine pending animations and invalidations into
875 // a single update. 907 // a single update.
876 if (is_accelerated_compositing_active_ && animation_task_posted_) 908 if (is_accelerated_compositing_active_ && animation_task_posted_)
877 return; 909 return;
878 910
879 // Perform updating asynchronously. This serves two purposes: 911 // Perform updating asynchronously. This serves two purposes:
880 // 1) Ensures that we call WebView::Paint without a bunch of other junk 912 // 1) Ensures that we call WebView::Paint without a bunch of other junk
(...skipping 17 matching lines...) Expand all
898 if (damaged_rect.IsEmpty()) 930 if (damaged_rect.IsEmpty())
899 return; 931 return;
900 932
901 paint_aggregator_.ScrollRect(dx, dy, damaged_rect); 933 paint_aggregator_.ScrollRect(dx, dy, damaged_rect);
902 934
903 // We may not need to schedule another call to DoDeferredUpdate. 935 // We may not need to schedule another call to DoDeferredUpdate.
904 if (invalidation_task_posted_) 936 if (invalidation_task_posted_)
905 return; 937 return;
906 if (!paint_aggregator_.HasPendingUpdate()) 938 if (!paint_aggregator_.HasPendingUpdate())
907 return; 939 return;
908 if (update_reply_pending() || 940 if (update_reply_pending_ ||
909 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) 941 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending)
910 return; 942 return;
911 943
912 // When GPU rendering, combine pending animations and invalidations into 944 // When GPU rendering, combine pending animations and invalidations into
913 // a single update. 945 // a single update.
914 if (is_accelerated_compositing_active_ && animation_task_posted_) 946 if (is_accelerated_compositing_active_ && animation_task_posted_)
915 return; 947 return;
916 948
917 // Perform updating asynchronously. This serves two purposes: 949 // Perform updating asynchronously. This serves two purposes:
918 // 1) Ensures that we call WebView::Paint without a bunch of other junk 950 // 1) Ensures that we call WebView::Paint without a bunch of other junk
(...skipping 10 matching lines...) Expand all
929 } 961 }
930 962
931 void RenderWidget::didActivateCompositor(int compositor_identifier) { 963 void RenderWidget::didActivateCompositor(int compositor_identifier) {
932 TRACE_EVENT0("gpu", "RenderWidget::didActivateCompositor"); 964 TRACE_EVENT0("gpu", "RenderWidget::didActivateCompositor");
933 965
934 CompositorThread* compositor_thread = 966 CompositorThread* compositor_thread =
935 RenderThreadImpl::current()->compositor_thread(); 967 RenderThreadImpl::current()->compositor_thread();
936 if (compositor_thread) 968 if (compositor_thread)
937 compositor_thread->AddCompositor(routing_id_, compositor_identifier); 969 compositor_thread->AddCompositor(routing_id_, compositor_identifier);
938 970
971 if (!is_accelerated_compositing_active_) {
972 // When not in accelerated compositing mode, in certain cases (e.g. waiting
973 // for a resize or if no backing store) the RenderWidgetHost is blocking the
974 // browser's UI thread for some time, waiting for an UpdateRect. If we are
975 // going to switch to accelerated compositing, the GPU process may need
976 // round-trips to the browser's UI thread before finishing the frame,
977 // causing deadlocks if we delay the UpdateRect until we receive the
978 // OnSwapBuffersComplete. So send a dummy message that will unblock the
979 // browser's UI thread.
980 Send(new ViewHostMsg_UpdateIsDelayed(routing_id_));
981 }
982
939 is_accelerated_compositing_active_ = true; 983 is_accelerated_compositing_active_ = true;
940 Send(new ViewHostMsg_DidActivateAcceleratedCompositing( 984 Send(new ViewHostMsg_DidActivateAcceleratedCompositing(
941 routing_id_, is_accelerated_compositing_active_)); 985 routing_id_, is_accelerated_compositing_active_));
942 986
943 // Note: asynchronous swapbuffer support currently only matters if 987 // Note: asynchronous swapbuffer support currently only matters if
944 // compositing scheduling happens on the RenderWidget. 988 // compositing scheduling happens on the RenderWidget.
945 using_asynchronous_swapbuffers_ = SupportsAsynchronousSwapBuffers(); 989 using_asynchronous_swapbuffers_ = SupportsAsynchronousSwapBuffers();
946 } 990 }
947 991
948 void RenderWidget::didDeactivateCompositor() { 992 void RenderWidget::didDeactivateCompositor() {
949 TRACE_EVENT0("gpu", "RenderWidget::didDeactivateCompositor"); 993 TRACE_EVENT0("gpu", "RenderWidget::didDeactivateCompositor");
950 994
951 is_accelerated_compositing_active_ = false; 995 is_accelerated_compositing_active_ = false;
952 Send(new ViewHostMsg_DidActivateAcceleratedCompositing( 996 Send(new ViewHostMsg_DidActivateAcceleratedCompositing(
953 routing_id_, is_accelerated_compositing_active_)); 997 routing_id_, is_accelerated_compositing_active_));
954 998
955 if (using_asynchronous_swapbuffers_) 999 if (using_asynchronous_swapbuffers_)
956 using_asynchronous_swapbuffers_ = false; 1000 using_asynchronous_swapbuffers_ = false;
957 } 1001 }
958 1002
959 void RenderWidget::didCommitAndDrawCompositorFrame() { 1003 void RenderWidget::didCommitAndDrawCompositorFrame() {
960 TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame"); 1004 TRACE_EVENT0("gpu", "RenderWidget::didCommitAndDrawCompositorFrame");
961 // Notify subclasses. 1005 // Notify subclasses.
962 DidFlushPaint(); 1006 DidFlushPaint();
963 } 1007 }
964 1008
965 void RenderWidget::didCompleteSwapBuffers() { 1009 void RenderWidget::didCompleteSwapBuffers() {
966 if (update_reply_pending()) 1010 if (update_reply_pending_)
967 return; 1011 return;
968 1012
969 if (!next_paint_flags_ && !plugin_window_moves_.size()) 1013 if (!next_paint_flags_ && !plugin_window_moves_.size())
970 return; 1014 return;
971 1015
972 ViewHostMsg_UpdateRect_Params params; 1016 ViewHostMsg_UpdateRect_Params params;
973 params.view_size = size_; 1017 params.view_size = size_;
974 params.resizer_rect = resizer_rect_; 1018 params.resizer_rect = resizer_rect_;
975 params.plugin_window_moves.swap(plugin_window_moves_); 1019 params.plugin_window_moves.swap(plugin_window_moves_);
976 params.flags = next_paint_flags_; 1020 params.flags = next_paint_flags_;
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 } 1532 }
1489 } 1533 }
1490 1534
1491 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { 1535 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) {
1492 return false; 1536 return false;
1493 } 1537 }
1494 1538
1495 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const { 1539 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const {
1496 return false; 1540 return false;
1497 } 1541 }
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