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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 animation_task_posted_(false), | 96 animation_task_posted_(false), |
97 invalidation_task_posted_(false) { | 97 invalidation_task_posted_(false) { |
98 RenderProcess::current()->AddRefProcess(); | 98 RenderProcess::current()->AddRefProcess(); |
99 DCHECK(RenderThread::Get()); | 99 DCHECK(RenderThread::Get()); |
100 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( | 100 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( |
101 switches::kDisableGpuVsync); | 101 switches::kDisableGpuVsync); |
102 } | 102 } |
103 | 103 |
104 RenderWidget::~RenderWidget() { | 104 RenderWidget::~RenderWidget() { |
105 DCHECK(!webwidget_) << "Leaking our WebWidget!"; | 105 DCHECK(!webwidget_) << "Leaking our WebWidget!"; |
106 while (!updates_pending_swap_.empty()) { | |
jam
2011/11/11 03:03:45
STLDeleteContainerPointers?
piman
2011/11/16 01:00:55
std::queue doesn't have iterators. I changed to a
| |
107 delete updates_pending_swap_.front(); | |
108 updates_pending_swap_.pop(); | |
109 } | |
106 if (current_paint_buf_) { | 110 if (current_paint_buf_) { |
107 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); | 111 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); |
108 current_paint_buf_ = NULL; | 112 current_paint_buf_ = NULL; |
109 } | 113 } |
110 // If we are swapped out, we have released already. | 114 // If we are swapped out, we have released already. |
111 if (!is_swapped_out_) | 115 if (!is_swapped_out_) |
112 RenderProcess::current()->ReleaseProcess(); | 116 RenderProcess::current()->ReleaseProcess(); |
113 } | 117 } |
114 | 118 |
115 // static | 119 // static |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 RenderProcess::current()->ReleaseProcess(); | 352 RenderProcess::current()->ReleaseProcess(); |
349 } | 353 } |
350 | 354 |
351 void RenderWidget::OnRequestMoveAck() { | 355 void RenderWidget::OnRequestMoveAck() { |
352 DCHECK(pending_window_rect_count_); | 356 DCHECK(pending_window_rect_count_); |
353 pending_window_rect_count_--; | 357 pending_window_rect_count_--; |
354 } | 358 } |
355 | 359 |
356 void RenderWidget::OnUpdateRectAck() { | 360 void RenderWidget::OnUpdateRectAck() { |
357 TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck"); | 361 TRACE_EVENT0("renderer", "RenderWidget::OnUpdateRectAck"); |
358 DCHECK(update_reply_pending()); | 362 DCHECK(update_reply_pending_); |
359 update_reply_pending_ = false; | 363 update_reply_pending_ = false; |
360 | 364 |
361 // If we sent an UpdateRect message with a zero-sized bitmap, then we should | 365 // If we sent an UpdateRect message with a zero-sized bitmap, then we should |
362 // have no current paint buffer. | 366 // have no current paint buffer. |
363 if (current_paint_buf_) { | 367 if (current_paint_buf_) { |
364 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); | 368 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); |
365 current_paint_buf_ = NULL; | 369 current_paint_buf_ = NULL; |
366 } | 370 } |
367 | 371 |
368 // If swapbuffers is still pending, then defer the update until the | 372 // If swapbuffers is still pending, then defer the update until the |
(...skipping 11 matching lines...) Expand all Loading... | |
380 } | 384 } |
381 | 385 |
382 bool RenderWidget::SupportsAsynchronousSwapBuffers() | 386 bool RenderWidget::SupportsAsynchronousSwapBuffers() |
383 { | 387 { |
384 return false; | 388 return false; |
385 } | 389 } |
386 | 390 |
387 void RenderWidget::OnSwapBuffersAborted() | 391 void RenderWidget::OnSwapBuffersAborted() |
388 { | 392 { |
389 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); | 393 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); |
394 while (!updates_pending_swap_.empty()) { | |
395 ViewHostMsg_UpdateRect* msg = updates_pending_swap_.front(); | |
396 updates_pending_swap_.pop(); | |
397 if (msg) | |
jam
2011/11/11 03:03:45
here and below, when would updates_pending_swap_ n
piman
2011/11/16 01:00:55
Added a comment.
| |
398 Send(msg); | |
399 } | |
390 num_swapbuffers_complete_pending_ = 0; | 400 num_swapbuffers_complete_pending_ = 0; |
391 using_asynchronous_swapbuffers_ = false; | 401 using_asynchronous_swapbuffers_ = false; |
392 // Schedule another frame so the compositor learns about it. | 402 // Schedule another frame so the compositor learns about it. |
393 scheduleComposite(); | 403 scheduleComposite(); |
394 } | 404 } |
395 | 405 |
396 void RenderWidget::OnSwapBuffersPosted() { | 406 void RenderWidget::OnSwapBuffersPosted() { |
397 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); | 407 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted"); |
398 if (using_asynchronous_swapbuffers_) | 408 |
409 if (using_asynchronous_swapbuffers_) { | |
410 ViewHostMsg_UpdateRect* msg = NULL; | |
411 if (pending_update_params_.get()) { | |
412 msg = new ViewHostMsg_UpdateRect(routing_id_, *pending_update_params_); | |
413 pending_update_params_.reset(); | |
414 } | |
415 updates_pending_swap_.push(msg); | |
399 num_swapbuffers_complete_pending_++; | 416 num_swapbuffers_complete_pending_++; |
417 } | |
400 } | 418 } |
401 | 419 |
402 void RenderWidget::OnSwapBuffersComplete() { | 420 void RenderWidget::OnSwapBuffersComplete() { |
403 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete"); | 421 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete"); |
404 // When compositing deactivates, we reset the swapbuffers pending count. The | 422 // When compositing deactivates, we reset the swapbuffers pending count. The |
405 // swapbuffers acks may still arrive, however. | 423 // swapbuffers acks may still arrive, however. |
406 if (num_swapbuffers_complete_pending_ == 0) { | 424 if (num_swapbuffers_complete_pending_ == 0) { |
407 TRACE_EVENT0("renderer", "EarlyOut_ZeroSwapbuffersPending"); | 425 TRACE_EVENT0("renderer", "EarlyOut_ZeroSwapbuffersPending"); |
408 return; | 426 return; |
409 } | 427 } |
428 DCHECK(!updates_pending_swap_.empty()); | |
429 ViewHostMsg_UpdateRect* msg = updates_pending_swap_.front(); | |
430 updates_pending_swap_.pop(); | |
431 if (msg) { | |
432 Send(msg); | |
433 } | |
410 num_swapbuffers_complete_pending_--; | 434 num_swapbuffers_complete_pending_--; |
411 | 435 |
412 // If update reply is still pending, then defer the update until that reply | 436 // If update reply is still pending, then defer the update until that reply |
413 // occurs. | 437 // occurs. |
414 if (update_reply_pending_){ | 438 if (update_reply_pending_){ |
415 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); | 439 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); |
416 return; | 440 return; |
417 } | 441 } |
418 | 442 |
419 // If we are not accelerated rendering, then this is a stale swapbuffers from | 443 // If we are not accelerated rendering, then this is a stale swapbuffers from |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
703 | 727 |
704 if (pending_input_event_ack_.get()) | 728 if (pending_input_event_ack_.get()) |
705 Send(pending_input_event_ack_.release()); | 729 Send(pending_input_event_ack_.release()); |
706 } | 730 } |
707 | 731 |
708 void RenderWidget::DoDeferredUpdate() { | 732 void RenderWidget::DoDeferredUpdate() { |
709 TRACE_EVENT0("renderer", "RenderWidget::DoDeferredUpdate"); | 733 TRACE_EVENT0("renderer", "RenderWidget::DoDeferredUpdate"); |
710 | 734 |
711 if (!webwidget_) | 735 if (!webwidget_) |
712 return; | 736 return; |
713 if (update_reply_pending()) { | 737 if (update_reply_pending_) { |
714 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); | 738 TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending"); |
715 return; | 739 return; |
716 } | 740 } |
717 if (is_accelerated_compositing_active_ && | 741 if (is_accelerated_compositing_active_ && |
718 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) { | 742 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) { |
719 TRACE_EVENT0("renderer", "EarlyOut_MaxSwapBuffersPending"); | 743 TRACE_EVENT0("renderer", "EarlyOut_MaxSwapBuffersPending"); |
720 return; | 744 return; |
721 } | 745 } |
722 | 746 |
723 // Suppress updating when we are hidden. | 747 // Suppress updating when we are hidden. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 last_do_deferred_update_time_ = frame_begin_ticks; | 791 last_do_deferred_update_time_ = frame_begin_ticks; |
768 | 792 |
769 // OK, save the pending update to a local since painting may cause more | 793 // OK, save the pending update to a local since painting may cause more |
770 // invalidation. Some WebCore rendering objects only layout when painted. | 794 // invalidation. Some WebCore rendering objects only layout when painted. |
771 PaintAggregator::PendingUpdate update; | 795 PaintAggregator::PendingUpdate update; |
772 paint_aggregator_.PopPendingUpdate(&update); | 796 paint_aggregator_.PopPendingUpdate(&update); |
773 | 797 |
774 gfx::Rect scroll_damage = update.GetScrollDamage(); | 798 gfx::Rect scroll_damage = update.GetScrollDamage(); |
775 gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage); | 799 gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage); |
776 | 800 |
777 // Compositing the page may disable accelerated compositing. | |
778 bool accelerated_compositing_was_active = is_accelerated_compositing_active_; | |
779 | |
780 // A plugin may be able to do an optimized paint. First check this, in which | 801 // A plugin may be able to do an optimized paint. First check this, in which |
781 // case we can skip all of the bitmap generation and regular paint code. | 802 // case we can skip all of the bitmap generation and regular paint code. |
782 // This optimization allows PPAPI plugins that declare themselves on top of | 803 // This optimization allows PPAPI plugins that declare themselves on top of |
783 // the page (like a traditional windowed plugin) to be able to animate (think | 804 // the page (like a traditional windowed plugin) to be able to animate (think |
784 // movie playing) without repeatedly re-painting the page underneath, or | 805 // movie playing) without repeatedly re-painting the page underneath, or |
785 // copying the plugin backing store (since we can send the plugin's backing | 806 // copying the plugin backing store (since we can send the plugin's backing |
786 // store directly to the browser). | 807 // store directly to the browser). |
787 // | 808 // |
788 // This optimization only works when the entire invalid region is contained | 809 // This optimization only works when the entire invalid region is contained |
789 // within the plugin. There is a related optimization in PaintRect for the | 810 // within the plugin. There is a related optimization in PaintRect for the |
790 // case where there may be multiple invalid regions. | 811 // case where there may be multiple invalid regions. |
791 TransportDIB::Id dib_id = TransportDIB::Id(); | |
792 TransportDIB* dib = NULL; | 812 TransportDIB* dib = NULL; |
793 std::vector<gfx::Rect> copy_rects; | |
794 gfx::Rect optimized_copy_rect, optimized_copy_location; | 813 gfx::Rect optimized_copy_rect, optimized_copy_location; |
814 DCHECK(!pending_update_params_.get()); | |
815 pending_update_params_.reset(new ViewHostMsg_UpdateRect_Params); | |
816 pending_update_params_->dx = update.scroll_delta.x(); | |
817 pending_update_params_->dy = update.scroll_delta.y(); | |
818 pending_update_params_->scroll_rect = update.scroll_rect; | |
819 pending_update_params_->view_size = size_; | |
820 pending_update_params_->resizer_rect = resizer_rect_; | |
821 pending_update_params_->plugin_window_moves.swap(plugin_window_moves_); | |
822 pending_update_params_->flags = next_paint_flags_; | |
823 pending_update_params_->scroll_offset = GetScrollOffset(); | |
824 next_paint_flags_ = 0; | |
825 | |
795 if (update.scroll_rect.IsEmpty() && | 826 if (update.scroll_rect.IsEmpty() && |
796 !is_accelerated_compositing_active_ && | 827 !is_accelerated_compositing_active_ && |
797 GetBitmapForOptimizedPluginPaint(bounds, &dib, &optimized_copy_location, | 828 GetBitmapForOptimizedPluginPaint(bounds, &dib, &optimized_copy_location, |
798 &optimized_copy_rect)) { | 829 &optimized_copy_rect)) { |
799 // Only update the part of the plugin that actually changed. | 830 // Only update the part of the plugin that actually changed. |
800 optimized_copy_rect = optimized_copy_rect.Intersect(bounds); | 831 optimized_copy_rect = optimized_copy_rect.Intersect(bounds); |
801 bounds = optimized_copy_location; | 832 pending_update_params_->bitmap = dib->id(); |
802 copy_rects.push_back(optimized_copy_rect); | 833 pending_update_params_->bitmap_rect = optimized_copy_location; |
803 dib_id = dib->id(); | 834 pending_update_params_->copy_rects.push_back(optimized_copy_rect); |
835 pending_update_params_->flags |= ViewHostMsg_UpdateRect_Flags::NEEDS_ACK; | |
804 } else if (!is_accelerated_compositing_active_) { | 836 } else if (!is_accelerated_compositing_active_) { |
805 // Compute a buffer for painting and cache it. | 837 // Compute a buffer for painting and cache it. |
806 scoped_ptr<skia::PlatformCanvas> canvas( | 838 scoped_ptr<skia::PlatformCanvas> canvas( |
807 RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_, | 839 RenderProcess::current()->GetDrawingCanvas(¤t_paint_buf_, |
808 bounds)); | 840 bounds)); |
809 if (!canvas.get()) { | 841 if (!canvas.get()) { |
810 NOTREACHED(); | 842 NOTREACHED(); |
811 return; | 843 return; |
812 } | 844 } |
813 | 845 |
814 // We may get back a smaller canvas than we asked for. | 846 // We may get back a smaller canvas than we asked for. |
815 // TODO(darin): This seems like it could cause painting problems! | 847 // TODO(darin): This seems like it could cause painting problems! |
816 DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); | 848 DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); |
817 DCHECK_EQ(bounds.height(), canvas->getDevice()->height()); | 849 DCHECK_EQ(bounds.height(), canvas->getDevice()->height()); |
818 bounds.set_width(canvas->getDevice()->width()); | 850 bounds.set_width(canvas->getDevice()->width()); |
819 bounds.set_height(canvas->getDevice()->height()); | 851 bounds.set_height(canvas->getDevice()->height()); |
820 | 852 |
821 HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size()); | 853 HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size()); |
822 | 854 |
855 pending_update_params_->bitmap = current_paint_buf_->id(); | |
856 pending_update_params_->bitmap_rect = bounds; | |
857 pending_update_params_->flags |= ViewHostMsg_UpdateRect_Flags::NEEDS_ACK; | |
858 | |
859 std::vector<gfx::Rect>& copy_rects = pending_update_params_->copy_rects; | |
823 // The scroll damage is just another rectangle to paint and copy. | 860 // The scroll damage is just another rectangle to paint and copy. |
824 copy_rects.swap(update.paint_rects); | 861 copy_rects.swap(update.paint_rects); |
825 if (!scroll_damage.IsEmpty()) | 862 if (!scroll_damage.IsEmpty()) |
826 copy_rects.push_back(scroll_damage); | 863 copy_rects.push_back(scroll_damage); |
827 | 864 |
828 for (size_t i = 0; i < copy_rects.size(); ++i) | 865 for (size_t i = 0; i < copy_rects.size(); ++i) |
829 PaintRect(copy_rects[i], bounds.origin(), canvas.get()); | 866 PaintRect(copy_rects[i], bounds.origin(), canvas.get()); |
830 | |
831 dib_id = current_paint_buf_->id(); | |
832 } else { // Accelerated compositing path | 867 } else { // Accelerated compositing path |
833 // Begin painting. | 868 // Begin painting. |
869 pending_update_params_->bitmap_rect = bounds; | |
870 pending_update_params_->scroll_rect = gfx::Rect(); | |
834 webwidget_->composite(false); | 871 webwidget_->composite(false); |
835 } | 872 } |
836 | 873 |
837 // sending an ack to browser process that the paint is complete... | 874 // If composite() called SwapBuffers, pending_update_params_ will be reset (in |
838 ViewHostMsg_UpdateRect_Params params; | 875 // OnSwapBuffersPosted), meaning a message has been added to the |
839 params.bitmap = dib_id; | 876 // updates_pending_swap_ queue, that will be sent later. Otherwise, we send |
840 params.bitmap_rect = bounds; | 877 // the message now. |
841 params.dx = update.scroll_delta.x(); | 878 if (pending_update_params_.get()) { |
nduca
2011/11/15 01:57:32
Can we just put this in the non-composited half of
piman
2011/11/16 01:00:55
When we lose the context, composite() doesn't call
| |
842 params.dy = update.scroll_delta.y(); | 879 // sending an ack to browser process that the paint is complete... |
843 if (accelerated_compositing_was_active) { | 880 update_reply_pending_ = ViewHostMsg_UpdateRect_Flags::needs_ack( |
844 // If painting is done via the gpu process then we clear out all damage | 881 pending_update_params_->flags); |
845 // rects to save the browser process from doing unecessary work. | 882 Send(new ViewHostMsg_UpdateRect(routing_id_, *pending_update_params_)); |
nduca
2011/11/15 01:57:32
Might want to preserve this comment up by the //be
piman
2011/11/16 01:00:55
Done.
| |
846 params.scroll_rect = gfx::Rect(); | 883 pending_update_params_.reset(); |
847 params.copy_rects.clear(); | |
848 } else { | |
849 params.scroll_rect = update.scroll_rect; | |
850 params.copy_rects.swap(copy_rects); // TODO(darin): clip to bounds? | |
851 } | 884 } |
852 params.view_size = size_; | |
853 params.resizer_rect = resizer_rect_; | |
854 params.plugin_window_moves.swap(plugin_window_moves_); | |
855 params.flags = next_paint_flags_; | |
856 params.scroll_offset = GetScrollOffset(); | |
857 | |
858 update_reply_pending_ = true; | |
859 Send(new ViewHostMsg_UpdateRect(routing_id_, params)); | |
860 next_paint_flags_ = 0; | |
861 | 885 |
862 UpdateTextInputState(); | 886 UpdateTextInputState(); |
863 UpdateSelectionBounds(); | 887 UpdateSelectionBounds(); |
864 | 888 |
865 // Let derived classes know we've painted. | 889 // Let derived classes know we've painted. |
866 DidInitiatePaint(); | 890 DidInitiatePaint(); |
867 } | 891 } |
868 | 892 |
869 /////////////////////////////////////////////////////////////////////////////// | 893 /////////////////////////////////////////////////////////////////////////////// |
870 // WebWidgetClient | 894 // WebWidgetClient |
871 | 895 |
872 void RenderWidget::didInvalidateRect(const WebRect& rect) { | 896 void RenderWidget::didInvalidateRect(const WebRect& rect) { |
873 // The invalidated rect might be outside the bounds of the view. | 897 // The invalidated rect might be outside the bounds of the view. |
874 gfx::Rect view_rect(size_); | 898 gfx::Rect view_rect(size_); |
875 gfx::Rect damaged_rect = view_rect.Intersect(rect); | 899 gfx::Rect damaged_rect = view_rect.Intersect(rect); |
876 if (damaged_rect.IsEmpty()) | 900 if (damaged_rect.IsEmpty()) |
877 return; | 901 return; |
878 | 902 |
879 paint_aggregator_.InvalidateRect(damaged_rect); | 903 paint_aggregator_.InvalidateRect(damaged_rect); |
880 | 904 |
881 // We may not need to schedule another call to DoDeferredUpdate. | 905 // We may not need to schedule another call to DoDeferredUpdate. |
882 if (invalidation_task_posted_) | 906 if (invalidation_task_posted_) |
883 return; | 907 return; |
884 if (!paint_aggregator_.HasPendingUpdate()) | 908 if (!paint_aggregator_.HasPendingUpdate()) |
885 return; | 909 return; |
886 if (update_reply_pending() || | 910 if (update_reply_pending_ || |
887 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) | 911 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) |
888 return; | 912 return; |
889 | 913 |
890 // When GPU rendering, combine pending animations and invalidations into | 914 // When GPU rendering, combine pending animations and invalidations into |
891 // a single update. | 915 // a single update. |
892 if (is_accelerated_compositing_active_ && animation_task_posted_) | 916 if (is_accelerated_compositing_active_ && animation_task_posted_) |
893 return; | 917 return; |
894 | 918 |
895 // Perform updating asynchronously. This serves two purposes: | 919 // Perform updating asynchronously. This serves two purposes: |
896 // 1) Ensures that we call WebView::Paint without a bunch of other junk | 920 // 1) Ensures that we call WebView::Paint without a bunch of other junk |
(...skipping 17 matching lines...) Expand all Loading... | |
914 if (damaged_rect.IsEmpty()) | 938 if (damaged_rect.IsEmpty()) |
915 return; | 939 return; |
916 | 940 |
917 paint_aggregator_.ScrollRect(dx, dy, damaged_rect); | 941 paint_aggregator_.ScrollRect(dx, dy, damaged_rect); |
918 | 942 |
919 // We may not need to schedule another call to DoDeferredUpdate. | 943 // We may not need to schedule another call to DoDeferredUpdate. |
920 if (invalidation_task_posted_) | 944 if (invalidation_task_posted_) |
921 return; | 945 return; |
922 if (!paint_aggregator_.HasPendingUpdate()) | 946 if (!paint_aggregator_.HasPendingUpdate()) |
923 return; | 947 return; |
924 if (update_reply_pending() || | 948 if (update_reply_pending_ || |
925 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) | 949 num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) |
926 return; | 950 return; |
927 | 951 |
928 // When GPU rendering, combine pending animations and invalidations into | 952 // When GPU rendering, combine pending animations and invalidations into |
929 // a single update. | 953 // a single update. |
930 if (is_accelerated_compositing_active_ && animation_task_posted_) | 954 if (is_accelerated_compositing_active_ && animation_task_posted_) |
931 return; | 955 return; |
932 | 956 |
933 // Perform updating asynchronously. This serves two purposes: | 957 // Perform updating asynchronously. This serves two purposes: |
934 // 1) Ensures that we call WebView::Paint without a bunch of other junk | 958 // 1) Ensures that we call WebView::Paint without a bunch of other junk |
935 // on the call stack. | 959 // on the call stack. |
936 // 2) Allows us to collect more damage rects before painting to help coalesce | 960 // 2) Allows us to collect more damage rects before painting to help coalesce |
937 // the work that we will need to do. | 961 // the work that we will need to do. |
938 invalidation_task_posted_ = true; | 962 invalidation_task_posted_ = true; |
939 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( | 963 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( |
940 this, &RenderWidget::InvalidationCallback)); | 964 this, &RenderWidget::InvalidationCallback)); |
941 } | 965 } |
942 | 966 |
943 void RenderWidget::didActivateCompositor(int compositor_identifier) { | 967 void RenderWidget::didActivateCompositor(int compositor_identifier) { |
944 TRACE_EVENT0("gpu", "RenderWidget::didActivateCompositor"); | 968 TRACE_EVENT0("gpu", "RenderWidget::didActivateCompositor"); |
945 | 969 |
946 CompositorThread* compositor_thread = | 970 CompositorThread* compositor_thread = |
947 RenderThreadImpl::current()->compositor_thread(); | 971 RenderThreadImpl::current()->compositor_thread(); |
948 if (compositor_thread) | 972 if (compositor_thread) |
949 compositor_thread->AddCompositor(routing_id_, compositor_identifier); | 973 compositor_thread->AddCompositor(routing_id_, compositor_identifier); |
950 | 974 |
975 if (!is_accelerated_compositing_active_) { | |
976 // When not in accelerated compositing mode, in certain cases (e.g. waiting | |
977 // for a resize or if no backing store) the RenderWidgetHost is blocking the | |
978 // browser's UI thread for some time, waiting for an UpdateRect. If we are | |
979 // going to switch to accelerated compositing, the GPU process may need | |
980 // round-trips to the browser's UI thread before finishing the frame, | |
981 // causing deadlocks if we delay the UpdateRect until we receive the | |
982 // OnSwapBuffersComplete. So send a dummy message that will unblock the | |
983 // browser's UI thread. | |
984 Send(new ViewHostMsg_UpdateIsDelayed(routing_id_)); | |
985 } | |
986 | |
951 is_accelerated_compositing_active_ = true; | 987 is_accelerated_compositing_active_ = true; |
952 Send(new ViewHostMsg_DidActivateAcceleratedCompositing( | 988 Send(new ViewHostMsg_DidActivateAcceleratedCompositing( |
953 routing_id_, is_accelerated_compositing_active_)); | 989 routing_id_, is_accelerated_compositing_active_)); |
954 | 990 |
955 // Note: asynchronous swapbuffer support currently only matters if | 991 // Note: asynchronous swapbuffer support currently only matters if |
956 // compositing scheduling happens on the RenderWidget. | 992 // compositing scheduling happens on the RenderWidget. |
957 using_asynchronous_swapbuffers_ = SupportsAsynchronousSwapBuffers(); | 993 using_asynchronous_swapbuffers_ = SupportsAsynchronousSwapBuffers(); |
958 } | 994 } |
959 | 995 |
960 void RenderWidget::didDeactivateCompositor() { | 996 void RenderWidget::didDeactivateCompositor() { |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1475 } | 1511 } |
1476 } | 1512 } |
1477 | 1513 |
1478 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { | 1514 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { |
1479 return false; | 1515 return false; |
1480 } | 1516 } |
1481 | 1517 |
1482 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const { | 1518 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const { |
1483 return false; | 1519 return false; |
1484 } | 1520 } |
OLD | NEW |