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/layer_tree_host_impl.h" | 5 #include "cc/layer_tree_host_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 m_client->setNeedsRedrawOnImplThread(); | 366 m_client->setNeedsRedrawOnImplThread(); |
367 } | 367 } |
368 | 368 |
369 bool LayerTreeHostImpl::haveTouchEventHandlersAt(const gfx::Point& viewportPoint
) | 369 bool LayerTreeHostImpl::haveTouchEventHandlersAt(const gfx::Point& viewportPoint
) |
370 { | 370 { |
371 | 371 |
372 gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceSca
leFactor); | 372 gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceSca
leFactor); |
373 | 373 |
374 // First find out which layer was hit from the saved list of visible layers | 374 // First find out which layer was hit from the saved list of visible layers |
375 // in the most recent frame. | 375 // in the most recent frame. |
376 LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(device
ViewportPoint, m_renderSurfaceLayerList); | 376 LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(device
ViewportPoint, activeTree()->RenderSurfaceLayerList()); |
377 | 377 |
378 // Walk up the hierarchy and look for a layer with a touch event handler reg
ion that the given point hits. | 378 // Walk up the hierarchy and look for a layer with a touch event handler reg
ion that the given point hits. |
379 for (; layerImpl; layerImpl = layerImpl->parent()) { | 379 for (; layerImpl; layerImpl = layerImpl->parent()) { |
380 if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(deviceViewportPoint,
layerImpl)) | 380 if (LayerTreeHostCommon::layerHasTouchEventHandlersAt(deviceViewportPoint,
layerImpl)) |
381 return true; | 381 return true; |
382 } | 382 } |
383 | 383 |
384 return false; | 384 return false; |
385 } | 385 } |
386 | 386 |
387 void LayerTreeHostImpl::trackDamageForAllSurfaces(LayerImpl* rootDrawLayer, cons
t LayerList& renderSurfaceLayerList) | 387 void LayerTreeHostImpl::trackDamageForAllSurfaces(LayerImpl* rootDrawLayer, cons
t LayerList& renderSurfaceLayerList) |
388 { | 388 { |
389 // For now, we use damage tracking to compute a global scissor. To do this,
we must | 389 // For now, we use damage tracking to compute a global scissor. To do this,
we must |
390 // compute all damage tracking before drawing anything, so that we know the
root | 390 // compute all damage tracking before drawing anything, so that we know the
root |
391 // damage rect. The root damage rect is then used to scissor each surface. | 391 // damage rect. The root damage rect is then used to scissor each surface. |
392 | 392 |
393 for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0
; --surfaceIndex) { | 393 for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0
; --surfaceIndex) { |
394 LayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; | 394 LayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; |
395 RenderSurfaceImpl* renderSurface = renderSurfaceLayer->renderSurface(); | 395 RenderSurfaceImpl* renderSurface = renderSurfaceLayer->renderSurface(); |
396 DCHECK(renderSurface); | 396 DCHECK(renderSurface); |
397 renderSurface->damageTracker()->updateDamageTrackingState(renderSurface-
>layerList(), renderSurfaceLayer->id(), renderSurface->surfacePropertyChangedOnl
yFromDescendant(), renderSurface->contentRect(), renderSurfaceLayer->maskLayer()
, renderSurfaceLayer->filters(), renderSurfaceLayer->filter().get()); | 397 renderSurface->damageTracker()->updateDamageTrackingState(renderSurface-
>layerList(), renderSurfaceLayer->id(), renderSurface->surfacePropertyChangedOnl
yFromDescendant(), renderSurface->contentRect(), renderSurfaceLayer->maskLayer()
, renderSurfaceLayer->filters(), renderSurfaceLayer->filter().get()); |
398 } | 398 } |
399 } | 399 } |
400 | 400 |
401 void LayerTreeHostImpl::updateDrawProperties() | 401 void LayerTreeHostImpl::updateDrawProperties() |
402 { | 402 { |
403 if (!needsUpdateDrawProperties()) | 403 if (!needsUpdateDrawProperties()) |
404 return; | 404 return; |
405 | 405 |
406 m_renderSurfaceLayerList.clear(); | 406 if (!m_renderer) { // For maxTextureSize. |
407 m_needsUpdateDrawProperties = false; | 407 // This will get set if renderer gets initialized. |
408 | 408 m_needsUpdateDrawProperties = false; |
409 if (!rootLayer()) | |
410 return; | |
411 | |
412 if (!m_renderer) // For maxTextureSize. | |
413 return; | 409 return; |
414 | |
415 if (rootScrollLayer()) | |
416 rootScrollLayer()->setImplTransform(implTransform()); | |
417 | |
418 { | |
419 TRACE_EVENT0("cc", "LayerTreeHostImpl::calcDrawEtc"); | |
420 float pageScaleFactor = m_pinchZoomViewport.pageScaleFactor(); | |
421 LayerTreeHostCommon::calculateDrawProperties(rootLayer(), deviceViewport
Size(), m_deviceScaleFactor, pageScaleFactor, rendererCapabilities().maxTextureS
ize, m_settings.canUseLCDText, m_renderSurfaceLayerList); | |
422 } | 410 } |
423 | 411 |
424 // TODO(nduca): Move this to LayerTreeImpl | 412 activeTree()->UpdateDrawProperties(); |
425 // Note: pending tree calcDrawProperties must follow the active tree one, | 413 if (pendingTree()) |
426 // as some properties are synced from active -> pending. | 414 pendingTree()->UpdateDrawProperties(); |
427 if (pendingTree() && pendingTree()->RootLayer()) | 415 |
428 { | 416 m_needsUpdateDrawProperties = false; |
429 float pageScaleFactor = m_pinchZoomViewport.pageScaleFactor(); | |
430 LayerList dummyList; | |
431 LayerTreeHostCommon::calculateDrawProperties(pendingTree()->RootLayer(),
deviceViewportSize(), m_deviceScaleFactor, pageScaleFactor, rendererCapabilitie
s().maxTextureSize, m_settings.canUseLCDText, dummyList); | |
432 } | |
433 } | 417 } |
434 | 418 |
435 void LayerTreeHostImpl::FrameData::appendRenderPass(scoped_ptr<RenderPass> rende
rPass) | 419 void LayerTreeHostImpl::FrameData::appendRenderPass(scoped_ptr<RenderPass> rende
rPass) |
436 { | 420 { |
437 RenderPass* pass = renderPass.get(); | 421 RenderPass* pass = renderPass.get(); |
438 renderPasses.push_back(pass); | 422 renderPasses.push_back(pass); |
439 renderPassesById.set(pass->id, renderPass.Pass()); | 423 renderPassesById.set(pass->id, renderPass.Pass()); |
440 } | 424 } |
441 | 425 |
442 static void appendQuadsForLayer(RenderPass* targetRenderPass, LayerImpl* layer,
OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData) | 426 static void appendQuadsForLayer(RenderPass* targetRenderPass, LayerImpl* layer,
OcclusionTrackerImpl& occlusionTracker, AppendQuadsData& appendQuadsData) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); | 505 scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); |
522 quad->SetNew(sharedQuadState, layerRect, screenBackgroundColor); | 506 quad->SetNew(sharedQuadState, layerRect, screenBackgroundColor); |
523 quadCuller.append(quad.PassAs<DrawQuad>(), appendQuadsData); | 507 quadCuller.append(quad.PassAs<DrawQuad>(), appendQuadsData); |
524 } | 508 } |
525 } | 509 } |
526 | 510 |
527 bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame) | 511 bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame) |
528 { | 512 { |
529 DCHECK(frame.renderPasses.empty()); | 513 DCHECK(frame.renderPasses.empty()); |
530 | 514 |
531 updateDrawProperties(); | |
532 if (!canDraw() || !rootLayer()) | 515 if (!canDraw() || !rootLayer()) |
533 return false; | 516 return false; |
534 | 517 |
535 trackDamageForAllSurfaces(rootLayer(), *frame.renderSurfaceLayerList); | 518 trackDamageForAllSurfaces(rootLayer(), *frame.renderSurfaceLayerList); |
536 | 519 |
537 TRACE_EVENT1("cc", "LayerTreeHostImpl::calculateRenderPasses", "renderSurfac
eLayerList.size()", static_cast<long long unsigned>(frame.renderSurfaceLayerList
->size())); | 520 TRACE_EVENT1("cc", "LayerTreeHostImpl::calculateRenderPasses", "renderSurfac
eLayerList.size()", static_cast<long long unsigned>(frame.renderSurfaceLayerList
->size())); |
538 | 521 |
539 // Create the render passes in dependency order. | 522 // Create the render passes in dependency order. |
540 for (int surfaceIndex = frame.renderSurfaceLayerList->size() - 1; surfaceInd
ex >= 0 ; --surfaceIndex) { | 523 for (int surfaceIndex = frame.renderSurfaceLayerList->size() - 1; surfaceInd
ex >= 0 ; --surfaceIndex) { |
541 LayerImpl* renderSurfaceLayer = (*frame.renderSurfaceLayerList)[surfaceI
ndex]; | 524 LayerImpl* renderSurfaceLayer = (*frame.renderSurfaceLayerList)[surfaceI
ndex]; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 } | 742 } |
760 | 743 |
761 bool LayerTreeHostImpl::prepareToDraw(FrameData& frame) | 744 bool LayerTreeHostImpl::prepareToDraw(FrameData& frame) |
762 { | 745 { |
763 TRACE_EVENT0("cc", "LayerTreeHostImpl::prepareToDraw"); | 746 TRACE_EVENT0("cc", "LayerTreeHostImpl::prepareToDraw"); |
764 | 747 |
765 if (m_tileManager) | 748 if (m_tileManager) |
766 m_tileManager->CheckForCompletedSetPixels(); | 749 m_tileManager->CheckForCompletedSetPixels(); |
767 | 750 |
768 activatePendingTreeIfNeeded(); | 751 activatePendingTreeIfNeeded(); |
| 752 updateDrawProperties(); |
769 | 753 |
770 frame.renderSurfaceLayerList = &m_renderSurfaceLayerList; | 754 frame.renderSurfaceLayerList = &activeTree()->RenderSurfaceLayerList(); |
771 frame.renderPasses.clear(); | 755 frame.renderPasses.clear(); |
772 frame.renderPassesById.clear(); | 756 frame.renderPassesById.clear(); |
773 frame.willDrawLayers.clear(); | 757 frame.willDrawLayers.clear(); |
774 | 758 |
775 if (!calculateRenderPasses(frame)) | 759 if (!calculateRenderPasses(frame)) |
776 return false; | 760 return false; |
777 | 761 |
778 // If we return true, then we expect drawLayers() to be called before this f
unction is called again. | 762 // If we return true, then we expect drawLayers() to be called before this f
unction is called again. |
779 return true; | 763 return true; |
780 } | 764 } |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 } | 1030 } |
1047 | 1031 |
1048 void LayerTreeHostImpl::activatePendingTree() | 1032 void LayerTreeHostImpl::activatePendingTree() |
1049 { | 1033 { |
1050 CHECK(m_pendingTree); | 1034 CHECK(m_pendingTree); |
1051 m_activeTree.swap(m_pendingTree); | 1035 m_activeTree.swap(m_pendingTree); |
1052 // TODO(enne): consider recycling this tree to prevent layer churn | 1036 // TODO(enne): consider recycling this tree to prevent layer churn |
1053 m_pendingTree.reset(); | 1037 m_pendingTree.reset(); |
1054 m_client->onCanDrawStateChanged(canDraw()); | 1038 m_client->onCanDrawStateChanged(canDraw()); |
1055 m_client->onHasPendingTreeStateChanged(pendingTree()); | 1039 m_client->onHasPendingTreeStateChanged(pendingTree()); |
1056 | |
1057 // TODO(nduca): Once render surface layer list moves to the tree so | |
1058 // that updateDrawProperties() affects both trees, this will be | |
1059 // unnecessary. | |
1060 setNeedsUpdateDrawProperties(); | |
1061 } | 1040 } |
1062 | 1041 |
1063 scoped_ptr<LayerImpl> LayerTreeHostImpl::detachLayerTree() | 1042 scoped_ptr<LayerImpl> LayerTreeHostImpl::detachLayerTree() |
1064 { | 1043 { |
1065 scoped_ptr<LayerImpl> layer = m_activeTree->DetachLayerTree(); | 1044 scoped_ptr<LayerImpl> layer = m_activeTree->DetachLayerTree(); |
1066 m_renderSurfaceLayerList.clear(); | |
1067 setNeedsUpdateDrawProperties(); | |
1068 return layer.Pass(); | 1045 return layer.Pass(); |
1069 } | 1046 } |
1070 | 1047 |
1071 void LayerTreeHostImpl::setVisible(bool visible) | 1048 void LayerTreeHostImpl::setVisible(bool visible) |
1072 { | 1049 { |
1073 DCHECK(m_proxy->isImplThread()); | 1050 DCHECK(m_proxy->isImplThread()); |
1074 | 1051 |
1075 if (m_visible == visible) | 1052 if (m_visible == visible) |
1076 return; | 1053 return; |
1077 m_visible = visible; | 1054 m_visible = visible; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 | 1090 |
1114 if (outputSurface->Capabilities().has_parent_compositor) | 1091 if (outputSurface->Capabilities().has_parent_compositor) |
1115 m_renderer = DelegatingRenderer::Create(this, resourceProvider.get()); | 1092 m_renderer = DelegatingRenderer::Create(this, resourceProvider.get()); |
1116 else if (outputSurface->Context3D()) | 1093 else if (outputSurface->Context3D()) |
1117 m_renderer = GLRenderer::create(this, outputSurface.get(), resourceProvi
der.get()); | 1094 m_renderer = GLRenderer::create(this, outputSurface.get(), resourceProvi
der.get()); |
1118 else if (outputSurface->SoftwareDevice()) | 1095 else if (outputSurface->SoftwareDevice()) |
1119 m_renderer = SoftwareRenderer::create(this, resourceProvider.get(), outp
utSurface->SoftwareDevice()); | 1096 m_renderer = SoftwareRenderer::create(this, resourceProvider.get(), outp
utSurface->SoftwareDevice()); |
1120 if (!m_renderer) | 1097 if (!m_renderer) |
1121 return false; | 1098 return false; |
1122 | 1099 |
| 1100 setNeedsUpdateDrawProperties(); |
1123 m_resourceProvider = resourceProvider.Pass(); | 1101 m_resourceProvider = resourceProvider.Pass(); |
1124 m_outputSurface = outputSurface.Pass(); | 1102 m_outputSurface = outputSurface.Pass(); |
1125 | 1103 |
1126 if (!m_visible) | 1104 if (!m_visible) |
1127 m_renderer->setVisible(m_visible); | 1105 m_renderer->setVisible(m_visible); |
1128 | 1106 |
1129 m_client->onCanDrawStateChanged(canDraw()); | 1107 m_client->onCanDrawStateChanged(canDraw()); |
1130 | 1108 |
1131 return true; | 1109 return true; |
1132 } | 1110 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 } | 1201 } |
1224 | 1202 |
1225 void LayerTreeHostImpl::setNeedsRedraw() | 1203 void LayerTreeHostImpl::setNeedsRedraw() |
1226 { | 1204 { |
1227 m_client->setNeedsRedrawOnImplThread(); | 1205 m_client->setNeedsRedrawOnImplThread(); |
1228 } | 1206 } |
1229 | 1207 |
1230 bool LayerTreeHostImpl::ensureRenderSurfaceLayerList() | 1208 bool LayerTreeHostImpl::ensureRenderSurfaceLayerList() |
1231 { | 1209 { |
1232 updateDrawProperties(); | 1210 updateDrawProperties(); |
1233 return m_renderSurfaceLayerList.size(); | 1211 return activeTree()->RenderSurfaceLayerList().size(); |
1234 } | 1212 } |
1235 | 1213 |
1236 InputHandlerClient::ScrollStatus LayerTreeHostImpl::scrollBegin(gfx::Point viewp
ortPoint, InputHandlerClient::ScrollInputType type) | 1214 InputHandlerClient::ScrollStatus LayerTreeHostImpl::scrollBegin(gfx::Point viewp
ortPoint, InputHandlerClient::ScrollInputType type) |
1237 { | 1215 { |
1238 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin"); | 1216 TRACE_EVENT0("cc", "LayerTreeHostImpl::scrollBegin"); |
1239 | 1217 |
1240 DCHECK(!currentlyScrollingLayer()); | 1218 DCHECK(!currentlyScrollingLayer()); |
1241 clearCurrentlyScrollingLayer(); | 1219 clearCurrentlyScrollingLayer(); |
1242 | 1220 |
1243 if (!ensureRenderSurfaceLayerList()) | 1221 if (!ensureRenderSurfaceLayerList()) |
1244 return ScrollIgnored; | 1222 return ScrollIgnored; |
1245 | 1223 |
1246 gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceSca
leFactor); | 1224 gfx::PointF deviceViewportPoint = gfx::ScalePoint(viewportPoint, m_deviceSca
leFactor); |
1247 | 1225 |
1248 // First find out which layer was hit from the saved list of visible layers | 1226 // First find out which layer was hit from the saved list of visible layers |
1249 // in the most recent frame. | 1227 // in the most recent frame. |
1250 LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(device
ViewportPoint, m_renderSurfaceLayerList); | 1228 LayerImpl* layerImpl = LayerTreeHostCommon::findLayerThatIsHitByPoint(device
ViewportPoint, activeTree()->RenderSurfaceLayerList()); |
1251 | 1229 |
1252 // Walk up the hierarchy and look for a scrollable layer. | 1230 // Walk up the hierarchy and look for a scrollable layer. |
1253 LayerImpl* potentiallyScrollingLayerImpl = 0; | 1231 LayerImpl* potentiallyScrollingLayerImpl = 0; |
1254 for (; layerImpl; layerImpl = layerImpl->parent()) { | 1232 for (; layerImpl; layerImpl = layerImpl->parent()) { |
1255 // The content layer can also block attempts to scroll outside the main
thread. | 1233 // The content layer can also block attempts to scroll outside the main
thread. |
1256 if (layerImpl->tryScroll(deviceViewportPoint, type) == ScrollOnMainThrea
d) { | 1234 if (layerImpl->tryScroll(deviceViewportPoint, type) == ScrollOnMainThrea
d) { |
1257 m_numMainThreadScrolls++; | 1235 m_numMainThreadScrolls++; |
1258 return ScrollOnMainThread; | 1236 return ScrollOnMainThread; |
1259 } | 1237 } |
1260 | 1238 |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 DCHECK(current); | 1607 DCHECK(current); |
1630 current->didLoseOutputSurface(); | 1608 current->didLoseOutputSurface(); |
1631 if (current->maskLayer()) | 1609 if (current->maskLayer()) |
1632 sendDidLoseOutputSurfaceRecursive(current->maskLayer()); | 1610 sendDidLoseOutputSurfaceRecursive(current->maskLayer()); |
1633 if (current->replicaLayer()) | 1611 if (current->replicaLayer()) |
1634 sendDidLoseOutputSurfaceRecursive(current->replicaLayer()); | 1612 sendDidLoseOutputSurfaceRecursive(current->replicaLayer()); |
1635 for (size_t i = 0; i < current->children().size(); ++i) | 1613 for (size_t i = 0; i < current->children().size(); ++i) |
1636 sendDidLoseOutputSurfaceRecursive(current->children()[i]); | 1614 sendDidLoseOutputSurfaceRecursive(current->children()[i]); |
1637 } | 1615 } |
1638 | 1616 |
1639 static void clearRenderSurfacesOnLayerImplRecursive(LayerImpl* current) | |
1640 { | |
1641 DCHECK(current); | |
1642 for (size_t i = 0; i < current->children().size(); ++i) | |
1643 clearRenderSurfacesOnLayerImplRecursive(current->children()[i]); | |
1644 current->clearRenderSurface(); | |
1645 } | |
1646 | |
1647 void LayerTreeHostImpl::clearRenderSurfaces() | 1617 void LayerTreeHostImpl::clearRenderSurfaces() |
1648 { | 1618 { |
1649 clearRenderSurfacesOnLayerImplRecursive(rootLayer()); | 1619 activeTree()->ClearRenderSurfaces(); |
1650 m_renderSurfaceLayerList.clear(); | 1620 if (pendingTree()) |
1651 setNeedsUpdateDrawProperties(); | 1621 pendingTree()->ClearRenderSurfaces(); |
1652 } | 1622 } |
1653 | 1623 |
1654 std::string LayerTreeHostImpl::layerTreeAsText() const | 1624 std::string LayerTreeHostImpl::layerTreeAsText() const |
1655 { | 1625 { |
1656 std::string str; | 1626 std::string str; |
1657 if (rootLayer()) { | 1627 if (rootLayer()) { |
1658 str = rootLayer()->layerTreeAsText(); | 1628 str = rootLayer()->layerTreeAsText(); |
1659 str += "RenderSurfaces:\n"; | 1629 str += "RenderSurfaces:\n"; |
1660 dumpRenderSurfaces(&str, 1, rootLayer()); | 1630 dumpRenderSurfaces(&str, 1, rootLayer()); |
1661 } | 1631 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 ScrollbarAnimationController* scrollbarController = layer->scrollbarAnimatio
nController(); | 1711 ScrollbarAnimationController* scrollbarController = layer->scrollbarAnimatio
nController(); |
1742 double monotonicTime = (time - base::TimeTicks()).InSecondsF(); | 1712 double monotonicTime = (time - base::TimeTicks()).InSecondsF(); |
1743 if (scrollbarController && scrollbarController->animate(monotonicTime)) | 1713 if (scrollbarController && scrollbarController->animate(monotonicTime)) |
1744 m_client->setNeedsRedrawOnImplThread(); | 1714 m_client->setNeedsRedrawOnImplThread(); |
1745 | 1715 |
1746 for (size_t i = 0; i < layer->children().size(); ++i) | 1716 for (size_t i = 0; i < layer->children().size(); ++i) |
1747 animateScrollbarsRecursive(layer->children()[i], time); | 1717 animateScrollbarsRecursive(layer->children()[i], time); |
1748 } | 1718 } |
1749 | 1719 |
1750 } // namespace cc | 1720 } // namespace cc |
OLD | NEW |