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

Side by Side Diff: cc/trees/thread_proxy.cc

Issue 15836005: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@nofrc
Patch Set: Fix PRId64 for Windows Created 7 years, 6 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
« no previous file with comments | « cc/trees/thread_proxy.h ('k') | chrome/test/perf/rendering/latency_tests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 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 "cc/trees/thread_proxy.h" 5 #include "cc/trees/thread_proxy.h"
6 6
7 #include <string>
8
7 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
8 #include "base/bind.h" 10 #include "base/bind.h"
9 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
10 #include "cc/base/thread.h" 12 #include "cc/base/thread.h"
11 #include "cc/input/input_handler.h" 13 #include "cc/input/input_handler.h"
12 #include "cc/output/context_provider.h" 14 #include "cc/output/context_provider.h"
13 #include "cc/output/output_surface.h" 15 #include "cc/output/output_surface.h"
14 #include "cc/quads/draw_quad.h" 16 #include "cc/quads/draw_quad.h"
15 #include "cc/resources/prioritized_resource_manager.h" 17 #include "cc/resources/prioritized_resource_manager.h"
16 #include "cc/scheduler/delay_based_time_source.h" 18 #include "cc/scheduler/delay_based_time_source.h"
17 #include "cc/scheduler/frame_rate_controller.h" 19 #include "cc/scheduler/frame_rate_controller.h"
18 #include "cc/scheduler/scheduler.h" 20 #include "cc/scheduler/scheduler.h"
19 #include "cc/scheduler/vsync_time_source.h"
20 #include "cc/trees/layer_tree_host.h" 21 #include "cc/trees/layer_tree_host.h"
21 #include "cc/trees/layer_tree_impl.h" 22 #include "cc/trees/layer_tree_impl.h"
22 23
23 namespace { 24 namespace {
24 25
25 // Measured in seconds. 26 // Measured in seconds.
26 const double kContextRecreationTickRate = 0.03; 27 const double kContextRecreationTickRate = 0.03;
27 28
28 // Measured in seconds. 29 // Measured in seconds.
29 const double kSmoothnessTakesPriorityExpirationDelay = 0.25; 30 const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
30 31
31 } // namespace 32 } // namespace
32 33
33 namespace cc { 34 namespace cc {
34 35
36 struct ThreadProxy::ReadbackRequest {
37 CompletionEvent completion;
38 bool success;
39 void* pixels;
40 gfx::Rect rect;
41 };
42
43 struct ThreadProxy::CommitPendingRequest {
44 CompletionEvent completion;
45 bool commit_pending;
46 };
47
48 struct ThreadProxy::SchedulerStateRequest {
49 CompletionEvent completion;
50 std::string state;
51 };
52
35 scoped_ptr<Proxy> ThreadProxy::Create(LayerTreeHost* layer_tree_host, 53 scoped_ptr<Proxy> ThreadProxy::Create(LayerTreeHost* layer_tree_host,
36 scoped_ptr<Thread> impl_thread) { 54 scoped_ptr<Thread> impl_thread) {
37 return make_scoped_ptr( 55 return make_scoped_ptr(
38 new ThreadProxy(layer_tree_host, impl_thread.Pass())).PassAs<Proxy>(); 56 new ThreadProxy(layer_tree_host, impl_thread.Pass())).PassAs<Proxy>();
39 } 57 }
40 58
41 ThreadProxy::ThreadProxy(LayerTreeHost* layer_tree_host, 59 ThreadProxy::ThreadProxy(LayerTreeHost* layer_tree_host,
42 scoped_ptr<Thread> impl_thread) 60 scoped_ptr<Thread> impl_thread)
43 : Proxy(impl_thread.Pass()), 61 : Proxy(impl_thread.Pass()),
44 animate_requested_(false), 62 animate_requested_(false),
(...skipping 12 matching lines...) Expand all
57 commit_completion_event_on_impl_thread_(NULL), 75 commit_completion_event_on_impl_thread_(NULL),
58 completion_event_for_commit_held_on_tree_activation_(NULL), 76 completion_event_for_commit_held_on_tree_activation_(NULL),
59 texture_acquisition_completion_event_on_impl_thread_(NULL), 77 texture_acquisition_completion_event_on_impl_thread_(NULL),
60 next_frame_is_newly_committed_frame_on_impl_thread_(false), 78 next_frame_is_newly_committed_frame_on_impl_thread_(false),
61 throttle_frame_production_( 79 throttle_frame_production_(
62 layer_tree_host->settings().throttle_frame_production), 80 layer_tree_host->settings().throttle_frame_production),
63 begin_frame_scheduling_enabled_( 81 begin_frame_scheduling_enabled_(
64 layer_tree_host->settings().begin_frame_scheduling_enabled), 82 layer_tree_host->settings().begin_frame_scheduling_enabled),
65 using_synchronous_renderer_compositor_( 83 using_synchronous_renderer_compositor_(
66 layer_tree_host->settings().using_synchronous_renderer_compositor), 84 layer_tree_host->settings().using_synchronous_renderer_compositor),
67 vsync_client_(NULL),
68 inside_draw_(false), 85 inside_draw_(false),
69 defer_commits_(false), 86 defer_commits_(false),
70 renew_tree_priority_on_impl_thread_pending_(false) { 87 renew_tree_priority_on_impl_thread_pending_(false) {
71 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); 88 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
72 DCHECK(IsMainThread()); 89 DCHECK(IsMainThread());
73 DCHECK(layer_tree_host_); 90 DCHECK(layer_tree_host_);
74 } 91 }
75 92
76 ThreadProxy::~ThreadProxy() { 93 ThreadProxy::~ThreadProxy() {
77 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy"); 94 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 offscreen_context_provider() : NULL; 338 offscreen_context_provider() : NULL;
322 339
323 if (offscreen_contexts) 340 if (offscreen_contexts)
324 offscreen_contexts->VerifyContexts(); 341 offscreen_contexts->VerifyContexts();
325 scheduler_on_impl_thread_->DidLoseOutputSurface(); 342 scheduler_on_impl_thread_->DidLoseOutputSurface();
326 } 343 }
327 344
328 void ThreadProxy::OnSwapBuffersCompleteOnImplThread() { 345 void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
329 DCHECK(IsImplThread()); 346 DCHECK(IsImplThread());
330 TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread"); 347 TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread");
331 scheduler_on_impl_thread_->DidSwapBuffersComplete();
332 Proxy::MainThread()->PostTask( 348 Proxy::MainThread()->PostTask(
333 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); 349 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
334 } 350 }
335 351
336 void ThreadProxy::OnVSyncParametersChanged(base::TimeTicks timebase, 352 void ThreadProxy::SetNeedsBeginFrameOnImplThread(bool enable) {
337 base::TimeDelta interval) {
338 DCHECK(IsImplThread()); 353 DCHECK(IsImplThread());
339 TRACE_EVENT2("cc", 354 TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrameOnImplThread",
340 "ThreadProxy::OnVSyncParametersChanged", 355 "enable", enable);
341 "timebase", 356 layer_tree_host_impl_->SetNeedsBeginFrame(enable);
342 (timebase - base::TimeTicks()).InMilliseconds(),
343 "interval",
344 interval.InMilliseconds());
345 scheduler_on_impl_thread_->SetTimebaseAndInterval(timebase, interval);
346 } 357 }
347 358
348 void ThreadProxy::BeginFrameOnImplThread(base::TimeTicks frame_time) { 359 void ThreadProxy::BeginFrameOnImplThread(base::TimeTicks frame_time) {
349 DCHECK(IsImplThread()); 360 DCHECK(IsImplThread());
350 TRACE_EVENT0("cc", "ThreadProxy::OnBeginFrameOnImplThread"); 361 TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread");
351 if (vsync_client_) 362 scheduler_on_impl_thread_->BeginFrame(frame_time);
352 vsync_client_->DidVSync(frame_time);
353 }
354
355 void ThreadProxy::RequestVSyncNotification(VSyncClient* client) {
356 DCHECK(IsImplThread());
357 TRACE_EVENT1(
358 "cc", "ThreadProxy::RequestVSyncNotification", "enable", !!client);
359 vsync_client_ = client;
360 layer_tree_host_impl_->SetNeedsBeginFrame(!!client);
361 } 363 }
362 364
363 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { 365 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
364 DCHECK(IsImplThread()); 366 DCHECK(IsImplThread());
365 TRACE_EVENT1( 367 TRACE_EVENT1(
366 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); 368 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
367 scheduler_on_impl_thread_->SetCanDraw(can_draw); 369 scheduler_on_impl_thread_->SetCanDraw(can_draw);
368 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( 370 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
369 !scheduler_on_impl_thread_->WillDrawIfNeeded()); 371 !scheduler_on_impl_thread_->WillDrawIfNeeded());
370 } 372 }
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 DCHECK(IsImplThread()); 1098 DCHECK(IsImplThread());
1097 *has_initialized_output_surface = 1099 *has_initialized_output_surface =
1098 scheduler_on_impl_thread_->HasInitializedOutputSurface(); 1100 scheduler_on_impl_thread_->HasInitializedOutputSurface();
1099 completion->Signal(); 1101 completion->Signal();
1100 } 1102 }
1101 1103
1102 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { 1104 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
1103 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); 1105 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
1104 DCHECK(IsImplThread()); 1106 DCHECK(IsImplThread());
1105 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); 1107 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
1106 const base::TimeDelta display_refresh_interval =
1107 base::TimeDelta::FromMicroseconds(
1108 base::Time::kMicrosecondsPerSecond /
1109 layer_tree_host_->settings().refresh_rate);
1110 scoped_ptr<FrameRateController> frame_rate_controller;
1111 if (throttle_frame_production_) {
1112 if (begin_frame_scheduling_enabled_) {
1113 frame_rate_controller.reset(
1114 new FrameRateController(VSyncTimeSource::Create(
1115 this,
1116 using_synchronous_renderer_compositor_ ?
1117 VSyncTimeSource::DISABLE_SYNCHRONOUSLY :
1118 VSyncTimeSource::DISABLE_ON_NEXT_TICK)));
1119 } else {
1120 frame_rate_controller.reset(
1121 new FrameRateController(DelayBasedTimeSource::Create(
1122 display_refresh_interval, Proxy::ImplThread())));
1123 }
1124 } else {
1125 frame_rate_controller.reset(new FrameRateController(Proxy::ImplThread()));
1126 }
1127 const LayerTreeSettings& settings = layer_tree_host_->settings(); 1108 const LayerTreeSettings& settings = layer_tree_host_->settings();
1128 SchedulerSettings scheduler_settings; 1109 SchedulerSettings scheduler_settings;
1129 scheduler_settings.impl_side_painting = settings.impl_side_painting; 1110 scheduler_settings.impl_side_painting = settings.impl_side_painting;
1130 scheduler_settings.timeout_and_draw_when_animation_checkerboards = 1111 scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1131 settings.timeout_and_draw_when_animation_checkerboards; 1112 settings.timeout_and_draw_when_animation_checkerboards;
1132 scheduler_on_impl_thread_ = Scheduler::Create(this, 1113 scheduler_settings.using_synchronous_renderer_compositor =
1133 frame_rate_controller.Pass(), 1114 settings.using_synchronous_renderer_compositor;
1134 scheduler_settings); 1115 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings);
1135 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); 1116 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
1136 1117
1137 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr(); 1118 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr();
1138 completion->Signal(); 1119 completion->Signal();
1139 } 1120 }
1140 1121
1141 void ThreadProxy::InitializeOutputSurfaceOnImplThread( 1122 void ThreadProxy::InitializeOutputSurfaceOnImplThread(
1142 CompletionEvent* completion, 1123 CompletionEvent* completion,
1143 scoped_ptr<OutputSurface> output_surface, 1124 scoped_ptr<OutputSurface> output_surface,
1144 scoped_refptr<ContextProvider> offscreen_context_provider, 1125 scoped_refptr<ContextProvider> offscreen_context_provider,
1145 bool* success, 1126 bool* success,
1146 RendererCapabilities* capabilities) { 1127 RendererCapabilities* capabilities) {
1147 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread"); 1128 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
1148 DCHECK(IsImplThread()); 1129 DCHECK(IsImplThread());
1149 DCHECK(IsMainThreadBlocked()); 1130 DCHECK(IsMainThreadBlocked());
1150 DCHECK(success); 1131 DCHECK(success);
1151 DCHECK(capabilities); 1132 DCHECK(capabilities);
1152 1133
1153 layer_tree_host_->DeleteContentsTexturesOnImplThread( 1134 layer_tree_host_->DeleteContentsTexturesOnImplThread(
1154 layer_tree_host_impl_->resource_provider()); 1135 layer_tree_host_impl_->resource_provider());
1155 1136
1156 *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); 1137 *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
1157 1138
1158 if (*success) { 1139 if (*success) {
1159 *capabilities = layer_tree_host_impl_->GetRendererCapabilities(); 1140 *capabilities = layer_tree_host_impl_->GetRendererCapabilities();
1160
1161 OutputSurface* output_surface_ptr = layer_tree_host_impl_->output_surface();
1162 DCHECK(output_surface_ptr);
1163 int max_frames_pending =
1164 output_surface_ptr->capabilities().max_frames_pending;
1165 if (max_frames_pending <= 0)
1166 max_frames_pending = FrameRateController::DEFAULT_MAX_FRAMES_PENDING;
1167
1168 scheduler_on_impl_thread_->SetMaxFramesPending(max_frames_pending);
1169
1170 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); 1141 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
1171 } 1142 }
1172 1143
1173 DidTryInitializeRendererOnImplThread(*success, offscreen_context_provider); 1144 DidTryInitializeRendererOnImplThread(*success, offscreen_context_provider);
1174 1145
1175 completion->Signal(); 1146 completion->Signal();
1176 } 1147 }
1177 1148
1178 void ThreadProxy::DidTryInitializeRendererOnImplThread( 1149 void ThreadProxy::DidTryInitializeRendererOnImplThread(
1179 bool success, 1150 bool success,
(...skipping 24 matching lines...) Expand all
1204 1175
1205 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) { 1176 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
1206 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread"); 1177 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
1207 DCHECK(IsImplThread()); 1178 DCHECK(IsImplThread());
1208 layer_tree_host_->DeleteContentsTexturesOnImplThread( 1179 layer_tree_host_->DeleteContentsTexturesOnImplThread(
1209 layer_tree_host_impl_->resource_provider()); 1180 layer_tree_host_impl_->resource_provider());
1210 layer_tree_host_impl_->SetNeedsBeginFrame(false); 1181 layer_tree_host_impl_->SetNeedsBeginFrame(false);
1211 scheduler_on_impl_thread_.reset(); 1182 scheduler_on_impl_thread_.reset();
1212 layer_tree_host_impl_.reset(); 1183 layer_tree_host_impl_.reset();
1213 weak_factory_on_impl_thread_.InvalidateWeakPtrs(); 1184 weak_factory_on_impl_thread_.InvalidateWeakPtrs();
1214 vsync_client_ = NULL;
1215 completion->Signal(); 1185 completion->Signal();
1216 } 1186 }
1217 1187
1218 size_t ThreadProxy::MaxPartialTextureUpdates() const { 1188 size_t ThreadProxy::MaxPartialTextureUpdates() const {
1219 return ResourceUpdateController::MaxPartialTextureUpdates(); 1189 return ResourceUpdateController::MaxPartialTextureUpdates();
1220 } 1190 }
1221 1191
1222 ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState() 1192 ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState()
1223 : memory_allocation_limit_bytes(0) {} 1193 : memory_allocation_limit_bytes(0) {}
1224 1194
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 void ThreadProxy::CommitPendingOnImplThreadForTesting( 1234 void ThreadProxy::CommitPendingOnImplThreadForTesting(
1265 CommitPendingRequest* request) { 1235 CommitPendingRequest* request) {
1266 DCHECK(IsImplThread()); 1236 DCHECK(IsImplThread());
1267 if (layer_tree_host_impl_->output_surface()) 1237 if (layer_tree_host_impl_->output_surface())
1268 request->commit_pending = scheduler_on_impl_thread_->CommitPending(); 1238 request->commit_pending = scheduler_on_impl_thread_->CommitPending();
1269 else 1239 else
1270 request->commit_pending = false; 1240 request->commit_pending = false;
1271 request->completion.Signal(); 1241 request->completion.Signal();
1272 } 1242 }
1273 1243
1244 std::string ThreadProxy::SchedulerStateAsStringForTesting() {
1245 if (IsImplThread())
1246 return scheduler_on_impl_thread_->StateAsStringForTesting();
1247
1248 SchedulerStateRequest scheduler_state_request;
1249 {
1250 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1251 Proxy::ImplThread()->PostTask(
1252 base::Bind(&ThreadProxy::SchedulerStateAsStringOnImplThreadForTesting,
1253 impl_thread_weak_ptr_,
1254 &scheduler_state_request));
1255 scheduler_state_request.completion.Wait();
1256 }
1257 return scheduler_state_request.state;
1258 }
1259
1260 void ThreadProxy::SchedulerStateAsStringOnImplThreadForTesting(
1261 SchedulerStateRequest* request) {
1262 DCHECK(IsImplThread());
1263 request->state = scheduler_on_impl_thread_->StateAsStringForTesting();
1264 request->completion.Signal();
1265 }
1266
1274 skia::RefPtr<SkPicture> ThreadProxy::CapturePicture() { 1267 skia::RefPtr<SkPicture> ThreadProxy::CapturePicture() {
1275 DCHECK(IsMainThread()); 1268 DCHECK(IsMainThread());
1276 CompletionEvent completion; 1269 CompletionEvent completion;
1277 skia::RefPtr<SkPicture> picture; 1270 skia::RefPtr<SkPicture> picture;
1278 { 1271 {
1279 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 1272 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1280 Proxy::ImplThread()->PostTask( 1273 Proxy::ImplThread()->PostTask(
1281 base::Bind(&ThreadProxy::CapturePictureOnImplThread, 1274 base::Bind(&ThreadProxy::CapturePictureOnImplThread,
1282 impl_thread_weak_ptr_, 1275 impl_thread_weak_ptr_,
1283 &completion, 1276 &completion,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 !layer_tree_host_impl_->pending_tree()) { 1369 !layer_tree_host_impl_->pending_tree()) {
1377 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation", 1370 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
1378 TRACE_EVENT_SCOPE_THREAD); 1371 TRACE_EVENT_SCOPE_THREAD);
1379 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); 1372 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1380 completion_event_for_commit_held_on_tree_activation_->Signal(); 1373 completion_event_for_commit_held_on_tree_activation_->Signal();
1381 completion_event_for_commit_held_on_tree_activation_ = NULL; 1374 completion_event_for_commit_held_on_tree_activation_ = NULL;
1382 } 1375 }
1383 } 1376 }
1384 1377
1385 } // namespace cc 1378 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/thread_proxy.h ('k') | chrome/test/perf/rendering/latency_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698