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

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

Issue 16833003: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: 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 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 DCHECK(IsImplThread()); 1105 DCHECK(IsImplThread());
1104 *has_initialized_output_surface = 1106 *has_initialized_output_surface =
1105 scheduler_on_impl_thread_->HasInitializedOutputSurface(); 1107 scheduler_on_impl_thread_->HasInitializedOutputSurface();
1106 completion->Signal(); 1108 completion->Signal();
1107 } 1109 }
1108 1110
1109 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { 1111 void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
1110 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); 1112 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
1111 DCHECK(IsImplThread()); 1113 DCHECK(IsImplThread());
1112 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); 1114 layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
1113 const base::TimeDelta display_refresh_interval =
1114 base::TimeDelta::FromMicroseconds(
1115 base::Time::kMicrosecondsPerSecond /
1116 layer_tree_host_->settings().refresh_rate);
1117 scoped_ptr<FrameRateController> frame_rate_controller;
1118 if (throttle_frame_production_) {
1119 if (begin_frame_scheduling_enabled_) {
1120 frame_rate_controller.reset(
1121 new FrameRateController(VSyncTimeSource::Create(
1122 this,
1123 using_synchronous_renderer_compositor_ ?
1124 VSyncTimeSource::DISABLE_SYNCHRONOUSLY :
1125 VSyncTimeSource::DISABLE_ON_NEXT_TICK)));
1126 } else {
1127 frame_rate_controller.reset(
1128 new FrameRateController(DelayBasedTimeSource::Create(
1129 display_refresh_interval, Proxy::ImplThread())));
1130 }
1131 } else {
1132 frame_rate_controller.reset(new FrameRateController(Proxy::ImplThread()));
1133 }
1134 const LayerTreeSettings& settings = layer_tree_host_->settings(); 1115 const LayerTreeSettings& settings = layer_tree_host_->settings();
1135 SchedulerSettings scheduler_settings; 1116 SchedulerSettings scheduler_settings;
1136 scheduler_settings.impl_side_painting = settings.impl_side_painting; 1117 scheduler_settings.impl_side_painting = settings.impl_side_painting;
1137 scheduler_settings.timeout_and_draw_when_animation_checkerboards = 1118 scheduler_settings.timeout_and_draw_when_animation_checkerboards =
1138 settings.timeout_and_draw_when_animation_checkerboards; 1119 settings.timeout_and_draw_when_animation_checkerboards;
1139 scheduler_on_impl_thread_ = Scheduler::Create(this, 1120 scheduler_settings.using_synchronous_renderer_compositor =
1140 frame_rate_controller.Pass(), 1121 settings.using_synchronous_renderer_compositor;
1141 scheduler_settings); 1122 scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings);
1142 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); 1123 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
1143 1124
1144 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr(); 1125 impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr();
1145 completion->Signal(); 1126 completion->Signal();
1146 } 1127 }
1147 1128
1148 void ThreadProxy::InitializeOutputSurfaceOnImplThread( 1129 void ThreadProxy::InitializeOutputSurfaceOnImplThread(
1149 CompletionEvent* completion, 1130 CompletionEvent* completion,
1150 scoped_ptr<OutputSurface> output_surface, 1131 scoped_ptr<OutputSurface> output_surface,
1151 scoped_refptr<ContextProvider> offscreen_context_provider, 1132 scoped_refptr<ContextProvider> offscreen_context_provider,
1152 bool* success, 1133 bool* success,
1153 RendererCapabilities* capabilities) { 1134 RendererCapabilities* capabilities) {
1154 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread"); 1135 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
1155 DCHECK(IsImplThread()); 1136 DCHECK(IsImplThread());
1156 DCHECK(IsMainThreadBlocked()); 1137 DCHECK(IsMainThreadBlocked());
1157 DCHECK(success); 1138 DCHECK(success);
1158 DCHECK(capabilities); 1139 DCHECK(capabilities);
1159 1140
1160 layer_tree_host_->DeleteContentsTexturesOnImplThread( 1141 layer_tree_host_->DeleteContentsTexturesOnImplThread(
1161 layer_tree_host_impl_->resource_provider()); 1142 layer_tree_host_impl_->resource_provider());
1162 1143
1163 *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); 1144 *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
1164 1145
1165 if (*success) { 1146 if (*success) {
1166 *capabilities = layer_tree_host_impl_->GetRendererCapabilities(); 1147 *capabilities = layer_tree_host_impl_->GetRendererCapabilities();
1167
1168 OutputSurface* output_surface_ptr = layer_tree_host_impl_->output_surface();
1169 DCHECK(output_surface_ptr);
1170 int max_frames_pending =
1171 output_surface_ptr->capabilities().max_frames_pending;
1172 if (max_frames_pending <= 0)
1173 max_frames_pending = FrameRateController::DEFAULT_MAX_FRAMES_PENDING;
1174
1175 scheduler_on_impl_thread_->SetMaxFramesPending(max_frames_pending);
1176
1177 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); 1148 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
1178 } 1149 }
1179 1150
1180 DidTryInitializeRendererOnImplThread(*success, offscreen_context_provider); 1151 DidTryInitializeRendererOnImplThread(*success, offscreen_context_provider);
1181 1152
1182 completion->Signal(); 1153 completion->Signal();
1183 } 1154 }
1184 1155
1185 void ThreadProxy::DidTryInitializeRendererOnImplThread( 1156 void ThreadProxy::DidTryInitializeRendererOnImplThread(
1186 bool success, 1157 bool success,
(...skipping 24 matching lines...) Expand all
1211 1182
1212 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) { 1183 void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
1213 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread"); 1184 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
1214 DCHECK(IsImplThread()); 1185 DCHECK(IsImplThread());
1215 layer_tree_host_->DeleteContentsTexturesOnImplThread( 1186 layer_tree_host_->DeleteContentsTexturesOnImplThread(
1216 layer_tree_host_impl_->resource_provider()); 1187 layer_tree_host_impl_->resource_provider());
1217 layer_tree_host_impl_->SetNeedsBeginFrame(false); 1188 layer_tree_host_impl_->SetNeedsBeginFrame(false);
1218 scheduler_on_impl_thread_.reset(); 1189 scheduler_on_impl_thread_.reset();
1219 layer_tree_host_impl_.reset(); 1190 layer_tree_host_impl_.reset();
1220 weak_factory_on_impl_thread_.InvalidateWeakPtrs(); 1191 weak_factory_on_impl_thread_.InvalidateWeakPtrs();
1221 vsync_client_ = NULL;
1222 completion->Signal(); 1192 completion->Signal();
1223 } 1193 }
1224 1194
1225 size_t ThreadProxy::MaxPartialTextureUpdates() const { 1195 size_t ThreadProxy::MaxPartialTextureUpdates() const {
1226 return ResourceUpdateController::MaxPartialTextureUpdates(); 1196 return ResourceUpdateController::MaxPartialTextureUpdates();
1227 } 1197 }
1228 1198
1229 ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState() 1199 ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState()
1230 : memory_allocation_limit_bytes(0) {} 1200 : memory_allocation_limit_bytes(0) {}
1231 1201
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 void ThreadProxy::CommitPendingOnImplThreadForTesting( 1241 void ThreadProxy::CommitPendingOnImplThreadForTesting(
1272 CommitPendingRequest* request) { 1242 CommitPendingRequest* request) {
1273 DCHECK(IsImplThread()); 1243 DCHECK(IsImplThread());
1274 if (layer_tree_host_impl_->output_surface()) 1244 if (layer_tree_host_impl_->output_surface())
1275 request->commit_pending = scheduler_on_impl_thread_->CommitPending(); 1245 request->commit_pending = scheduler_on_impl_thread_->CommitPending();
1276 else 1246 else
1277 request->commit_pending = false; 1247 request->commit_pending = false;
1278 request->completion.Signal(); 1248 request->completion.Signal();
1279 } 1249 }
1280 1250
1251 std::string ThreadProxy::SchedulerStateAsStringForTesting() {
1252 if (IsImplThread())
1253 return scheduler_on_impl_thread_->StateAsStringForTesting();
1254
1255 SchedulerStateRequest scheduler_state_request;
1256 {
1257 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1258 Proxy::ImplThread()->PostTask(
1259 base::Bind(&ThreadProxy::SchedulerStateAsStringOnImplThreadForTesting,
1260 impl_thread_weak_ptr_,
1261 &scheduler_state_request));
1262 scheduler_state_request.completion.Wait();
1263 }
1264 return scheduler_state_request.state;
1265 }
1266
1267 void ThreadProxy::SchedulerStateAsStringOnImplThreadForTesting(
1268 SchedulerStateRequest* request) {
1269 DCHECK(IsImplThread());
1270 request->state = scheduler_on_impl_thread_->StateAsStringForTesting();
1271 request->completion.Signal();
1272 }
1273
1281 skia::RefPtr<SkPicture> ThreadProxy::CapturePicture() { 1274 skia::RefPtr<SkPicture> ThreadProxy::CapturePicture() {
1282 DCHECK(IsMainThread()); 1275 DCHECK(IsMainThread());
1283 CompletionEvent completion; 1276 CompletionEvent completion;
1284 skia::RefPtr<SkPicture> picture; 1277 skia::RefPtr<SkPicture> picture;
1285 { 1278 {
1286 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 1279 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
1287 Proxy::ImplThread()->PostTask( 1280 Proxy::ImplThread()->PostTask(
1288 base::Bind(&ThreadProxy::CapturePictureOnImplThread, 1281 base::Bind(&ThreadProxy::CapturePictureOnImplThread,
1289 impl_thread_weak_ptr_, 1282 impl_thread_weak_ptr_,
1290 &completion, 1283 &completion,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 !layer_tree_host_impl_->pending_tree()) { 1376 !layer_tree_host_impl_->pending_tree()) {
1384 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation", 1377 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
1385 TRACE_EVENT_SCOPE_THREAD); 1378 TRACE_EVENT_SCOPE_THREAD);
1386 DCHECK(layer_tree_host_impl_->settings().impl_side_painting); 1379 DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
1387 completion_event_for_commit_held_on_tree_activation_->Signal(); 1380 completion_event_for_commit_held_on_tree_activation_->Signal();
1388 completion_event_for_commit_held_on_tree_activation_ = NULL; 1381 completion_event_for_commit_held_on_tree_activation_ = NULL;
1389 } 1382 }
1390 } 1383 }
1391 1384
1392 } // namespace cc 1385 } // 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