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

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

Issue 344743002: Make Android CompositorImpl use scheduled SingleThreadProxy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | 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/compositor_impl_android.h" 5 #include "content/browser/renderer_host/compositor_impl_android.h"
6 6
7 #include <android/bitmap.h> 7 #include <android/bitmap.h>
8 #include <android/native_window_jni.h> 8 #include <android/native_window_jni.h>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 187
188 CompositorImpl::CompositorImpl(CompositorClient* client, 188 CompositorImpl::CompositorImpl(CompositorClient* client,
189 gfx::NativeWindow root_window) 189 gfx::NativeWindow root_window)
190 : root_layer_(cc::Layer::Create()), 190 : root_layer_(cc::Layer::Create()),
191 has_transparent_background_(false), 191 has_transparent_background_(false),
192 device_scale_factor_(1), 192 device_scale_factor_(1),
193 window_(NULL), 193 window_(NULL),
194 surface_id_(0), 194 surface_id_(0),
195 client_(client), 195 client_(client),
196 root_window_(root_window), 196 root_window_(root_window),
197 did_post_swapbuffers_(false), 197 pending_swapbuffers_(0),
198 ignore_schedule_composite_(false),
199 needs_composite_(false),
200 needs_animate_(false),
201 will_composite_immediately_(false),
202 composite_on_vsync_trigger_(DO_NOT_COMPOSITE),
203 pending_swapbuffers_(0U),
204 weak_factory_(this) { 198 weak_factory_(this) {
205 DCHECK(client); 199 DCHECK(client);
206 DCHECK(root_window); 200 DCHECK(root_window);
207 ImageTransportFactoryAndroid::AddObserver(this); 201 ImageTransportFactoryAndroid::AddObserver(this);
208 root_window->AttachCompositor(this); 202 root_window->AttachCompositor(this);
209 } 203 }
210 204
211 CompositorImpl::~CompositorImpl() { 205 CompositorImpl::~CompositorImpl() {
212 root_window_->DetachCompositor(); 206 root_window_->DetachCompositor();
213 ImageTransportFactoryAndroid::RemoveObserver(this); 207 ImageTransportFactoryAndroid::RemoveObserver(this);
214 // Clean-up any surface references. 208 // Clean-up any surface references.
215 SetSurface(NULL); 209 SetSurface(NULL);
216 } 210 }
217 211
218 void CompositorImpl::PostComposite(CompositingTrigger trigger) {
219 DCHECK(needs_composite_);
220 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY);
221
222 if (will_composite_immediately_ ||
223 (trigger == COMPOSITE_EVENTUALLY && WillComposite())) {
224 // We will already composite soon enough.
225 DCHECK(WillComposite());
226 return;
227 }
228
229 if (DidCompositeThisFrame()) {
230 DCHECK(!WillCompositeThisFrame());
231 if (composite_on_vsync_trigger_ != COMPOSITE_IMMEDIATELY) {
232 composite_on_vsync_trigger_ = trigger;
233 root_window_->RequestVSyncUpdate();
234 }
235 DCHECK(WillComposite());
236 return;
237 }
238
239 base::TimeDelta delay;
240 if (trigger == COMPOSITE_IMMEDIATELY) {
241 will_composite_immediately_ = true;
242 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE;
243 } else {
244 DCHECK(!WillComposite());
245 const base::TimeDelta estimated_composite_time = vsync_period_ / 4;
246 const base::TimeTicks now = base::TimeTicks::Now();
247
248 if (!last_vsync_.is_null() && (now - last_vsync_) < vsync_period_) {
249 base::TimeTicks next_composite =
250 last_vsync_ + vsync_period_ - estimated_composite_time;
251 if (next_composite < now) {
252 // It's too late, we will reschedule composite as needed on the next
253 // vsync.
254 composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY;
255 root_window_->RequestVSyncUpdate();
256 DCHECK(WillComposite());
257 return;
258 }
259
260 delay = next_composite - now;
261 }
262 }
263 TRACE_EVENT2("cc", "CompositorImpl::PostComposite",
264 "trigger", trigger,
265 "delay", delay.InMillisecondsF());
266
267 DCHECK(composite_on_vsync_trigger_ == DO_NOT_COMPOSITE);
268 if (current_composite_task_)
269 current_composite_task_->Cancel();
270
271 // Unretained because we cancel the task on shutdown.
272 current_composite_task_.reset(new base::CancelableClosure(
273 base::Bind(&CompositorImpl::Composite, base::Unretained(this), trigger)));
274 base::MessageLoop::current()->PostDelayedTask(
275 FROM_HERE, current_composite_task_->callback(), delay);
276 }
277
278 void CompositorImpl::Composite(CompositingTrigger trigger) {
279 BrowserGpuChannelHostFactory* factory =
280 BrowserGpuChannelHostFactory::instance();
281 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) {
282 CauseForGpuLaunch cause =
283 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
284 factory->EstablishGpuChannel(
285 cause,
286 base::Bind(&CompositorImpl::OnGpuChannelEstablished,
287 weak_factory_.GetWeakPtr()));
288 return;
289 }
290
291 DCHECK(host_);
292 DCHECK(trigger == COMPOSITE_IMMEDIATELY || trigger == COMPOSITE_EVENTUALLY);
293 DCHECK(needs_composite_);
294 DCHECK(!DidCompositeThisFrame());
295
296 if (trigger == COMPOSITE_IMMEDIATELY)
297 will_composite_immediately_ = false;
298
299 DCHECK_LE(pending_swapbuffers_, kMaxSwapBuffers);
300 if (pending_swapbuffers_ == kMaxSwapBuffers) {
301 TRACE_EVENT0("compositor", "CompositorImpl_SwapLimit");
302 return;
303 }
304
305 // Reset state before Layout+Composite since that might create more
306 // requests to Composite that we need to respect.
307 needs_composite_ = false;
308
309 // Only allow compositing once per vsync.
310 current_composite_task_->Cancel();
311 DCHECK(DidCompositeThisFrame() && !WillComposite());
312
313 // Ignore ScheduleComposite() from layer tree changes during layout and
314 // animation updates that will already be reflected in the current frame
315 // we are about to draw.
316 ignore_schedule_composite_ = true;
317
318 const base::TimeTicks frame_time = gfx::FrameTime::Now();
319 if (needs_animate_) {
320 needs_animate_ = false;
321 root_window_->Animate(frame_time);
322 }
323 ignore_schedule_composite_ = false;
324
325 did_post_swapbuffers_ = false;
326 host_->Composite(frame_time);
327 if (did_post_swapbuffers_)
328 pending_swapbuffers_++;
329
330 // Need to track vsync to avoid compositing more than once per frame.
331 root_window_->RequestVSyncUpdate();
332 }
333
334 void CompositorImpl::OnGpuChannelEstablished() { 212 void CompositorImpl::OnGpuChannelEstablished() {
335 ScheduleComposite(); 213 if (host_)
214 host_->SetNeedsCommit();
brianderson 2014/06/24 23:50:12 Should this be SetNeedsRedraw? If this is meant to
danakj 2014/06/25 17:28:54 This should probably just go away?
336 } 215 }
337 216
338 UIResourceProvider& CompositorImpl::GetUIResourceProvider() { 217 UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
339 return ui_resource_provider_; 218 return ui_resource_provider_;
340 } 219 }
341 220
342 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) { 221 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
343 root_layer_->RemoveAllChildren(); 222 root_layer_->RemoveAllChildren();
344 if (root_layer) 223 if (root_layer)
345 root_layer_->AddChild(root_layer); 224 root_layer_->AddChild(root_layer);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 266 }
388 if (window) { 267 if (window) {
389 SetWindowSurface(window); 268 SetWindowSurface(window);
390 ANativeWindow_release(window); 269 ANativeWindow_release(window);
391 content::RegisterViewSurface(surface_id_, j_surface.obj()); 270 content::RegisterViewSurface(surface_id_, j_surface.obj());
392 } 271 }
393 } 272 }
394 273
395 void CompositorImpl::SetVisible(bool visible) { 274 void CompositorImpl::SetVisible(bool visible) {
396 if (!visible) { 275 if (!visible) {
397 if (WillComposite())
398 CancelComposite();
399 ui_resource_provider_.SetLayerTreeHost(NULL); 276 ui_resource_provider_.SetLayerTreeHost(NULL);
400 host_.reset(); 277 host_.reset();
401 } else if (!host_) { 278 } else if (!host_) {
402 DCHECK(!WillComposite());
403 needs_composite_ = false;
404 needs_animate_ = false;
405 pending_swapbuffers_ = 0; 279 pending_swapbuffers_ = 0;
406 cc::LayerTreeSettings settings; 280 cc::LayerTreeSettings settings;
407 settings.refresh_rate = 60.0; 281 settings.refresh_rate = 60.0;
408 settings.impl_side_painting = false; 282 settings.impl_side_painting = false;
409 settings.allow_antialiasing = false; 283 settings.allow_antialiasing = false;
410 settings.calculate_top_controls_position = false; 284 settings.calculate_top_controls_position = false;
411 settings.top_controls_height = 0.f; 285 settings.top_controls_height = 0.f;
412 settings.highp_threshold_min = 2048; 286 settings.highp_threshold_min = 2048;
no sievers 2014/06/19 17:49:21 If we set... settings.throttle_frame_production =
brianderson 2014/06/24 23:50:12 +1. I think DirectOutputSurface is now known as Ou
413 287
414 CommandLine* command_line = CommandLine::ForCurrentProcess(); 288 CommandLine* command_line = CommandLine::ForCurrentProcess();
415 settings.initial_debug_state.SetRecordRenderingStats( 289 settings.initial_debug_state.SetRecordRenderingStats(
416 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); 290 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
417 settings.initial_debug_state.show_fps_counter = 291 settings.initial_debug_state.show_fps_counter =
418 command_line->HasSwitch(cc::switches::kUIShowFPSCounter); 292 command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
419 // TODO(enne): Update this this compositor to use the scheduler.
420 settings.single_thread_proxy_scheduler = false;
421 293
422 host_ = cc::LayerTreeHost::CreateSingleThreaded( 294 host_ = cc::LayerTreeHost::CreateSingleThreaded(
423 this, this, HostSharedBitmapManager::current(), settings); 295 this, this, HostSharedBitmapManager::current(), settings);
424 host_->SetRootLayer(root_layer_); 296 host_->SetRootLayer(root_layer_);
425 297
426 host_->SetVisible(true); 298 host_->SetVisible(true);
427 host_->SetLayerTreeHostClientReady(); 299 host_->SetLayerTreeHostClientReady();
428 host_->SetViewportSize(size_); 300 host_->SetViewportSize(size_);
429 host_->set_has_transparent_background(has_transparent_background_); 301 host_->set_has_transparent_background(has_transparent_background_);
430 host_->SetDeviceScaleFactor(device_scale_factor_); 302 host_->SetDeviceScaleFactor(device_scale_factor_);
431 ui_resource_provider_.SetLayerTreeHost(host_.get()); 303 ui_resource_provider_.SetLayerTreeHost(host_.get());
304
305 BrowserGpuChannelHostFactory* factory =
306 BrowserGpuChannelHostFactory::instance();
307 if (!factory->GetGpuChannel() || factory->GetGpuChannel()->IsLost()) {
308 CauseForGpuLaunch cause =
309 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
310 factory->EstablishGpuChannel(
311 cause,
312 base::Bind(&CompositorImpl::OnGpuChannelEstablished,
313 weak_factory_.GetWeakPtr()));
no sievers 2014/06/19 17:13:26 We then need to defer the host_->SetLayerTreeHostC
314 }
432 } 315 }
433 } 316 }
434 317
435 void CompositorImpl::setDeviceScaleFactor(float factor) { 318 void CompositorImpl::setDeviceScaleFactor(float factor) {
436 device_scale_factor_ = factor; 319 device_scale_factor_ = factor;
437 if (host_) 320 if (host_)
438 host_->SetDeviceScaleFactor(factor); 321 host_->SetDeviceScaleFactor(factor);
439 } 322 }
440 323
441 void CompositorImpl::SetWindowBounds(const gfx::Size& size) { 324 void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
442 if (size_ == size) 325 if (size_ == size)
443 return; 326 return;
444 327
445 size_ = size; 328 size_ = size;
446 if (host_) 329 if (host_)
447 host_->SetViewportSize(size); 330 host_->SetViewportSize(size);
448 root_layer_->SetBounds(size); 331 root_layer_->SetBounds(size);
449 } 332 }
450 333
451 void CompositorImpl::SetHasTransparentBackground(bool flag) { 334 void CompositorImpl::SetHasTransparentBackground(bool flag) {
452 has_transparent_background_ = flag; 335 has_transparent_background_ = flag;
453 if (host_) 336 if (host_)
454 host_->set_has_transparent_background(flag); 337 host_->set_has_transparent_background(flag);
455 } 338 }
456 339
457 void CompositorImpl::SetNeedsComposite() { 340 void CompositorImpl::SetNeedsComposite() {
458 if (!host_.get()) 341 if (!host_.get())
459 return; 342 return;
460 DCHECK(!needs_composite_ || WillComposite()); 343 host_->SetNeedsCommit();
461
462 needs_composite_ = true;
463 PostComposite(COMPOSITE_IMMEDIATELY);
464 } 344 }
465 345
466 static scoped_ptr<WebGraphicsContext3DCommandBufferImpl> 346 static scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
467 CreateGpuProcessViewContext( 347 CreateGpuProcessViewContext(
468 const scoped_refptr<GpuChannelHost>& gpu_channel_host, 348 const scoped_refptr<GpuChannelHost>& gpu_channel_host,
469 const blink::WebGraphicsContext3D::Attributes attributes, 349 const blink::WebGraphicsContext3D::Attributes attributes,
470 int surface_id) { 350 int surface_id) {
471 DCHECK(gpu_channel_host); 351 DCHECK(gpu_channel_host);
472 352
473 GURL url("chrome://gpu/Compositor::createContext3D"); 353 GURL url("chrome://gpu/Compositor::createContext3D");
(...skipping 15 matching lines...) Expand all
489 new WebGraphicsContext3DCommandBufferImpl(surface_id, 369 new WebGraphicsContext3DCommandBufferImpl(surface_id,
490 url, 370 url,
491 gpu_channel_host.get(), 371 gpu_channel_host.get(),
492 attributes, 372 attributes,
493 lose_context_when_out_of_memory, 373 lose_context_when_out_of_memory,
494 limits, 374 limits,
495 NULL)); 375 NULL));
496 } 376 }
497 377
498 void CompositorImpl::Layout() { 378 void CompositorImpl::Layout() {
499 ignore_schedule_composite_ = true; 379 host_->SetDeferCommits(true);
500 client_->Layout(); 380 client_->Layout();
501 ignore_schedule_composite_ = false; 381 host_->SetDeferCommits(false);
502 } 382 }
503 383
504 scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface( 384 scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface(
505 bool fallback) { 385 bool fallback) {
506 blink::WebGraphicsContext3D::Attributes attrs; 386 blink::WebGraphicsContext3D::Attributes attrs;
507 attrs.shareResources = true; 387 attrs.shareResources = true;
508 attrs.noAutomaticFlushes = true; 388 attrs.noAutomaticFlushes = true;
509 pending_swapbuffers_ = 0; 389 pending_swapbuffers_ = 0;
510 390
511 DCHECK(window_); 391 DCHECK(window_);
(...skipping 15 matching lines...) Expand all
527 407
528 return scoped_ptr<cc::OutputSurface>( 408 return scoped_ptr<cc::OutputSurface>(
529 new OutputSurfaceWithoutParent(context_provider)); 409 new OutputSurfaceWithoutParent(context_provider));
530 } 410 }
531 411
532 void CompositorImpl::OnLostResources() { 412 void CompositorImpl::OnLostResources() {
533 client_->DidLoseResources(); 413 client_->DidLoseResources();
534 ui_resource_provider_.UIResourcesAreInvalid(); 414 ui_resource_provider_.UIResourcesAreInvalid();
535 } 415 }
536 416
537 void CompositorImpl::ScheduleComposite() {
538 DCHECK(!needs_composite_ || WillComposite());
539 if (ignore_schedule_composite_)
540 return;
541
542 needs_composite_ = true;
543 // We currently expect layer tree invalidations at most once per frame
544 // during normal operation and therefore try to composite immediately
545 // to minimize latency.
546 PostComposite(COMPOSITE_IMMEDIATELY);
547 }
548
549 void CompositorImpl::ScheduleAnimation() {
550 DCHECK(!needs_animate_ || needs_composite_);
551 DCHECK(!needs_composite_ || WillComposite());
552 needs_animate_ = true;
553
554 if (needs_composite_)
555 return;
556
557 TRACE_EVENT0("cc", "CompositorImpl::ScheduleAnimation");
558 needs_composite_ = true;
559 PostComposite(COMPOSITE_EVENTUALLY);
560 }
561
562 void CompositorImpl::DidPostSwapBuffers() { 417 void CompositorImpl::DidPostSwapBuffers() {
563 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers"); 418 TRACE_EVENT0("compositor", "CompositorImpl::DidPostSwapBuffers");
564 did_post_swapbuffers_ = true; 419 pending_swapbuffers_++;
565 } 420 }
566 421
567 void CompositorImpl::DidCompleteSwapBuffers() { 422 void CompositorImpl::DidCompleteSwapBuffers() {
568 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers"); 423 TRACE_EVENT0("compositor", "CompositorImpl::DidCompleteSwapBuffers");
569 DCHECK_GT(pending_swapbuffers_, 0U); 424 DCHECK_GT(pending_swapbuffers_, 0U);
570 if (pending_swapbuffers_-- == kMaxSwapBuffers && needs_composite_) 425 pending_swapbuffers_--;
571 PostComposite(COMPOSITE_IMMEDIATELY);
572 client_->OnSwapBuffersCompleted(pending_swapbuffers_); 426 client_->OnSwapBuffersCompleted(pending_swapbuffers_);
brianderson 2014/06/24 23:50:12 Can we get rid of pending_swapbuffers_? Implementa
no sievers 2014/06/25 00:03:26 There is one call site in Chrome for Android, wher
427
428 // TODO(enne): where does this go?
429 root_window_->RequestVSyncUpdate();
enne (OOO) 2014/06/19 01:09:27 This maybe could be in a better place.
no sievers 2014/06/19 17:49:21 ...then line 429 can go away here...
573 } 430 }
574 431
575 void CompositorImpl::DidAbortSwapBuffers() { 432 void CompositorImpl::DidAbortSwapBuffers() {
576 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers"); 433 TRACE_EVENT0("compositor", "CompositorImpl::DidAbortSwapBuffers");
577 // This really gets called only once from 434 // This really gets called only once from
578 // SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the 435 // SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the
579 // context was lost. 436 // context was lost.
580 ScheduleComposite();
581 client_->OnSwapBuffersCompleted(0); 437 client_->OnSwapBuffersCompleted(0);
582 } 438 }
583 439
584 void CompositorImpl::DidCommit() { 440 void CompositorImpl::DidCommit() {
585 root_window_->OnCompositingDidCommit(); 441 root_window_->OnCompositingDidCommit();
586 } 442 }
587 443
588 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { 444 void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) {
589 root_layer_->AddChild(layer); 445 root_layer_->AddChild(layer);
590 } 446 }
591 447
592 void CompositorImpl::RequestCopyOfOutputOnRootLayer( 448 void CompositorImpl::RequestCopyOfOutputOnRootLayer(
593 scoped_ptr<cc::CopyOutputRequest> request) { 449 scoped_ptr<cc::CopyOutputRequest> request) {
594 root_layer_->RequestCopyOfOutput(request.Pass()); 450 root_layer_->RequestCopyOfOutput(request.Pass());
595 } 451 }
596 452
597 void CompositorImpl::OnVSync(base::TimeTicks frame_time, 453 void CompositorImpl::OnVSync(base::TimeTicks frame_time,
598 base::TimeDelta vsync_period) { 454 base::TimeDelta vsync_period) {
599 vsync_period_ = vsync_period; 455 // TODO(enne): Does this need to get piped to output surface somehow?
enne (OOO) 2014/06/19 01:09:27 brianderson: I'm a little unclear about vsync para
no sievers 2014/06/19 17:49:21 ...and it would take care of the vsync scheduling.
brianderson 2014/06/24 23:50:12 Yes, that makes sense and is how the scheduler exp
600 last_vsync_ = frame_time;
601
602 if (WillCompositeThisFrame()) {
603 // We somehow missed the last vsync interval, so reschedule for deadline.
604 // We cannot schedule immediately, or will get us out-of-phase with new
605 // renderer frames.
606 CancelComposite();
607 composite_on_vsync_trigger_ = COMPOSITE_EVENTUALLY;
608 } else {
609 current_composite_task_.reset();
610 }
611
612 DCHECK(!DidCompositeThisFrame() && !WillCompositeThisFrame());
613 if (composite_on_vsync_trigger_ != DO_NOT_COMPOSITE) {
614 CompositingTrigger trigger = composite_on_vsync_trigger_;
615 composite_on_vsync_trigger_ = DO_NOT_COMPOSITE;
616 PostComposite(trigger);
617 }
618 } 456 }
619 457
620 void CompositorImpl::SetNeedsAnimate() { 458 void CompositorImpl::SetNeedsAnimate() {
621 if (!host_) 459 if (!host_)
622 return; 460 return;
623 461
624 host_->SetNeedsAnimate(); 462 host_->SetNeedsAnimate();
625 } 463 }
626 464
627 } // namespace content 465 } // namespace content
OLDNEW
« cc/trees/single_thread_proxy.cc ('K') | « content/browser/renderer_host/compositor_impl_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698