aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs353
1 files changed, 184 insertions, 169 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index b50ccc4..2a511e4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1223,11 +1223,14 @@ namespace OpenSim.Region.Framework.Scenes
1223 // The first frame can take a very long time due to physics actors being added on startup. Therefore, 1223 // The first frame can take a very long time due to physics actors being added on startup. Therefore,
1224 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false 1224 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1225 // alarms for scenes with many objects. 1225 // alarms for scenes with many objects.
1226 Update(); 1226 Update(1);
1227 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1227 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1228 1228
1229 while (!shuttingdown) 1229 while (!shuttingdown)
1230 Update(); 1230 Update(-1);
1231
1232 m_lastUpdate = Util.EnvironmentTickCount();
1233 m_firstHeartbeat = false;
1231 } 1234 }
1232 finally 1235 finally
1233 { 1236 {
@@ -1238,196 +1241,208 @@ namespace OpenSim.Region.Framework.Scenes
1238 Watchdog.RemoveThread(); 1241 Watchdog.RemoveThread();
1239 } 1242 }
1240 1243
1241 public override void Update() 1244 public override void Update(int frames)
1242 { 1245 {
1243 float physicsFPS = 0f; 1246 long? endFrame = null;
1244
1245 int maintc = Util.EnvironmentTickCount();
1246 int tmpFrameMS = maintc;
1247 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1248 1247
1249 ++Frame; 1248 if (frames >= 0)
1249 endFrame = Frame + frames;
1250 1250
1251// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); 1251 float physicsFPS = 0f;
1252 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
1253 int maintc;
1254 List<Vector3> coarseLocations;
1255 List<UUID> avatarUUIDs;
1252 1256
1253 try 1257 while (!shuttingdown && (endFrame == null || Frame < endFrame))
1254 { 1258 {
1255 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1259 maintc = Util.EnvironmentTickCount();
1256 if ((Frame % m_update_physics == 0) && m_physics_enabled) 1260 ++Frame;
1257 m_sceneGraph.UpdatePreparePhysics();
1258 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1259
1260 // Apply any pending avatar force input to the avatar's velocity
1261 int tmpAgentMS = Util.EnvironmentTickCount();
1262 if (Frame % m_update_entitymovement == 0)
1263 m_sceneGraph.UpdateScenePresenceMovement();
1264 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1265
1266 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1267 // velocity
1268 int tmpPhysicsMS = Util.EnvironmentTickCount();
1269 if (Frame % m_update_physics == 0)
1270 {
1271 if (m_physics_enabled)
1272 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1273
1274 if (SynchronizeScene != null)
1275 SynchronizeScene(this);
1276 }
1277 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1278 1261
1279 tmpAgentMS = Util.EnvironmentTickCount(); 1262// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1280
1281 // Check if any objects have reached their targets
1282 CheckAtTargets();
1283
1284 // Update SceneObjectGroups that have scheduled themselves for updates
1285 // Objects queue their updates onto all scene presences
1286 if (Frame % m_update_objects == 0)
1287 m_sceneGraph.UpdateObjectGroups();
1288 1263
1289 // Run through all ScenePresences looking for updates 1264 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1290 // Presence updates and queued object updates for each presence are sent to clients
1291 if (Frame % m_update_presences == 0)
1292 m_sceneGraph.UpdatePresences();
1293 1265
1294 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) 1266 try
1295 if (Frame % m_update_coarse_locations == 0)
1296 { 1267 {
1297 List<Vector3> coarseLocations; 1268 tmpPhysicsMS2 = Util.EnvironmentTickCount();
1298 List<UUID> avatarUUIDs; 1269 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1299 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); 1270 m_sceneGraph.UpdatePreparePhysics();
1300 // Send coarse locations to clients 1271 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1301 ForEachScenePresence(delegate(ScenePresence presence) 1272
1273 // Apply any pending avatar force input to the avatar's velocity
1274 tmpAgentMS = Util.EnvironmentTickCount();
1275 if (Frame % m_update_entitymovement == 0)
1276 m_sceneGraph.UpdateScenePresenceMovement();
1277 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1278
1279 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1280 // velocity
1281 tmpPhysicsMS = Util.EnvironmentTickCount();
1282 if (Frame % m_update_physics == 0)
1302 { 1283 {
1303 presence.SendCoarseLocations(coarseLocations, avatarUUIDs); 1284 if (m_physics_enabled)
1304 }); 1285 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1305 } 1286
1306 1287 if (SynchronizeScene != null)
1307 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); 1288 SynchronizeScene(this);
1308 1289 }
1309 // Delete temp-on-rez stuff 1290 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1310 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1311 {
1312 int tmpTempOnRezMS = Util.EnvironmentTickCount();
1313 m_cleaningTemps = true;
1314 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1315 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1316 }
1317
1318 if (Frame % m_update_events == 0)
1319 {
1320 int evMS = Util.EnvironmentTickCount();
1321 UpdateEvents();
1322 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1323 }
1324
1325 // if (Frame % m_update_land == 0)
1326 // {
1327 // int ldMS = Util.EnvironmentTickCount();
1328 // UpdateLand();
1329 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1330 // }
1331
1332 if (Frame % m_update_backup == 0)
1333 {
1334 int backMS = Util.EnvironmentTickCount();
1335 UpdateStorageBackup();
1336 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1337 }
1338
1339 if (Frame % m_update_terrain == 0)
1340 {
1341 int terMS = Util.EnvironmentTickCount();
1342 UpdateTerrain();
1343 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1344 }
1345
1346 //if (Frame % m_update_land == 0)
1347 //{
1348 // int ldMS = Util.EnvironmentTickCount();
1349 // UpdateLand();
1350 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1351 //}
1352
1353 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1354 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1355 lastCompletedFrame = Util.EnvironmentTickCount();
1356
1357 // if (Frame%m_update_avatars == 0)
1358 // UpdateInWorldTime();
1359 StatsReporter.AddPhysicsFPS(physicsFPS);
1360 StatsReporter.AddTimeDilation(TimeDilation);
1361 StatsReporter.AddFPS(1);
1362 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1363 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1364 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1365 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1366 StatsReporter.addFrameMS(frameMS);
1367 StatsReporter.addAgentMS(agentMS);
1368 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1369 StatsReporter.addOtherMS(otherMS);
1370 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1371 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1372
1373 if (LoginsDisabled && Frame == 20)
1374 {
1375// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1376
1377 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1378 // this is a rare case where we know we have just went through a long cycle of heap
1379 // allocations, and there is no more work to be done until someone logs in
1380 GC.Collect();
1381 1291
1382 IConfig startupConfig = m_config.Configs["Startup"]; 1292 tmpAgentMS = Util.EnvironmentTickCount();
1383 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1293
1294 // Check if any objects have reached their targets
1295 CheckAtTargets();
1296
1297 // Update SceneObjectGroups that have scheduled themselves for updates
1298 // Objects queue their updates onto all scene presences
1299 if (Frame % m_update_objects == 0)
1300 m_sceneGraph.UpdateObjectGroups();
1301
1302 // Run through all ScenePresences looking for updates
1303 // Presence updates and queued object updates for each presence are sent to clients
1304 if (Frame % m_update_presences == 0)
1305 m_sceneGraph.UpdatePresences();
1306
1307 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1308 if (Frame % m_update_coarse_locations == 0)
1309 {
1310 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1311 // Send coarse locations to clients
1312 ForEachScenePresence(delegate(ScenePresence presence)
1313 {
1314 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1315 });
1316 }
1317
1318 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
1319
1320 // Delete temp-on-rez stuff
1321 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1322 {
1323 tmpTempOnRezMS = Util.EnvironmentTickCount();
1324 m_cleaningTemps = true;
1325 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1326 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1327 }
1328
1329 if (Frame % m_update_events == 0)
1330 {
1331 evMS = Util.EnvironmentTickCount();
1332 UpdateEvents();
1333 eventMS = Util.EnvironmentTickCountSubtract(evMS);
1334 }
1335
1336 if (Frame % m_update_backup == 0)
1337 {
1338 backMS = Util.EnvironmentTickCount();
1339 UpdateStorageBackup();
1340 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1341 }
1342
1343 if (Frame % m_update_terrain == 0)
1384 { 1344 {
1385 // This handles a case of a region having no scripts for the RegionReady module 1345 terMS = Util.EnvironmentTickCount();
1386 if (m_sceneGraph.GetActiveScriptsCount() == 0) 1346 UpdateTerrain();
1347 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1348 }
1349
1350 //if (Frame % m_update_land == 0)
1351 //{
1352 // int ldMS = Util.EnvironmentTickCount();
1353 // UpdateLand();
1354 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1355 //}
1356
1357 frameMS = Util.EnvironmentTickCountSubtract(maintc);
1358 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1359 lastCompletedFrame = Util.EnvironmentTickCount();
1360
1361 // if (Frame%m_update_avatars == 0)
1362 // UpdateInWorldTime();
1363 StatsReporter.AddPhysicsFPS(physicsFPS);
1364 StatsReporter.AddTimeDilation(TimeDilation);
1365 StatsReporter.AddFPS(1);
1366 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1367 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1368 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1369 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1370
1371 // frameMS currently records work frame times, not total frame times (work + any required sleep to
1372 // reach min frame time.
1373 StatsReporter.addFrameMS(frameMS);
1374
1375 StatsReporter.addAgentMS(agentMS);
1376 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1377 StatsReporter.addOtherMS(otherMS);
1378 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1379 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1380
1381 if (LoginsDisabled && Frame == 20)
1382 {
1383 // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1384
1385 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1386 // this is a rare case where we know we have just went through a long cycle of heap
1387 // allocations, and there is no more work to be done until someone logs in
1388 GC.Collect();
1389
1390 IConfig startupConfig = m_config.Configs["Startup"];
1391 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1387 { 1392 {
1388 // need to be able to tell these have changed in RegionReady 1393 // This handles a case of a region having no scripts for the RegionReady module
1389 LoginLock = false; 1394 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1390 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); 1395 {
1396 // need to be able to tell these have changed in RegionReady
1397 LoginLock = false;
1398 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1399 }
1400 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1401
1402 // For RegionReady lockouts
1403 if(LoginLock == false)
1404 {
1405 LoginsDisabled = false;
1406 }
1407
1408 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1391 } 1409 }
1392 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1410 else
1393
1394 // For RegionReady lockouts
1395 if(LoginLock == false)
1396 { 1411 {
1397 LoginsDisabled = false; 1412 StartDisabled = true;
1413 LoginsDisabled = true;
1398 } 1414 }
1399
1400 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1401 }
1402 else
1403 {
1404 StartDisabled = true;
1405 LoginsDisabled = true;
1406 } 1415 }
1407 } 1416 }
1408 } 1417 catch (Exception e)
1409 catch (Exception e) 1418 {
1410 { 1419 m_log.ErrorFormat(
1411 m_log.ErrorFormat( 1420 "[SCENE]: Failed on region {0} with exception {1}{2}",
1412 "[SCENE]: Failed on region {0} with exception {1}{2}", 1421 RegionInfo.RegionName, e.Message, e.StackTrace);
1413 RegionInfo.RegionName, e.Message, e.StackTrace); 1422 }
1414 } 1423
1415 1424 EventManager.TriggerRegionHeartbeatEnd(this);
1416 EventManager.TriggerRegionHeartbeatEnd(this);
1417 1425
1418 maintc = Util.EnvironmentTickCountSubtract(maintc); 1426 // Tell the watchdog that this thread is still alive
1419 maintc = (int)(MinFrameTime * 1000) - maintc; 1427 Watchdog.UpdateThread();
1420 1428
1429 maintc = Util.EnvironmentTickCountSubtract(maintc);
1430 maintc = (int)(MinFrameTime * 1000) - maintc;
1421 1431
1422 m_lastUpdate = Util.EnvironmentTickCount(); 1432 m_lastUpdate = Util.EnvironmentTickCount();
1423 m_firstHeartbeat = false; 1433 m_firstHeartbeat = false;
1424 1434
1425 if (maintc > 0) 1435 if (maintc > 0)
1426 Thread.Sleep(maintc); 1436 Thread.Sleep(maintc);
1427 1437
1428 // Tell the watchdog that this thread is still alive 1438// if (frameMS > (int)(MinFrameTime * 1000))
1429 Watchdog.UpdateThread(); 1439// m_log.WarnFormat(
1430 } 1440// "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1441// frameMS,
1442// MinFrameTime * 1000,
1443// RegionInfo.RegionName);
1444 }
1445 }
1431 1446
1432 public void AddGroupTarget(SceneObjectGroup grp) 1447 public void AddGroupTarget(SceneObjectGroup grp)
1433 { 1448 {