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

Side by Side Diff: content/browser/renderer_host/render_widget_host_impl.cc

Issue 9980016: Delete background tab IOSurfaces on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: no change - update/merge Created 8 years, 8 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
OLDNEW
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 "content/browser/renderer_host/render_widget_host_impl.h" 5 #include "content/browser/renderer_host/render_widget_host_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 using WebKit::WebMouseEvent; 58 using WebKit::WebMouseEvent;
59 using WebKit::WebMouseWheelEvent; 59 using WebKit::WebMouseWheelEvent;
60 using WebKit::WebTextDirection; 60 using WebKit::WebTextDirection;
61 61
62 namespace { 62 namespace {
63 63
64 // How long to (synchronously) wait for the renderer to respond with a 64 // How long to (synchronously) wait for the renderer to respond with a
65 // PaintRect message, when our backing-store is invalid, before giving up and 65 // PaintRect message, when our backing-store is invalid, before giving up and
66 // returning a null or incorrectly sized backing-store from GetBackingStore. 66 // returning a null or incorrectly sized backing-store from GetBackingStore.
67 // This timeout impacts the "choppiness" of our window resize perf. 67 // This timeout impacts the "choppiness" of our window resize perf.
68 static const int kPaintMsgTimeoutMS = 40; 68 static const int kPaintMsgTimeoutMS = 50;
69 69
70 // How long to wait before we consider a renderer hung. 70 // How long to wait before we consider a renderer hung.
71 static const int kHungRendererDelayMs = 20000; 71 static const int kHungRendererDelayMs = 20000;
72 72
73 // Returns |true| if the two wheel events should be coalesced. 73 // Returns |true| if the two wheel events should be coalesced.
74 bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event, 74 bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event,
75 const WebMouseWheelEvent& new_event) { 75 const WebMouseWheelEvent& new_event) {
76 return last_event.modifiers == new_event.modifiers && 76 return last_event.modifiers == new_event.modifiers &&
77 last_event.scrollByPage == new_event.scrollByPage && 77 last_event.scrollByPage == new_event.scrollByPage &&
78 last_event.hasPreciseScrollingDeltas 78 last_event.hasPreciseScrollingDeltas
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) { 250 bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
251 bool handled = true; 251 bool handled = true;
252 bool msg_is_ok = true; 252 bool msg_is_ok = true;
253 IPC_BEGIN_MESSAGE_MAP_EX(RenderWidgetHostImpl, msg, msg_is_ok) 253 IPC_BEGIN_MESSAGE_MAP_EX(RenderWidgetHostImpl, msg, msg_is_ok)
254 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnMsgRenderViewReady) 254 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnMsgRenderViewReady)
255 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewGone, OnMsgRenderViewGone) 255 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewGone, OnMsgRenderViewGone)
256 IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose) 256 IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose)
257 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove) 257 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove)
258 IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnMsgSetTooltipText) 258 IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnMsgSetTooltipText)
259 IPC_MESSAGE_HANDLER(ViewHostMsg_PaintAtSize_ACK, OnMsgPaintAtSizeAck) 259 IPC_MESSAGE_HANDLER(ViewHostMsg_PaintAtSize_ACK, OnMsgPaintAtSizeAck)
260 IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped,
261 OnCompositorSurfaceBuffersSwapped)
260 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnMsgUpdateRect) 262 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnMsgUpdateRect)
261 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnMsgUpdateIsDelayed) 263 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnMsgUpdateIsDelayed)
262 IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck) 264 IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck)
263 IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus) 265 IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus)
264 IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) 266 IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur)
265 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeNumTouchEvents, 267 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeNumTouchEvents,
266 OnMsgDidChangeNumTouchEvents) 268 OnMsgDidChangeNumTouchEvents)
267 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) 269 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor)
268 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged, 270 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
269 OnMsgTextInputStateChanged) 271 OnMsgTextInputStateChanged)
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 int tag, 569 int tag,
568 const gfx::Size& page_size, 570 const gfx::Size& page_size,
569 const gfx::Size& desired_size) { 571 const gfx::Size& desired_size) {
570 // Ask the renderer to create a bitmap regardless of whether it's 572 // Ask the renderer to create a bitmap regardless of whether it's
571 // hidden, being resized, redrawn, etc. It resizes the web widget 573 // hidden, being resized, redrawn, etc. It resizes the web widget
572 // to the page_size and then scales it to the desired_size. 574 // to the page_size and then scales it to the desired_size.
573 Send(new ViewMsg_PaintAtSize(routing_id_, dib_handle, tag, 575 Send(new ViewMsg_PaintAtSize(routing_id_, dib_handle, tag,
574 page_size, desired_size)); 576 page_size, desired_size));
575 } 577 }
576 578
579 bool RenderWidgetHostImpl::TryGetBackingStore(const gfx::Size& desired_size,
580 BackingStore** backing_store) {
581 // Check if the view has an accelerated surface of the desired size.
582 if (view_->HasAcceleratedSurface(desired_size)) {
583 *backing_store = NULL;
584 return true;
585 }
586
587 // Check for a software backing store of the desired size.
588 *backing_store = BackingStoreManager::GetBackingStore(this, desired_size);
589 return !!*backing_store;
590 }
591
577 BackingStore* RenderWidgetHostImpl::GetBackingStore(bool force_create) { 592 BackingStore* RenderWidgetHostImpl::GetBackingStore(bool force_create) {
593 if (!view_)
594 return NULL;
595
596 // Get the desired size from the current view bounds.
597 gfx::Rect view_rect = view_->GetViewBounds();
598 if (view_rect.IsEmpty())
599 return NULL;
600 gfx::Size view_size = view_rect.size();
601
578 TRACE_EVENT2("renderer_host", "RenderWidgetHostImpl::GetBackingStore", 602 TRACE_EVENT2("renderer_host", "RenderWidgetHostImpl::GetBackingStore",
579 "width", base::IntToString(current_size_.width()), 603 "width", base::IntToString(view_size.width()),
580 "height", base::IntToString(current_size_.height())); 604 "height", base::IntToString(view_size.height()));
581 605
582 // We should not be asked to paint while we are hidden. If we are hidden, 606 // We should not be asked to paint while we are hidden. If we are hidden,
583 // then it means that our consumer failed to call WasRestored. If we're not 607 // then it means that our consumer failed to call WasRestored. If we're not
584 // force creating the backing store, it's OK since we can feel free to give 608 // force creating the backing store, it's OK since we can feel free to give
585 // out our cached one if we have it. 609 // out our cached one if we have it.
586 DCHECK(!is_hidden_ || !force_create) << 610 DCHECK(!is_hidden_ || !force_create) <<
587 "GetBackingStore called while hidden!"; 611 "GetBackingStore called while hidden!";
588 612
589 // We should never be called recursively; this can theoretically lead to 613 // We should never be called recursively; this can theoretically lead to
590 // infinite recursion and almost certainly leads to lower performance. 614 // infinite recursion and almost certainly leads to lower performance.
591 DCHECK(!in_get_backing_store_) << "GetBackingStore called recursively!"; 615 DCHECK(!in_get_backing_store_) << "GetBackingStore called recursively!";
592 AutoReset<bool> auto_reset_in_get_backing_store(&in_get_backing_store_, true); 616 AutoReset<bool> auto_reset_in_get_backing_store(&in_get_backing_store_, true);
593 617
594 // We might have a cached backing store that we can reuse! 618 // We might have a cached backing store that we can reuse!
595 BackingStore* backing_store = 619 BackingStore* backing_store = NULL;
596 BackingStoreManager::GetBackingStore(this, current_size_); 620 if (TryGetBackingStore(view_size, &backing_store) || !force_create)
597 if (!force_create)
598 return backing_store; 621 return backing_store;
599 622
600 // If we fail to find a backing store in the cache, send out a request 623 TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS);
601 // to the renderer to paint the view if required. 624 TimeTicks end_time = TimeTicks::Now() + max_delay;
602 if (!backing_store && !repaint_ack_pending_ && !resize_ack_pending_ && 625 do {
603 !view_being_painted_) { 626 TRACE_EVENT0("renderer_host", "GetBackingStore::WaitForUpdate");
604 repaint_start_time_ = TimeTicks::Now();
605 repaint_ack_pending_ = true;
606 Send(new ViewMsg_Repaint(routing_id_, current_size_));
607 }
608 627
609 // When we have asked the RenderWidget to resize, and we are still waiting on 628 // We do not have a suitable backing store in the cache, so send out a
610 // a response, block for a little while to see if we can't get a response 629 // request to the renderer to paint the view if required. Note that this
611 // before returning the old (incorrectly sized) backing store. 630 // message may not be sent the first time through this loop when acks are
612 if (resize_ack_pending_ || !backing_store) { 631 // pending, but we still may need to send it if the delivered BackingStores
632 // were of the wrong size.
633 if (!repaint_ack_pending_ && !resize_ack_pending_ && !view_being_painted_) {
634 repaint_start_time_ = TimeTicks::Now();
635 repaint_ack_pending_ = true;
636 Send(new ViewMsg_Repaint(routing_id_, view_size));
637 }
638
639 // When we have asked the RenderWidget to resize, and we are still waiting
640 // on a response, block for a little while to see if we can't get a response
641 // before returning the old (incorrectly sized) backing store.
613 IPC::Message msg; 642 IPC::Message msg;
614 TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS); 643 if (process_->WaitForBackingStoreMsg(routing_id_, max_delay, &msg)) {
615 if (process_->WaitForUpdateMsg(routing_id_, max_delay, &msg)) {
616 OnMessageReceived(msg); 644 OnMessageReceived(msg);
617 backing_store = BackingStoreManager::GetBackingStore(this, current_size_); 645 // Break now if we got a backing store or accelerated surface of the
646 // correct size.
647 if (TryGetBackingStore(view_size, &backing_store))
648 return backing_store;
649 } else {
650 TRACE_EVENT0("renderer_host", "GetBackingStore::Timeout");
651 break;
618 } 652 }
619 }
620 653
654 // Loop if we still have time left and haven't gotten a properly sized
655 // BackingStore yet. This is necessary to support the GPU path which
656 // typically has multiple frames pipelined -- we may need to skip one or two
657 // BackingStore messages to get to the latest.
658 max_delay = end_time - TimeTicks::Now();
659 } while (max_delay > TimeDelta::FromSeconds(0));
660
661 // We have failed to get a backing store of view_size. Fall back on
662 // current_size_ to avoid a white flash while resizing slow pages.
663 TryGetBackingStore(current_size_, &backing_store);
621 return backing_store; 664 return backing_store;
622 } 665 }
623 666
624 BackingStore* RenderWidgetHostImpl::AllocBackingStore(const gfx::Size& size) { 667 BackingStore* RenderWidgetHostImpl::AllocBackingStore(const gfx::Size& size) {
625 if (!view_) 668 if (!view_)
626 return NULL; 669 return NULL;
627 return view_->AllocBackingStore(size); 670 return view_->AllocBackingStore(size);
628 } 671 }
629 672
630 void RenderWidgetHostImpl::DonePaintingToBackingStore() { 673 void RenderWidgetHostImpl::DonePaintingToBackingStore() {
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 } 1179 }
1137 1180
1138 void RenderWidgetHostImpl::OnMsgPaintAtSizeAck(int tag, const gfx::Size& size) { 1181 void RenderWidgetHostImpl::OnMsgPaintAtSizeAck(int tag, const gfx::Size& size) {
1139 std::pair<int, gfx::Size> details = std::make_pair(tag, size); 1182 std::pair<int, gfx::Size> details = std::make_pair(tag, size);
1140 NotificationService::current()->Notify( 1183 NotificationService::current()->Notify(
1141 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK, 1184 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK,
1142 Source<RenderWidgetHost>(this), 1185 Source<RenderWidgetHost>(this),
1143 Details<std::pair<int, gfx::Size> >(&details)); 1186 Details<std::pair<int, gfx::Size> >(&details));
1144 } 1187 }
1145 1188
1189 void RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped(
1190 int32 surface_id,
1191 uint64 surface_handle,
1192 int32 route_id,
1193 int32 gpu_process_host_id) {
1194 TRACE_EVENT0("renderer_host",
1195 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped");
1196 if (!view_) {
1197 RenderWidgetHostImpl::AcknowledgeSwapBuffers(route_id,
1198 gpu_process_host_id);
1199 return;
1200 }
1201 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params gpu_params;
1202 gpu_params.surface_id = surface_id;
1203 gpu_params.surface_handle = surface_handle;
1204 gpu_params.route_id = route_id;
1205 #if defined(OS_MACOSX)
1206 // Compositor window is always gfx::kNullPluginWindow.
1207 // TODO(jbates) http://crbug.com/105344 This will be removed when there are no
1208 // plugin windows.
1209 gpu_params.window = gfx::kNullPluginWindow;
1210 #endif
1211 view_->AcceleratedSurfaceBuffersSwapped(gpu_params,
1212 gpu_process_host_id);
1213 }
1214
1146 void RenderWidgetHostImpl::OnMsgUpdateRect( 1215 void RenderWidgetHostImpl::OnMsgUpdateRect(
1147 const ViewHostMsg_UpdateRect_Params& params) { 1216 const ViewHostMsg_UpdateRect_Params& params) {
1148 TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnMsgUpdateRect"); 1217 TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnMsgUpdateRect");
1149 TimeTicks paint_start = TimeTicks::Now(); 1218 TimeTicks paint_start = TimeTicks::Now();
1150 1219
1151 // Update our knowledge of the RenderWidget's size. 1220 // Update our knowledge of the RenderWidget's size.
1152 current_size_ = params.view_size; 1221 current_size_ = params.view_size;
1153 // Update our knowledge of the RenderWidget's scroll offset. 1222 // Update our knowledge of the RenderWidget's scroll offset.
1154 last_scroll_offset_ = params.scroll_offset; 1223 last_scroll_offset_ = params.scroll_offset;
1155 1224
(...skipping 12 matching lines...) Expand all
1168 ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags); 1237 ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags);
1169 if (is_repaint_ack) { 1238 if (is_repaint_ack) {
1170 repaint_ack_pending_ = false; 1239 repaint_ack_pending_ = false;
1171 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; 1240 TimeDelta delta = TimeTicks::Now() - repaint_start_time_;
1172 UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta); 1241 UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta);
1173 } 1242 }
1174 1243
1175 DCHECK(!params.view_size.IsEmpty()); 1244 DCHECK(!params.view_size.IsEmpty());
1176 1245
1177 bool was_async = false; 1246 bool was_async = false;
1178 if (!is_accelerated_compositing_active_) { 1247
1248 // If this is a GPU UpdateRect, params.bitmap is invalid and dib will be NULL.
1249 TransportDIB* dib = process_->GetTransportDIB(params.bitmap);
1250
1251 // If gpu process does painting, scroll_rect and copy_rects are always empty
1252 // and backing store is never used.
1253 if (dib) {
1179 DCHECK(!params.bitmap_rect.IsEmpty()); 1254 DCHECK(!params.bitmap_rect.IsEmpty());
1180 const size_t size = params.bitmap_rect.height() * 1255 const size_t size = params.bitmap_rect.height() *
1181 params.bitmap_rect.width() * 4; 1256 params.bitmap_rect.width() * 4;
1182 TransportDIB* dib = process_->GetTransportDIB(params.bitmap); 1257 if (dib->size() < size) {
1258 DLOG(WARNING) << "Transport DIB too small for given rectangle";
1259 RecordAction(UserMetricsAction("BadMessageTerminate_RWH1"));
1260 GetProcess()->ReceivedBadMessage();
1261 } else {
1262 UNSHIPPED_TRACE_EVENT_INSTANT2("test_latency", "UpdateRect",
1263 "x+y", params.bitmap_rect.x() + params.bitmap_rect.y(),
1264 "color", 0xffffff & *static_cast<uint32*>(dib->memory()));
1265 UNSHIPPED_TRACE_EVENT_INSTANT1("test_latency", "UpdateRectWidth",
1266 "width", params.bitmap_rect.width());
1183 1267
1184 // If gpu process does painting, scroll_rect and copy_rects are always empty 1268 // Scroll the backing store.
1185 // and backing store is never used. 1269 if (!params.scroll_rect.IsEmpty()) {
1186 if (dib) { 1270 ScrollBackingStoreRect(params.dx, params.dy,
1187 if (dib->size() < size) { 1271 params.scroll_rect,
1188 DLOG(WARNING) << "Transport DIB too small for given rectangle"; 1272 params.view_size);
1189 RecordAction(UserMetricsAction("BadMessageTerminate_RWH1")); 1273 }
1190 GetProcess()->ReceivedBadMessage();
1191 } else {
1192 UNSHIPPED_TRACE_EVENT_INSTANT2("test_latency", "UpdateRect",
1193 "x+y", params.bitmap_rect.x() + params.bitmap_rect.y(),
1194 "color", 0xffffff & *static_cast<uint32*>(dib->memory()));
1195 UNSHIPPED_TRACE_EVENT_INSTANT1("test_latency", "UpdateRectWidth",
1196 "width", params.bitmap_rect.width());
1197 1274
1198 // Scroll the backing store. 1275 // Paint the backing store. This will update it with the
1199 if (!params.scroll_rect.IsEmpty()) { 1276 // renderer-supplied bits. The view will read out of the backing store
1200 ScrollBackingStoreRect(params.dx, params.dy, 1277 // later to actually draw to the screen.
1201 params.scroll_rect, 1278 was_async = PaintBackingStoreRect(
1202 params.view_size); 1279 params.bitmap,
1203 } 1280 params.bitmap_rect,
1204 1281 params.copy_rects,
1205 // Paint the backing store. This will update it with the 1282 params.view_size,
1206 // renderer-supplied bits. The view will read out of the backing store 1283 base::Bind(&RenderWidgetHostImpl::DidUpdateBackingStore,
1207 // later to actually draw to the screen. 1284 weak_factory_.GetWeakPtr(), params, paint_start));
1208 was_async = PaintBackingStoreRect(
1209 params.bitmap,
1210 params.bitmap_rect,
1211 params.copy_rects,
1212 params.view_size,
1213 base::Bind(&RenderWidgetHostImpl::DidUpdateBackingStore,
1214 weak_factory_.GetWeakPtr(), params, paint_start));
1215 }
1216 } 1285 }
1217 } 1286 }
1218 1287
1219 if (!was_async) { 1288 if (!was_async) {
1220 DidUpdateBackingStore(params, paint_start); 1289 DidUpdateBackingStore(params, paint_start);
1221 } 1290 }
1222 1291
1223 if (should_auto_resize_) { 1292 if (should_auto_resize_) {
1224 bool post_callback = new_auto_size_.IsEmpty(); 1293 bool post_callback = new_auto_size_.IsEmpty();
1225 new_auto_size_ = params.view_size; 1294 new_auto_size_ = params.view_size;
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 // indicate that no callback is in progress (i.e. without this line 1795 // indicate that no callback is in progress (i.e. without this line
1727 // DelayedAutoResized will not get called again). 1796 // DelayedAutoResized will not get called again).
1728 new_auto_size_.SetSize(0, 0); 1797 new_auto_size_.SetSize(0, 0);
1729 if (!should_auto_resize_) 1798 if (!should_auto_resize_)
1730 return; 1799 return;
1731 1800
1732 OnRenderAutoResized(new_size); 1801 OnRenderAutoResized(new_size);
1733 } 1802 }
1734 1803
1735 } // namespace content 1804 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698