| OLD | NEW |
| 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> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 | 394 |
| 395 if (main().commit_requested) | 395 if (main().commit_requested) |
| 396 return; | 396 return; |
| 397 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit"); | 397 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit"); |
| 398 main().commit_requested = true; | 398 main().commit_requested = true; |
| 399 | 399 |
| 400 SendCommitRequestToImplThreadIfNeeded(); | 400 SendCommitRequestToImplThreadIfNeeded(); |
| 401 } | 401 } |
| 402 | 402 |
| 403 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() { | 403 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() { |
| 404 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); |
| 404 DCHECK(IsImplThread()); | 405 DCHECK(IsImplThread()); |
| 405 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); | |
| 406 CheckOutputSurfaceStatusOnImplThread(); | 406 CheckOutputSurfaceStatusOnImplThread(); |
| 407 } | 407 } |
| 408 | 408 |
| 409 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { | 409 void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { |
| 410 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); |
| 410 DCHECK(IsImplThread()); | 411 DCHECK(IsImplThread()); |
| 411 TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); | |
| 412 if (!impl().layer_tree_host_impl->IsContextLost()) | 412 if (!impl().layer_tree_host_impl->IsContextLost()) |
| 413 return; | 413 return; |
| 414 if (ContextProvider* offscreen_contexts = | 414 if (ContextProvider* offscreen_contexts = |
| 415 impl().layer_tree_host_impl->offscreen_context_provider()) | 415 impl().layer_tree_host_impl->offscreen_context_provider()) |
| 416 offscreen_contexts->VerifyContexts(); | 416 offscreen_contexts->VerifyContexts(); |
| 417 impl().scheduler->DidLoseOutputSurface(); | 417 impl().scheduler->DidLoseOutputSurface(); |
| 418 } | 418 } |
| 419 | 419 |
| 420 void ThreadProxy::OnSwapBuffersCompleteOnImplThread() { | 420 void ThreadProxy::OnSwapBuffersCompleteOnImplThread() { |
| 421 TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread"); |
| 421 DCHECK(IsImplThread()); | 422 DCHECK(IsImplThread()); |
| 422 TRACE_EVENT0("cc", "ThreadProxy::OnSwapBuffersCompleteOnImplThread"); | |
| 423 Proxy::MainThreadTaskRunner()->PostTask( | 423 Proxy::MainThreadTaskRunner()->PostTask( |
| 424 FROM_HERE, | 424 FROM_HERE, |
| 425 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); | 425 base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); |
| 426 } | 426 } |
| 427 | 427 |
| 428 void ThreadProxy::SetNeedsBeginImplFrame(bool enable) { | 428 void ThreadProxy::SetNeedsBeginImplFrame(bool enable) { |
| 429 TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame", "enable", enable); |
| 429 DCHECK(IsImplThread()); | 430 DCHECK(IsImplThread()); |
| 430 TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame", "enable", enable); | |
| 431 impl().layer_tree_host_impl->SetNeedsBeginImplFrame(enable); | 431 impl().layer_tree_host_impl->SetNeedsBeginImplFrame(enable); |
| 432 UpdateBackgroundAnimateTicking(); | 432 UpdateBackgroundAnimateTicking(); |
| 433 } | 433 } |
| 434 | 434 |
| 435 void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) { | 435 void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) { |
| 436 TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame"); |
| 436 DCHECK(IsImplThread()); | 437 DCHECK(IsImplThread()); |
| 437 TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame"); | |
| 438 | 438 |
| 439 // Sample the frame time now. This time will be used for updating animations | 439 // Sample the frame time now. This time will be used for updating animations |
| 440 // when we draw. | 440 // when we draw. |
| 441 impl().layer_tree_host_impl->CurrentFrameTimeTicks(); | 441 impl().layer_tree_host_impl->CurrentFrameTimeTicks(); |
| 442 | 442 |
| 443 impl().scheduler->BeginImplFrame(args); | 443 impl().scheduler->BeginImplFrame(args); |
| 444 } | 444 } |
| 445 | 445 |
| 446 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { | 446 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) { |
| 447 DCHECK(IsImplThread()); | |
| 448 TRACE_EVENT1( | 447 TRACE_EVENT1( |
| 449 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); | 448 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); |
| 449 DCHECK(IsImplThread()); |
| 450 impl().scheduler->SetCanDraw(can_draw); | 450 impl().scheduler->SetCanDraw(can_draw); |
| 451 UpdateBackgroundAnimateTicking(); | 451 UpdateBackgroundAnimateTicking(); |
| 452 } | 452 } |
| 453 | 453 |
| 454 void ThreadProxy::NotifyReadyToActivate() { | 454 void ThreadProxy::NotifyReadyToActivate() { |
| 455 TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate"); | 455 TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate"); |
| 456 impl().scheduler->NotifyReadyToActivate(); | 456 impl().scheduler->NotifyReadyToActivate(); |
| 457 } | 457 } |
| 458 | 458 |
| 459 void ThreadProxy::SetNeedsCommitOnImplThread() { | 459 void ThreadProxy::SetNeedsCommitOnImplThread() { |
| 460 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread"); |
| 460 DCHECK(IsImplThread()); | 461 DCHECK(IsImplThread()); |
| 461 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread"); | |
| 462 impl().scheduler->SetNeedsCommit(); | 462 impl().scheduler->SetNeedsCommit(); |
| 463 } | 463 } |
| 464 | 464 |
| 465 void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread( | 465 void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread( |
| 466 scoped_ptr<AnimationEventsVector> events, | 466 scoped_ptr<AnimationEventsVector> events, |
| 467 base::Time wall_clock_time) { | 467 base::Time wall_clock_time) { |
| 468 DCHECK(IsImplThread()); | |
| 469 TRACE_EVENT0("cc", | 468 TRACE_EVENT0("cc", |
| 470 "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); | 469 "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); |
| 470 DCHECK(IsImplThread()); |
| 471 Proxy::MainThreadTaskRunner()->PostTask( | 471 Proxy::MainThreadTaskRunner()->PostTask( |
| 472 FROM_HERE, | 472 FROM_HERE, |
| 473 base::Bind(&ThreadProxy::SetAnimationEvents, | 473 base::Bind(&ThreadProxy::SetAnimationEvents, |
| 474 main_thread_weak_ptr_, | 474 main_thread_weak_ptr_, |
| 475 base::Passed(&events), | 475 base::Passed(&events), |
| 476 wall_clock_time)); | 476 wall_clock_time)); |
| 477 } | 477 } |
| 478 | 478 |
| 479 bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes, | 479 bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes, |
| 480 int priority_cutoff) { | 480 int priority_cutoff) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 | 517 |
| 518 impl().layer_tree_host_impl->SendManagedMemoryStats( | 518 impl().layer_tree_host_impl->SendManagedMemoryStats( |
| 519 impl().contents_texture_manager->MemoryVisibleBytes(), | 519 impl().contents_texture_manager->MemoryVisibleBytes(), |
| 520 impl().contents_texture_manager->MemoryVisibleAndNearbyBytes(), | 520 impl().contents_texture_manager->MemoryVisibleAndNearbyBytes(), |
| 521 impl().contents_texture_manager->MemoryUseBytes()); | 521 impl().contents_texture_manager->MemoryUseBytes()); |
| 522 } | 522 } |
| 523 | 523 |
| 524 bool ThreadProxy::IsInsideDraw() { return impl().inside_draw; } | 524 bool ThreadProxy::IsInsideDraw() { return impl().inside_draw; } |
| 525 | 525 |
| 526 void ThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { | 526 void ThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { |
| 527 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw"); |
| 527 DCHECK(IsMainThread()); | 528 DCHECK(IsMainThread()); |
| 528 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw"); | |
| 529 Proxy::ImplThreadTaskRunner()->PostTask( | 529 Proxy::ImplThreadTaskRunner()->PostTask( |
| 530 FROM_HERE, | 530 FROM_HERE, |
| 531 base::Bind(&ThreadProxy::SetNeedsRedrawRectOnImplThread, | 531 base::Bind(&ThreadProxy::SetNeedsRedrawRectOnImplThread, |
| 532 impl_thread_weak_ptr_, | 532 impl_thread_weak_ptr_, |
| 533 damage_rect)); | 533 damage_rect)); |
| 534 } | 534 } |
| 535 | 535 |
| 536 void ThreadProxy::SetNextCommitWaitsForActivation() { | 536 void ThreadProxy::SetNextCommitWaitsForActivation() { |
| 537 DCHECK(IsMainThread()); | 537 DCHECK(IsMainThread()); |
| 538 DCHECK(!blocked_main().main_thread_inside_commit); | 538 DCHECK(!blocked_main().main_thread_inside_commit); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 561 DCHECK(IsMainThread()); | 561 DCHECK(IsMainThread()); |
| 562 return main().commit_requested; | 562 return main().commit_requested; |
| 563 } | 563 } |
| 564 | 564 |
| 565 bool ThreadProxy::BeginMainFrameRequested() const { | 565 bool ThreadProxy::BeginMainFrameRequested() const { |
| 566 DCHECK(IsMainThread()); | 566 DCHECK(IsMainThread()); |
| 567 return main().commit_request_sent_to_impl_thread; | 567 return main().commit_request_sent_to_impl_thread; |
| 568 } | 568 } |
| 569 | 569 |
| 570 void ThreadProxy::SetNeedsRedrawOnImplThread() { | 570 void ThreadProxy::SetNeedsRedrawOnImplThread() { |
| 571 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread"); |
| 571 DCHECK(IsImplThread()); | 572 DCHECK(IsImplThread()); |
| 572 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread"); | |
| 573 impl().scheduler->SetNeedsRedraw(); | 573 impl().scheduler->SetNeedsRedraw(); |
| 574 } | 574 } |
| 575 | 575 |
| 576 void ThreadProxy::SetNeedsManageTilesOnImplThread() { | 576 void ThreadProxy::SetNeedsManageTilesOnImplThread() { |
| 577 DCHECK(IsImplThread()); | 577 DCHECK(IsImplThread()); |
| 578 impl().scheduler->SetNeedsManageTiles(); | 578 impl().scheduler->SetNeedsManageTiles(); |
| 579 } | 579 } |
| 580 | 580 |
| 581 void ThreadProxy::SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) { | 581 void ThreadProxy::SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) { |
| 582 DCHECK(IsImplThread()); | 582 DCHECK(IsImplThread()); |
| 583 impl().layer_tree_host_impl->SetViewportDamage(damage_rect); | 583 impl().layer_tree_host_impl->SetViewportDamage(damage_rect); |
| 584 SetNeedsRedrawOnImplThread(); | 584 SetNeedsRedrawOnImplThread(); |
| 585 } | 585 } |
| 586 | 586 |
| 587 void ThreadProxy::SetSwapUsedIncompleteTileOnImplThread( | 587 void ThreadProxy::SetSwapUsedIncompleteTileOnImplThread( |
| 588 bool used_incomplete_tile) { | 588 bool used_incomplete_tile) { |
| 589 DCHECK(IsImplThread()); | 589 DCHECK(IsImplThread()); |
| 590 if (used_incomplete_tile) { | 590 if (used_incomplete_tile) { |
| 591 TRACE_EVENT_INSTANT0("cc", | 591 TRACE_EVENT_INSTANT0("cc", |
| 592 "ThreadProxy::SetSwapUsedIncompleteTileOnImplThread", | 592 "ThreadProxy::SetSwapUsedIncompleteTileOnImplThread", |
| 593 TRACE_EVENT_SCOPE_THREAD); | 593 TRACE_EVENT_SCOPE_THREAD); |
| 594 } | 594 } |
| 595 impl().scheduler->SetSwapUsedIncompleteTile(used_incomplete_tile); | 595 impl().scheduler->SetSwapUsedIncompleteTile(used_incomplete_tile); |
| 596 } | 596 } |
| 597 | 597 |
| 598 void ThreadProxy::DidInitializeVisibleTileOnImplThread() { | 598 void ThreadProxy::DidInitializeVisibleTileOnImplThread() { |
| 599 TRACE_EVENT0("cc", "ThreadProxy::DidInitializeVisibleTileOnImplThread"); |
| 599 DCHECK(IsImplThread()); | 600 DCHECK(IsImplThread()); |
| 600 TRACE_EVENT0("cc", "ThreadProxy::DidInitializeVisibleTileOnImplThread"); | |
| 601 impl().scheduler->SetNeedsRedraw(); | 601 impl().scheduler->SetNeedsRedraw(); |
| 602 } | 602 } |
| 603 | 603 |
| 604 void ThreadProxy::MainThreadHasStoppedFlinging() { | 604 void ThreadProxy::MainThreadHasStoppedFlinging() { |
| 605 DCHECK(IsMainThread()); | 605 DCHECK(IsMainThread()); |
| 606 Proxy::ImplThreadTaskRunner()->PostTask( | 606 Proxy::ImplThreadTaskRunner()->PostTask( |
| 607 FROM_HERE, | 607 FROM_HERE, |
| 608 base::Bind(&ThreadProxy::MainThreadHasStoppedFlingingOnImplThread, | 608 base::Bind(&ThreadProxy::MainThreadHasStoppedFlingingOnImplThread, |
| 609 impl_thread_weak_ptr_)); | 609 impl_thread_weak_ptr_)); |
| 610 } | 610 } |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 | 1077 |
| 1078 impl().commit_complete_time = base::TimeTicks::HighResNow(); | 1078 impl().commit_complete_time = base::TimeTicks::HighResNow(); |
| 1079 impl().begin_main_frame_to_commit_duration_history.InsertSample( | 1079 impl().begin_main_frame_to_commit_duration_history.InsertSample( |
| 1080 impl().commit_complete_time - impl().begin_main_frame_sent_time); | 1080 impl().commit_complete_time - impl().begin_main_frame_sent_time); |
| 1081 | 1081 |
| 1082 // SetVisible kicks off the next scheduler action, so this must be last. | 1082 // SetVisible kicks off the next scheduler action, so this must be last. |
| 1083 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); | 1083 impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); |
| 1084 } | 1084 } |
| 1085 | 1085 |
| 1086 void ThreadProxy::ScheduledActionUpdateVisibleTiles() { | 1086 void ThreadProxy::ScheduledActionUpdateVisibleTiles() { |
| 1087 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles"); |
| 1087 DCHECK(IsImplThread()); | 1088 DCHECK(IsImplThread()); |
| 1088 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionUpdateVisibleTiles"); | |
| 1089 impl().layer_tree_host_impl->UpdateVisibleTiles(); | 1089 impl().layer_tree_host_impl->UpdateVisibleTiles(); |
| 1090 } | 1090 } |
| 1091 | 1091 |
| 1092 void ThreadProxy::ScheduledActionActivatePendingTree() { | 1092 void ThreadProxy::ScheduledActionActivatePendingTree() { |
| 1093 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree"); |
| 1093 DCHECK(IsImplThread()); | 1094 DCHECK(IsImplThread()); |
| 1094 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree"); | |
| 1095 impl().layer_tree_host_impl->ActivatePendingTree(); | 1095 impl().layer_tree_host_impl->ActivatePendingTree(); |
| 1096 } | 1096 } |
| 1097 | 1097 |
| 1098 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { | 1098 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { |
| 1099 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation"); |
| 1099 DCHECK(IsImplThread()); | 1100 DCHECK(IsImplThread()); |
| 1100 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation"); | |
| 1101 Proxy::MainThreadTaskRunner()->PostTask( | 1101 Proxy::MainThreadTaskRunner()->PostTask( |
| 1102 FROM_HERE, | 1102 FROM_HERE, |
| 1103 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, | 1103 base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, |
| 1104 main_thread_weak_ptr_)); | 1104 main_thread_weak_ptr_)); |
| 1105 } | 1105 } |
| 1106 | 1106 |
| 1107 DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal( | 1107 DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal( |
| 1108 bool forced_draw, | 1108 bool forced_draw, |
| 1109 bool swap_requested, | 1109 bool swap_requested, |
| 1110 bool readback_requested) { | 1110 bool readback_requested) { |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1656 base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread, | 1656 base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread, |
| 1657 impl_thread_weak_ptr_), | 1657 impl_thread_weak_ptr_), |
| 1658 delay); | 1658 delay); |
| 1659 } | 1659 } |
| 1660 | 1660 |
| 1661 void ThreadProxy::StartScrollbarAnimationOnImplThread() { | 1661 void ThreadProxy::StartScrollbarAnimationOnImplThread() { |
| 1662 impl().layer_tree_host_impl->StartScrollbarAnimation(); | 1662 impl().layer_tree_host_impl->StartScrollbarAnimation(); |
| 1663 } | 1663 } |
| 1664 | 1664 |
| 1665 void ThreadProxy::DidActivatePendingTree() { | 1665 void ThreadProxy::DidActivatePendingTree() { |
| 1666 TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread"); |
| 1666 DCHECK(IsImplThread()); | 1667 DCHECK(IsImplThread()); |
| 1667 TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread"); | |
| 1668 | 1668 |
| 1669 if (impl().completion_event_for_commit_held_on_tree_activation && | 1669 if (impl().completion_event_for_commit_held_on_tree_activation && |
| 1670 !impl().layer_tree_host_impl->pending_tree()) { | 1670 !impl().layer_tree_host_impl->pending_tree()) { |
| 1671 TRACE_EVENT_INSTANT0( | 1671 TRACE_EVENT_INSTANT0( |
| 1672 "cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD); | 1672 "cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD); |
| 1673 DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting); | 1673 DCHECK(impl().layer_tree_host_impl->settings().impl_side_painting); |
| 1674 impl().completion_event_for_commit_held_on_tree_activation->Signal(); | 1674 impl().completion_event_for_commit_held_on_tree_activation->Signal(); |
| 1675 impl().completion_event_for_commit_held_on_tree_activation = NULL; | 1675 impl().completion_event_for_commit_held_on_tree_activation = NULL; |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 UpdateBackgroundAnimateTicking(); | 1678 UpdateBackgroundAnimateTicking(); |
| 1679 | 1679 |
| 1680 impl().commit_to_activate_duration_history.InsertSample( | 1680 impl().commit_to_activate_duration_history.InsertSample( |
| 1681 base::TimeTicks::HighResNow() - impl().commit_complete_time); | 1681 base::TimeTicks::HighResNow() - impl().commit_complete_time); |
| 1682 } | 1682 } |
| 1683 | 1683 |
| 1684 void ThreadProxy::DidManageTiles() { | 1684 void ThreadProxy::DidManageTiles() { |
| 1685 DCHECK(IsImplThread()); | 1685 DCHECK(IsImplThread()); |
| 1686 impl().scheduler->DidManageTiles(); | 1686 impl().scheduler->DidManageTiles(); |
| 1687 } | 1687 } |
| 1688 | 1688 |
| 1689 } // namespace cc | 1689 } // namespace cc |
| OLD | NEW |