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

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

Issue 23694031: Fix race conditions in window snapshot code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 <math.h> 7 #include <math.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/containers/hash_tables.h" 13 #include "base/containers/hash_tables.h"
14 #include "base/debug/trace_event.h" 14 #include "base/debug/trace_event.h"
15 #include "base/i18n/rtl.h" 15 #include "base/i18n/rtl.h"
16 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/logging.h"
17 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
18 #include "base/metrics/field_trial.h" 19 #include "base/metrics/field_trial.h"
19 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
20 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
22 #include "cc/output/compositor_frame.h" 23 #include "cc/output/compositor_frame.h"
23 #include "cc/output/compositor_frame_ack.h" 24 #include "cc/output/compositor_frame_ack.h"
24 #include "content/browser/accessibility/browser_accessibility_state_impl.h" 25 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
25 #include "content/browser/gpu/compositor_util.h" 26 #include "content/browser/gpu/compositor_util.h"
26 #include "content/browser/gpu/gpu_process_host.h" 27 #include "content/browser/gpu/gpu_process_host.h"
(...skipping 22 matching lines...) Expand all
49 #include "content/public/common/content_switches.h" 50 #include "content/public/common/content_switches.h"
50 #include "content/public/common/result_codes.h" 51 #include "content/public/common/result_codes.h"
51 #include "skia/ext/image_operations.h" 52 #include "skia/ext/image_operations.h"
52 #include "skia/ext/platform_canvas.h" 53 #include "skia/ext/platform_canvas.h"
53 #include "third_party/WebKit/public/web/WebCompositionUnderline.h" 54 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
54 #include "ui/base/events/event.h" 55 #include "ui/base/events/event.h"
55 #include "ui/base/keycodes/keyboard_codes.h" 56 #include "ui/base/keycodes/keyboard_codes.h"
56 #include "ui/gfx/size_conversions.h" 57 #include "ui/gfx/size_conversions.h"
57 #include "ui/gfx/skbitmap_operations.h" 58 #include "ui/gfx/skbitmap_operations.h"
58 #include "ui/gfx/vector2d_conversions.h" 59 #include "ui/gfx/vector2d_conversions.h"
60 #include "ui/snapshot/snapshot.h"
59 #include "webkit/common/cursors/webcursor.h" 61 #include "webkit/common/cursors/webcursor.h"
60 #include "webkit/common/webpreferences.h" 62 #include "webkit/common/webpreferences.h"
61 63
62 #if defined(TOOLKIT_GTK) 64 #if defined(TOOLKIT_GTK)
63 #include "content/browser/renderer_host/backing_store_gtk.h" 65 #include "content/browser/renderer_host/backing_store_gtk.h"
64 #elif defined(OS_MACOSX) 66 #elif defined(OS_MACOSX)
65 #include "content/browser/renderer_host/backing_store_mac.h" 67 #include "content/browser/renderer_host/backing_store_mac.h"
66 #elif defined(OS_WIN) 68 #elif defined(OS_WIN)
67 #include "content/common/plugin_constants_win.h" 69 #include "content/common/plugin_constants_win.h"
68 #endif 70 #endif
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 // problem, for example by tracking in the RenderWidgetHelper the routing id 169 // problem, for example by tracking in the RenderWidgetHelper the routing id
168 // (and surface id) that have been created, but whose RWH haven't yet. 170 // (and surface id) that have been created, but whose RWH haven't yet.
169 surface_id_ = GpuSurfaceTracker::Get()->LookupSurfaceForRenderer( 171 surface_id_ = GpuSurfaceTracker::Get()->LookupSurfaceForRenderer(
170 process_->GetID(), 172 process_->GetID(),
171 routing_id_); 173 routing_id_);
172 DCHECK(surface_id_); 174 DCHECK(surface_id_);
173 } 175 }
174 176
175 is_threaded_compositing_enabled_ = IsThreadedCompositingEnabled(); 177 is_threaded_compositing_enabled_ = IsThreadedCompositingEnabled();
176 178
179 LOG(INFO) << "RenderWidgetHostImpl: created for process id = " << process->Get ID() << " routing id = " << routing_id_;
180
177 g_routing_id_widget_map.Get().insert(std::make_pair( 181 g_routing_id_widget_map.Get().insert(std::make_pair(
178 RenderWidgetHostID(process->GetID(), routing_id_), this)); 182 RenderWidgetHostID(process->GetID(), routing_id_), this));
179 process_->AddRoute(routing_id_, this); 183 process_->AddRoute(routing_id_, this);
180 184
181 // If we're initially visible, tell the process host that we're alive. 185 // If we're initially visible, tell the process host that we're alive.
182 // Otherwise we'll notify the process host when we are first shown. 186 // Otherwise we'll notify the process host when we are first shown.
183 if (!hidden) 187 if (!hidden)
184 process_->WidgetRestored(); 188 process_->WidgetRestored();
185 189
186 accessibility_mode_ = 190 accessibility_mode_ =
(...skipping 2258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 1000000, 2449 1000000,
2446 100); 2450 100);
2447 } 2451 }
2448 2452
2449 if (CommandLine::ForCurrentProcess()->HasSwitch( 2453 if (CommandLine::ForCurrentProcess()->HasSwitch(
2450 switches::kEnableGpuBenchmarking)) 2454 switches::kEnableGpuBenchmarking))
2451 Send(new ViewMsg_SetBrowserRenderingStats(routing_id_, rendering_stats_)); 2455 Send(new ViewMsg_SetBrowserRenderingStats(routing_id_, rendering_stats_));
2452 } 2456 }
2453 2457
2454 void RenderWidgetHostImpl::FrameSwapped(const ui::LatencyInfo& latency_info) { 2458 void RenderWidgetHostImpl::FrameSwapped(const ui::LatencyInfo& latency_info) {
2459 LOG(INFO) << "RenderWidgetHostImpl::FrameSwapped";
2460 ui::LatencyInfo::LatencyComponent window_snapshot_component;
2461 if (latency_info.FindLatency(ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT,
2462 GetLatencyComponentId(),
2463 &window_snapshot_component)) {
2464 WindowSnapshotReachedScreen(
2465 static_cast<int>(window_snapshot_component.sequence_number));
2466 }
2467
2455 ui::LatencyInfo::LatencyComponent rwh_component; 2468 ui::LatencyInfo::LatencyComponent rwh_component;
2456 if (!latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_RWH_COMPONENT, 2469 if (!latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_RWH_COMPONENT,
2457 GetLatencyComponentId(), 2470 GetLatencyComponentId(),
2458 &rwh_component)) 2471 &rwh_component))
2459 return; 2472 return;
2460 2473
2461 rendering_stats_.input_event_count += rwh_component.event_count; 2474 rendering_stats_.input_event_count += rwh_component.event_count;
2462 rendering_stats_.total_input_latency += 2475 rendering_stats_.total_input_latency +=
2463 rwh_component.event_count * 2476 rwh_component.event_count *
2464 (latency_info.swap_timestamp - rwh_component.event_time); 2477 (latency_info.swap_timestamp - rwh_component.event_time);
(...skipping 24 matching lines...) Expand all
2489 2502
2490 if (CommandLine::ForCurrentProcess()->HasSwitch( 2503 if (CommandLine::ForCurrentProcess()->HasSwitch(
2491 switches::kEnableGpuBenchmarking)) 2504 switches::kEnableGpuBenchmarking))
2492 Send(new ViewMsg_SetBrowserRenderingStats(routing_id_, rendering_stats_)); 2505 Send(new ViewMsg_SetBrowserRenderingStats(routing_id_, rendering_stats_));
2493 } 2506 }
2494 2507
2495 void RenderWidgetHostImpl::DidReceiveRendererFrame() { 2508 void RenderWidgetHostImpl::DidReceiveRendererFrame() {
2496 view_->DidReceiveRendererFrame(); 2509 view_->DidReceiveRendererFrame();
2497 } 2510 }
2498 2511
2512 void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) {
2513 LOG(INFO) << "RenderWidgetHostImpl::WindowSnapshotReachedScreen: " << snapshot _id;
2514
2515 DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_UI));
2516
2517 std::vector<unsigned char> png;
2518
2519 // This feature is behind the kEnableGpuBenchmarking command line switch
2520 // because it poses security concerns and should only be used for testing.
2521 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
jbauman 2013/09/13 22:33:24 Can multiple snapshots be outstanding at once? If
2522 if (command_line.HasSwitch(switches::kEnableGpuBenchmarking)) {
2523 gfx::Rect view_bounds = GetView()->GetViewBounds();
2524 gfx::Rect snapshot_bounds(view_bounds.size());
2525 gfx::Size snapshot_size = snapshot_bounds.size();
2526
2527 if (ui::GrabViewSnapshot(GetView()->GetNativeView(),
2528 &png, snapshot_bounds)) {
2529 Send(new ViewMsg_WindowSnapshotCompleted(
2530 GetRoutingID(), snapshot_id, snapshot_size, png));
2531 return;
2532 }
2533 }
2534
2535 Send(new ViewMsg_WindowSnapshotCompleted(
2536 GetRoutingID(), snapshot_id, gfx::Size(), png));
2537 }
2538
2499 // static 2539 // static
2500 void RenderWidgetHostImpl::CompositorFrameDrawn( 2540 void RenderWidgetHostImpl::CompositorFrameDrawn(
2501 const ui::LatencyInfo& latency_info) { 2541 const ui::LatencyInfo& latency_info) {
2542 LOG(INFO) << "RenderWidgetHostImpl::CompositorFrameDrawn top level";
2502 for (ui::LatencyInfo::LatencyMap::const_iterator b = 2543 for (ui::LatencyInfo::LatencyMap::const_iterator b =
2503 latency_info.latency_components.begin(); 2544 latency_info.latency_components.begin();
2504 b != latency_info.latency_components.end(); 2545 b != latency_info.latency_components.end();
2505 ++b) { 2546 ++b) {
2506 if (b->first.first != ui::INPUT_EVENT_LATENCY_RWH_COMPONENT) 2547 if (b->first.first == ui::INPUT_EVENT_LATENCY_RWH_COMPONENT ||
2548 b->first.first == ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT) {
2549 // Matches with GetLatencyComponentId
2550 int routing_id = b->first.second & 0xffffffff;
2551 int process_id = (b->first.second >> 32) & 0xffffffff;
2552 LOG(INFO) << "RenderWidgetHostImpl::CompositorFrameDrawn: type = " << (int ) b->first.first << " process id = " << process_id << " routing_id = " << rout ing_id;
2553 RenderWidgetHost* rwh =
2554 RenderWidgetHost::FromID(process_id, routing_id);
2555 if (!rwh) {
2556 LOG(INFO) << " (no such RenderWidgetHost)";
2557 continue;
2558 }
2559 RenderWidgetHostImpl::From(rwh)->FrameSwapped(latency_info);
jbauman 2013/09/13 22:33:24 You should probably make a set of RWHI to send the
2507 continue; 2560 continue;
2508 // Matches with GetLatencyComponentId 2561 }
2509 int routing_id = b->first.second & 0xffffffff;
2510 int process_id = (b->first.second >> 32) & 0xffffffff;
2511 RenderWidgetHost* rwh =
2512 RenderWidgetHost::FromID(process_id, routing_id);
2513 if (!rwh)
2514 continue;
2515 RenderWidgetHostImpl::From(rwh)->FrameSwapped(latency_info);
2516 } 2562 }
2517 } 2563 }
2518 2564
2519 } // namespace content 2565 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698