| 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 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 new SceneState(scene_token.Pass(), SanitizeLabel(label)); | 48 new SceneState(scene_token.Pass(), SanitizeLabel(label)); |
| 49 SceneImpl* scene_impl = | 49 SceneImpl* scene_impl = |
| 50 new SceneImpl(this, scene_state, scene_request.Pass()); | 50 new SceneImpl(this, scene_state, scene_request.Pass()); |
| 51 scene_state->set_scene_impl(scene_impl); | 51 scene_state->set_scene_impl(scene_impl); |
| 52 base::Closure error_handler = | 52 base::Closure error_handler = |
| 53 base::Bind(&CompositorEngine::OnSceneConnectionError, | 53 base::Bind(&CompositorEngine::OnSceneConnectionError, |
| 54 base::Unretained(this), scene_state); | 54 base::Unretained(this), scene_state); |
| 55 scene_impl->set_connection_error_handler(error_handler); | 55 scene_impl->set_connection_error_handler(error_handler); |
| 56 | 56 |
| 57 // Add to registry. | 57 // Add to registry. |
| 58 scenes_by_token_.insert({scene_state->scene_token()->value, scene_state}); | 58 scenes_by_token_.emplace(scene_state->scene_token().value, scene_state); |
| 59 universe_.AddScene(scene_state->scene_def()->label()); |
| 59 DVLOG(1) << "CreateScene: scene=" << scene_state; | 60 DVLOG(1) << "CreateScene: scene=" << scene_state; |
| 60 return scene_state->scene_token()->Clone(); | 61 return scene_state->scene_token().Clone(); |
| 61 } | 62 } |
| 62 | 63 |
| 63 void CompositorEngine::OnSceneConnectionError(SceneState* scene_state) { | 64 void CompositorEngine::OnSceneConnectionError(SceneState* scene_state) { |
| 64 DCHECK(IsSceneStateRegisteredDebug(scene_state)); | 65 DCHECK(IsSceneStateRegisteredDebug(scene_state)); |
| 65 DVLOG(1) << "OnSceneConnectionError: scene=" << scene_state; | 66 DVLOG(1) << "OnSceneConnectionError: scene=" << scene_state; |
| 66 | 67 |
| 67 DestroyScene(scene_state); | 68 DestroyScene(scene_state); |
| 68 } | 69 } |
| 69 | 70 |
| 70 void CompositorEngine::DestroyScene(SceneState* scene_state) { | 71 void CompositorEngine::DestroyScene(SceneState* scene_state) { |
| 71 DCHECK(IsSceneStateRegisteredDebug(scene_state)); | 72 DCHECK(IsSceneStateRegisteredDebug(scene_state)); |
| 72 DVLOG(1) << "DestroyScene: scene=" << scene_state; | 73 DVLOG(1) << "DestroyScene: scene=" << scene_state; |
| 73 | 74 |
| 74 // Unlink from other scenes. | 75 // Notify other scenes which may depend on this one. |
| 75 for (auto& pair : scenes_by_token_) { | 76 for (auto& pair : scenes_by_token_) { |
| 76 SceneState* other_scene_state = pair.second; | 77 SceneState* other_scene_state = pair.second; |
| 77 other_scene_state->scene_def()->UnlinkReferencedScene( | 78 other_scene_state->scene_def()->NotifySceneUnavailable( |
| 78 scene_state->scene_def(), | 79 scene_state->scene_token(), |
| 79 base::Bind(&CompositorEngine::SendResourceUnavailable, | 80 base::Bind(&CompositorEngine::SendResourceUnavailable, |
| 80 base::Unretained(this), | 81 base::Unretained(this), |
| 81 base::Unretained(other_scene_state))); | 82 base::Unretained(other_scene_state))); |
| 82 } | 83 } |
| 83 | 84 |
| 84 // Destroy any renderers using this scene. | 85 // Destroy any renderers using this scene. |
| 85 for (auto& renderer : renderers_) { | 86 for (auto& renderer : renderers_) { |
| 86 if (renderer->root_scene() == scene_state) { | 87 if (renderer->root_scene() == scene_state) { |
| 87 LOG(ERROR) << "Destroying renderer whose root scene has become " | 88 LOG(ERROR) << "Destroying renderer whose root scene has become " |
| 88 "unavailable: renderer=" | 89 "unavailable: renderer=" |
| 89 << renderer; | 90 << renderer; |
| 90 DestroyRenderer(renderer); | 91 DestroyRenderer(renderer); |
| 91 } | 92 } |
| 92 } | 93 } |
| 93 | 94 |
| 94 // Destroy. | 95 // Consider all dependent rendering to be invalidated. |
| 96 universe_.RemoveScene(scene_state->scene_token()); |
| 95 InvalidateScene(scene_state); | 97 InvalidateScene(scene_state); |
| 96 | 98 |
| 97 // Remove from registry. | 99 // Remove from registry. |
| 98 scenes_by_token_.erase(scene_state->scene_token()->value); | 100 scenes_by_token_.erase(scene_state->scene_token().value); |
| 99 delete scene_state; | 101 delete scene_state; |
| 100 } | 102 } |
| 101 | 103 |
| 102 void CompositorEngine::CreateRenderer( | 104 void CompositorEngine::CreateRenderer( |
| 103 mojo::InterfaceHandle<mojo::ContextProvider> context_provider, | 105 mojo::InterfaceHandle<mojo::ContextProvider> context_provider, |
| 104 mojo::InterfaceRequest<mojo::gfx::composition::Renderer> renderer_request, | 106 mojo::InterfaceRequest<mojo::gfx::composition::Renderer> renderer_request, |
| 105 const mojo::String& label) { | 107 const mojo::String& label) { |
| 106 DCHECK(context_provider); | 108 DCHECK(context_provider); |
| 107 uint32_t renderer_id = next_renderer_id_++; | 109 uint32_t renderer_id = next_renderer_id_++; |
| 108 CHECK(renderer_id); | 110 CHECK(renderer_id); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 auto result = mojo::gfx::composition::HitTestResult::New(); | 282 auto result = mojo::gfx::composition::HitTestResult::New(); |
| 281 | 283 |
| 282 if (renderer_state->visible_snapshot()) { | 284 if (renderer_state->visible_snapshot()) { |
| 283 DCHECK(!renderer_state->visible_snapshot()->is_blocked()); | 285 DCHECK(!renderer_state->visible_snapshot()->is_blocked()); |
| 284 renderer_state->visible_snapshot()->HitTest(*point, result.get()); | 286 renderer_state->visible_snapshot()->HitTest(*point, result.get()); |
| 285 } | 287 } |
| 286 | 288 |
| 287 callback.Run(result.Pass()); | 289 callback.Run(result.Pass()); |
| 288 } | 290 } |
| 289 | 291 |
| 290 base::WeakPtr<SceneDef> CompositorEngine::ResolveSceneReference( | 292 bool CompositorEngine::ResolveSceneReference( |
| 291 const mojo::gfx::composition::SceneToken& scene_token) { | 293 const mojo::gfx::composition::SceneToken& scene_token) { |
| 292 SceneState* scene_state = FindScene(scene_token.value); | 294 return FindScene(scene_token.value) != nullptr; |
| 293 return scene_state ? scene_state->scene_def()->GetWeakPtr() | |
| 294 : base::WeakPtr<SceneDef>(); | |
| 295 } | 295 } |
| 296 | 296 |
| 297 void CompositorEngine::SendResourceUnavailable(SceneState* scene_state, | 297 void CompositorEngine::SendResourceUnavailable(SceneState* scene_state, |
| 298 uint32_t resource_id) { | 298 uint32_t resource_id) { |
| 299 DCHECK(IsSceneStateRegisteredDebug(scene_state)); | 299 DCHECK(IsSceneStateRegisteredDebug(scene_state)); |
| 300 DVLOG(2) << "SendResourceUnavailable: resource_id=" << resource_id; | 300 DVLOG(2) << "SendResourceUnavailable: resource_id=" << resource_id; |
| 301 | 301 |
| 302 // TODO: Detect ANRs | 302 // TODO: Detect ANRs |
| 303 if (scene_state->scene_listener()) { | 303 if (scene_state->scene_listener()) { |
| 304 scene_state->scene_listener()->OnResourceUnavailable( | 304 scene_state->scene_listener()->OnResourceUnavailable( |
| 305 resource_id, base::Bind(&base::DoNothing)); | 305 resource_id, base::Bind(&base::DoNothing)); |
| 306 } | 306 } |
| 307 } | 307 } |
| 308 | 308 |
| 309 SceneState* CompositorEngine::FindScene(uint32_t scene_token) { | 309 SceneState* CompositorEngine::FindScene(uint32_t scene_token) { |
| 310 auto it = scenes_by_token_.find(scene_token); | 310 auto it = scenes_by_token_.find(scene_token); |
| 311 return it != scenes_by_token_.end() ? it->second : nullptr; | 311 return it != scenes_by_token_.end() ? it->second : nullptr; |
| 312 } | 312 } |
| 313 | 313 |
| 314 void CompositorEngine::InvalidateScene(SceneState* scene_state) { | 314 void CompositorEngine::InvalidateScene(SceneState* scene_state) { |
| 315 DCHECK(IsSceneStateRegisteredDebug(scene_state)); | 315 DCHECK(IsSceneStateRegisteredDebug(scene_state)); |
| 316 DVLOG(2) << "InvalidateScene: scene=" << scene_state; | 316 DVLOG(2) << "InvalidateScene: scene=" << scene_state; |
| 317 | 317 |
| 318 for (auto& renderer : renderers_) { | 318 for (auto& renderer : renderers_) { |
| 319 if (renderer->current_snapshot() && | 319 if (renderer->current_snapshot() && |
| 320 renderer->current_snapshot()->HasDependency(scene_state->scene_def())) { | 320 renderer->current_snapshot()->HasDependency( |
| 321 scene_state->scene_token())) { |
| 321 ScheduleFrameForRenderer(renderer, Scheduler::SchedulingMode::kSnapshot); | 322 ScheduleFrameForRenderer(renderer, Scheduler::SchedulingMode::kSnapshot); |
| 322 } | 323 } |
| 323 } | 324 } |
| 324 } | 325 } |
| 325 | 326 |
| 326 SceneDef::Disposition CompositorEngine::PresentScene( | 327 SceneDef::Disposition CompositorEngine::PresentScene( |
| 327 SceneState* scene_state, | 328 SceneState* scene_state, |
| 328 int64_t presentation_time) { | 329 int64_t presentation_time) { |
| 329 DCHECK(IsSceneStateRegisteredDebug(scene_state)); | 330 DCHECK(IsSceneStateRegisteredDebug(scene_state)); |
| 330 DVLOG(2) << "PresentScene: scene=" << scene_state; | 331 DVLOG(2) << "PresentScene: scene=" << scene_state; |
| 331 | 332 |
| 332 std::ostringstream errs; | 333 std::ostringstream errs; |
| 333 SceneDef::Disposition disposition = scene_state->scene_def()->Present( | 334 SceneDef::Disposition disposition = scene_state->scene_def()->Present( |
| 334 presentation_time, base::Bind(&CompositorEngine::ResolveSceneReference, | 335 presentation_time, &universe_, |
| 335 base::Unretained(this)), | 336 base::Bind(&CompositorEngine::ResolveSceneReference, |
| 337 base::Unretained(this)), |
| 336 base::Bind(&CompositorEngine::SendResourceUnavailable, | 338 base::Bind(&CompositorEngine::SendResourceUnavailable, |
| 337 base::Unretained(this), base::Unretained(scene_state)), | 339 base::Unretained(this), base::Unretained(scene_state)), |
| 338 errs); | 340 errs); |
| 339 if (disposition == SceneDef::Disposition::kFailed) { | 341 if (disposition == SceneDef::Disposition::kFailed) { |
| 340 LOG(ERROR) << "Scene published invalid updates: scene=" << scene_state; | 342 LOG(ERROR) << "Scene published invalid updates: scene=" << scene_state; |
| 341 LOG(ERROR) << errs.str(); | 343 LOG(ERROR) << errs.str(); |
| 342 // Caller is responsible for destroying the scene. | 344 // Caller is responsible for destroying the scene. |
| 343 } | 345 } |
| 344 return disposition; | 346 return disposition; |
| 345 } | 347 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 367 RendererState* renderer_state, | 369 RendererState* renderer_state, |
| 368 const mojo::gfx::composition::FrameInfo& frame_info) { | 370 const mojo::gfx::composition::FrameInfo& frame_info) { |
| 369 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); | 371 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
| 370 DVLOG(2) << "SnapshotRenderer: renderer_state=" << renderer_state; | 372 DVLOG(2) << "SnapshotRenderer: renderer_state=" << renderer_state; |
| 371 | 373 |
| 372 if (VLOG_IS_ON(2)) { | 374 if (VLOG_IS_ON(2)) { |
| 373 std::ostringstream block_log; | 375 std::ostringstream block_log; |
| 374 SnapshotRendererInner(renderer_state, &block_log); | 376 SnapshotRendererInner(renderer_state, &block_log); |
| 375 if (!renderer_state->current_snapshot() || | 377 if (!renderer_state->current_snapshot() || |
| 376 renderer_state->current_snapshot()->is_blocked()) { | 378 renderer_state->current_snapshot()->is_blocked()) { |
| 377 DVLOG(2) << "Rendering completely blocked: " << block_log.str(); | 379 DVLOG(2) << "Rendering completely blocked:" << std::endl |
| 380 << block_log.str(); |
| 378 } else if (!block_log.str().empty()) { | 381 } else if (!block_log.str().empty()) { |
| 379 DVLOG(2) << "Rendering partially blocked: " << block_log.str(); | 382 DVLOG(2) << "Rendering partially blocked:" << std::endl |
| 383 << block_log.str(); |
| 380 } else { | 384 } else { |
| 381 DVLOG(2) << "Rendering unblocked"; | 385 DVLOG(2) << "Rendering unblocked"; |
| 382 } | 386 } |
| 383 } else { | 387 } else { |
| 384 SnapshotRendererInner(renderer_state, nullptr); | 388 SnapshotRendererInner(renderer_state, nullptr); |
| 385 } | 389 } |
| 386 | 390 |
| 387 if (renderer_state->visible_snapshot()) { | 391 if (renderer_state->visible_snapshot()) { |
| 388 DCHECK(!renderer_state->visible_snapshot()->is_blocked()); | 392 DCHECK(!renderer_state->visible_snapshot()->is_blocked()); |
| 389 renderer_state->output()->SubmitFrame( | 393 renderer_state->output()->SubmitFrame( |
| 390 renderer_state->visible_snapshot()->CreateFrame( | 394 renderer_state->visible_snapshot()->CreateFrame( |
| 391 renderer_state->root_scene_viewport(), frame_info)); | 395 renderer_state->root_scene_viewport(), frame_info)); |
| 392 } else { | 396 } else { |
| 393 renderer_state->output()->SubmitFrame(new RenderFrame( | 397 renderer_state->output()->SubmitFrame(new RenderFrame( |
| 394 renderer_state->root_scene_viewport().To<SkIRect>(), frame_info)); | 398 renderer_state->root_scene_viewport().To<SkIRect>(), frame_info)); |
| 395 } | 399 } |
| 396 } | 400 } |
| 397 | 401 |
| 398 void CompositorEngine::SnapshotRendererInner(RendererState* renderer_state, | 402 void CompositorEngine::SnapshotRendererInner(RendererState* renderer_state, |
| 399 std::ostream* block_log) { | 403 std::ostream* block_log) { |
| 400 if (!renderer_state->root_scene()) { | 404 if (!renderer_state->root_scene()) { |
| 401 if (block_log) | 405 if (block_log) |
| 402 *block_log << "No root scene" << std::endl; | 406 *block_log << "No root scene" << std::endl; |
| 403 renderer_state->SetSnapshot(nullptr); | 407 renderer_state->SetSnapshot(nullptr); |
| 404 return; | 408 return; |
| 405 } | 409 } |
| 406 | 410 |
| 407 SnapshotBuilder builder(block_log); | |
| 408 renderer_state->SetSnapshot( | 411 renderer_state->SetSnapshot( |
| 409 builder.Build(renderer_state->root_scene()->scene_def())); | 412 universe_.SnapshotScene(renderer_state->root_scene()->scene_token(), |
| 413 renderer_state->root_scene_version(), block_log)); |
| 410 } | 414 } |
| 411 | 415 |
| 412 void CompositorEngine::ScheduleFrameForRenderer( | 416 void CompositorEngine::ScheduleFrameForRenderer( |
| 413 RendererState* renderer_state, | 417 RendererState* renderer_state, |
| 414 Scheduler::SchedulingMode scheduling_mode) { | 418 Scheduler::SchedulingMode scheduling_mode) { |
| 415 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); | 419 DCHECK(IsRendererStateRegisteredDebug(renderer_state)); |
| 416 renderer_state->output()->GetScheduler()->ScheduleFrame(scheduling_mode); | 420 renderer_state->output()->GetScheduler()->ScheduleFrame(scheduling_mode); |
| 417 } | 421 } |
| 418 | 422 |
| 419 void CompositorEngine::OnOutputError( | 423 void CompositorEngine::OnOutputError( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 | 470 |
| 467 SceneDef::Disposition disposition = | 471 SceneDef::Disposition disposition = |
| 468 PresentScene(scene_state, presentation_time); | 472 PresentScene(scene_state, presentation_time); |
| 469 if (disposition == SceneDef::Disposition::kFailed) | 473 if (disposition == SceneDef::Disposition::kFailed) |
| 470 DestroyScene(scene_state); | 474 DestroyScene(scene_state); |
| 471 else if (disposition == SceneDef::Disposition::kSucceeded) | 475 else if (disposition == SceneDef::Disposition::kSucceeded) |
| 472 InvalidateScene(scene_state); | 476 InvalidateScene(scene_state); |
| 473 } | 477 } |
| 474 | 478 |
| 475 } // namespace compositor | 479 } // namespace compositor |
| OLD | NEW |