OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "services/gfx/compositor/compositor_engine.h" | 5 #include "services/gfx/compositor/compositor_engine.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <sstream> | 8 #include <sstream> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "base/trace_event/trace_event.h" |
14 #include "mojo/services/gfx/composition/cpp/formatting.h" | 15 #include "mojo/services/gfx/composition/cpp/formatting.h" |
15 #include "mojo/skia/type_converters.h" | 16 #include "mojo/skia/type_converters.h" |
16 #include "services/gfx/compositor/backend/gpu_output.h" | 17 #include "services/gfx/compositor/backend/gpu_output.h" |
17 #include "services/gfx/compositor/graph/snapshot.h" | 18 #include "services/gfx/compositor/graph/snapshot.h" |
18 #include "services/gfx/compositor/render/render_frame.h" | 19 #include "services/gfx/compositor/render/render_frame.h" |
19 #include "services/gfx/compositor/renderer_impl.h" | 20 #include "services/gfx/compositor/renderer_impl.h" |
20 #include "services/gfx/compositor/scene_impl.h" | 21 #include "services/gfx/compositor/scene_impl.h" |
21 | 22 |
22 namespace compositor { | 23 namespace compositor { |
23 namespace { | 24 namespace { |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 base::Unretained(this), base::Unretained(scene_state)), | 344 base::Unretained(this), base::Unretained(scene_state)), |
344 errs); | 345 errs); |
345 if (disposition == SceneDef::Disposition::kFailed) { | 346 if (disposition == SceneDef::Disposition::kFailed) { |
346 LOG(ERROR) << "Scene published invalid updates: scene=" << scene_state; | 347 LOG(ERROR) << "Scene published invalid updates: scene=" << scene_state; |
347 LOG(ERROR) << errs.str(); | 348 LOG(ERROR) << errs.str(); |
348 // Caller is responsible for destroying the scene. | 349 // Caller is responsible for destroying the scene. |
349 } | 350 } |
350 return disposition; | 351 return disposition; |
351 } | 352 } |
352 | 353 |
| 354 void CompositorEngine::ComposeRenderer( |
| 355 RendererState* renderer_state, |
| 356 const mojo::gfx::composition::FrameInfo& frame_info) { |
| 357 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
| 358 DVLOG(2) << "ComposeRenderer: renderer_state=" << renderer_state; |
| 359 |
| 360 TRACE_EVENT1("gfx", "CompositorEngine::ComposeRenderer", "renderer", |
| 361 renderer_state->FormattedLabel()); |
| 362 |
| 363 int64_t composition_time = MojoGetTimeTicksNow(); |
| 364 PresentRenderer(renderer_state, frame_info.presentation_time); |
| 365 SnapshotRenderer(renderer_state); |
| 366 PaintRenderer(renderer_state, frame_info, composition_time); |
| 367 } |
| 368 |
353 void CompositorEngine::PresentRenderer(RendererState* renderer_state, | 369 void CompositorEngine::PresentRenderer(RendererState* renderer_state, |
354 int64_t presentation_time) { | 370 int64_t presentation_time) { |
355 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); | 371 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
356 DVLOG(2) << "PresentRenderer: renderer_state=" << renderer_state; | 372 DVLOG(2) << "PresentRenderer: renderer_state=" << renderer_state; |
357 | 373 |
| 374 TRACE_EVENT1("gfx", "CompositorEngine::PresentRenderer", "renderer", |
| 375 renderer_state->FormattedLabel()); |
| 376 |
358 // TODO(jeffbrown): Be more selective and do this work only for scenes | 377 // TODO(jeffbrown): Be more selective and do this work only for scenes |
359 // associated with the renderer that actually have pending updates. | 378 // associated with the renderer that actually have pending updates. |
360 std::vector<SceneState*> dead_scenes; | 379 std::vector<SceneState*> dead_scenes; |
361 for (auto& pair : scenes_by_token_) { | 380 for (auto& pair : scenes_by_token_) { |
362 SceneState* scene_state = pair.second; | 381 SceneState* scene_state = pair.second; |
363 SceneDef::Disposition disposition = | 382 SceneDef::Disposition disposition = |
364 PresentScene(scene_state, presentation_time); | 383 PresentScene(scene_state, presentation_time); |
365 if (disposition == SceneDef::Disposition::kFailed) | 384 if (disposition == SceneDef::Disposition::kFailed) |
366 dead_scenes.push_back(scene_state); | 385 dead_scenes.push_back(scene_state); |
367 } | 386 } |
368 for (SceneState* scene_state : dead_scenes) | 387 for (SceneState* scene_state : dead_scenes) |
369 DestroyScene(scene_state); | 388 DestroyScene(scene_state); |
370 } | 389 } |
371 | 390 |
372 void CompositorEngine::SnapshotRenderer( | 391 void CompositorEngine::SnapshotRenderer(RendererState* renderer_state) { |
373 RendererState* renderer_state, | |
374 const mojo::gfx::composition::FrameInfo& frame_info) { | |
375 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); | 392 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
376 DVLOG(2) << "SnapshotRenderer: renderer_state=" << renderer_state; | 393 DVLOG(2) << "SnapshotRenderer: renderer_state=" << renderer_state; |
377 | 394 |
| 395 TRACE_EVENT1("gfx", "CompositorEngine::SnapshotRenderer", "renderer", |
| 396 renderer_state->FormattedLabel()); |
| 397 |
378 if (VLOG_IS_ON(2)) { | 398 if (VLOG_IS_ON(2)) { |
379 std::ostringstream block_log; | 399 std::ostringstream block_log; |
380 SnapshotRendererInner(renderer_state, &block_log); | 400 SnapshotRendererInner(renderer_state, &block_log); |
381 if (!renderer_state->current_snapshot() || | 401 if (!renderer_state->current_snapshot() || |
382 renderer_state->current_snapshot()->is_blocked()) { | 402 renderer_state->current_snapshot()->is_blocked()) { |
383 DVLOG(2) << "Rendering completely blocked:" << std::endl | 403 DVLOG(2) << "Rendering completely blocked:" << std::endl |
384 << block_log.str(); | 404 << block_log.str(); |
385 } else if (!block_log.str().empty()) { | 405 } else if (!block_log.str().empty()) { |
386 DVLOG(2) << "Rendering partially blocked:" << std::endl | 406 DVLOG(2) << "Rendering partially blocked:" << std::endl |
387 << block_log.str(); | 407 << block_log.str(); |
388 } else { | 408 } else { |
389 DVLOG(2) << "Rendering unblocked"; | 409 DVLOG(2) << "Rendering unblocked"; |
390 } | 410 } |
391 } else { | 411 } else { |
392 SnapshotRendererInner(renderer_state, nullptr); | 412 SnapshotRendererInner(renderer_state, nullptr); |
393 } | 413 } |
394 | |
395 if (renderer_state->visible_snapshot()) { | |
396 DCHECK(!renderer_state->visible_snapshot()->is_blocked()); | |
397 renderer_state->output()->SubmitFrame( | |
398 renderer_state->visible_snapshot()->CreateFrame( | |
399 renderer_state->root_scene_viewport(), frame_info)); | |
400 } else { | |
401 SkIRect viewport = renderer_state->root_scene_viewport().To<SkIRect>(); | |
402 if (!viewport.isEmpty()) { | |
403 renderer_state->output()->SubmitFrame( | |
404 new RenderFrame(viewport, frame_info)); | |
405 } | |
406 } | |
407 } | 414 } |
408 | 415 |
409 void CompositorEngine::SnapshotRendererInner(RendererState* renderer_state, | 416 void CompositorEngine::SnapshotRendererInner(RendererState* renderer_state, |
410 std::ostream* block_log) { | 417 std::ostream* block_log) { |
411 if (!renderer_state->root_scene()) { | 418 if (!renderer_state->root_scene()) { |
412 if (block_log) | 419 if (block_log) |
413 *block_log << "No root scene" << std::endl; | 420 *block_log << "No root scene" << std::endl; |
414 renderer_state->SetSnapshot(nullptr); | 421 renderer_state->SetSnapshot(nullptr); |
415 return; | 422 return; |
416 } | 423 } |
417 | 424 |
418 renderer_state->SetSnapshot( | 425 renderer_state->SetSnapshot( |
419 universe_.SnapshotScene(renderer_state->root_scene()->scene_token(), | 426 universe_.SnapshotScene(renderer_state->root_scene()->scene_token(), |
420 renderer_state->root_scene_version(), block_log)); | 427 renderer_state->root_scene_version(), block_log)); |
421 } | 428 } |
422 | 429 |
| 430 void CompositorEngine::PaintRenderer( |
| 431 RendererState* renderer_state, |
| 432 const mojo::gfx::composition::FrameInfo& frame_info, |
| 433 int64_t composition_time) { |
| 434 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
| 435 DVLOG(2) << "PaintRenderer: renderer_state=" << renderer_state; |
| 436 |
| 437 TRACE_EVENT1("gfx", "CompositorEngine::PaintRenderer", "renderer", |
| 438 renderer_state->FormattedLabel()); |
| 439 |
| 440 RenderFrame::Metadata frame_metadata(frame_info, composition_time); |
| 441 |
| 442 if (renderer_state->visible_snapshot()) { |
| 443 // The renderer has snapshotted content; paint and submit it. |
| 444 DCHECK(!renderer_state->visible_snapshot()->is_blocked()); |
| 445 renderer_state->output()->SubmitFrame( |
| 446 renderer_state->visible_snapshot()->Paint( |
| 447 frame_metadata, renderer_state->root_scene_viewport())); |
| 448 } else { |
| 449 // The renderer does not have any content; submit an empty (black) frame. |
| 450 SkIRect viewport = renderer_state->root_scene_viewport().To<SkIRect>(); |
| 451 if (!viewport.isEmpty()) { |
| 452 renderer_state->output()->SubmitFrame( |
| 453 new RenderFrame(frame_metadata, viewport)); |
| 454 } |
| 455 } |
| 456 } |
| 457 |
423 void CompositorEngine::ScheduleFrameForRenderer( | 458 void CompositorEngine::ScheduleFrameForRenderer( |
424 RendererState* renderer_state, | 459 RendererState* renderer_state, |
425 Scheduler::SchedulingMode scheduling_mode) { | 460 Scheduler::SchedulingMode scheduling_mode) { |
426 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); | 461 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
427 renderer_state->output()->GetScheduler()->ScheduleFrame(scheduling_mode); | 462 renderer_state->output()->GetScheduler()->ScheduleFrame(scheduling_mode); |
428 } | 463 } |
429 | 464 |
430 void CompositorEngine::OnOutputError( | 465 void CompositorEngine::OnOutputError( |
431 const base::WeakPtr<RendererState>& renderer_state_weak) { | 466 const base::WeakPtr<RendererState>& renderer_state_weak) { |
432 RendererState* renderer_state = renderer_state_weak.get(); | 467 RendererState* renderer_state = renderer_state_weak.get(); |
(...skipping 23 matching lines...) Expand all Loading... |
456 } | 491 } |
457 | 492 |
458 void CompositorEngine::OnOutputSnapshotRequest( | 493 void CompositorEngine::OnOutputSnapshotRequest( |
459 const base::WeakPtr<RendererState>& renderer_state_weak, | 494 const base::WeakPtr<RendererState>& renderer_state_weak, |
460 const mojo::gfx::composition::FrameInfo& frame_info) { | 495 const mojo::gfx::composition::FrameInfo& frame_info) { |
461 RendererState* renderer_state = renderer_state_weak.get(); | 496 RendererState* renderer_state = renderer_state_weak.get(); |
462 if (!renderer_state) | 497 if (!renderer_state) |
463 return; | 498 return; |
464 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); | 499 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
465 | 500 |
466 PresentRenderer(renderer_state, frame_info.presentation_time); | 501 ComposeRenderer(renderer_state, frame_info); |
467 SnapshotRenderer(renderer_state, frame_info); | |
468 } | 502 } |
469 | 503 |
470 void CompositorEngine::OnPresentScene( | 504 void CompositorEngine::OnPresentScene( |
471 const base::WeakPtr<SceneState>& scene_state_weak, | 505 const base::WeakPtr<SceneState>& scene_state_weak, |
472 int64_t presentation_time) { | 506 int64_t presentation_time) { |
473 SceneState* scene_state = scene_state_weak.get(); | 507 SceneState* scene_state = scene_state_weak.get(); |
474 if (!scene_state) | 508 if (!scene_state) |
475 return; | 509 return; |
476 DCHECK(IsSceneStateRegisteredDebug(scene_state)); | 510 DCHECK(IsSceneStateRegisteredDebug(scene_state)); |
477 | 511 |
478 SceneDef::Disposition disposition = | 512 SceneDef::Disposition disposition = |
479 PresentScene(scene_state, presentation_time); | 513 PresentScene(scene_state, presentation_time); |
480 if (disposition == SceneDef::Disposition::kFailed) | 514 if (disposition == SceneDef::Disposition::kFailed) |
481 DestroyScene(scene_state); | 515 DestroyScene(scene_state); |
482 else if (disposition == SceneDef::Disposition::kSucceeded) | 516 else if (disposition == SceneDef::Disposition::kSucceeded) |
483 InvalidateScene(scene_state); | 517 InvalidateScene(scene_state); |
484 } | 518 } |
485 | 519 |
486 } // namespace compositor | 520 } // namespace compositor |
OLD | NEW |