mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 08:44:01 +00:00
Level: Batch light updates at the end of the tick to amortize CPU cost (#2429)
this produces a 5x performance improvement for lighting updates during water flow, and 25% improvement for lava flow.
This commit is contained in:
parent
a9fc67663c
commit
09dea035d4
@ -247,6 +247,11 @@ class Level implements ChunkManager, Metadatable{
|
||||
/** @var bool */
|
||||
private $closed = false;
|
||||
|
||||
/** @var BlockLightUpdate|null */
|
||||
private $blockLightUpdate = null;
|
||||
/** @var SkyLightUpdate|null */
|
||||
private $skyLightUpdate = null;
|
||||
|
||||
public static function chunkHash(int $x, int $z) : int{
|
||||
return (($x & 0xFFFFFFFF) << 32) | ($z & 0xFFFFFFFF);
|
||||
}
|
||||
@ -764,6 +769,8 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->tickChunks();
|
||||
$this->timings->doTickTiles->stopTiming();
|
||||
|
||||
$this->executeQueuedLightUpdates();
|
||||
|
||||
if(count($this->changedBlocks) > 0){
|
||||
if(count($this->players) > 0){
|
||||
foreach($this->changedBlocks as $index => $blocks){
|
||||
@ -1417,22 +1424,21 @@ class Level implements ChunkManager, Metadatable{
|
||||
$newHeightMap = $oldHeightMap;
|
||||
}
|
||||
|
||||
$update = new SkyLightUpdate($this);
|
||||
|
||||
if($this->skyLightUpdate === null){
|
||||
$this->skyLightUpdate = new SkyLightUpdate($this);
|
||||
}
|
||||
if($newHeightMap > $oldHeightMap){ //Heightmap increase, block placed, remove sky light
|
||||
for($i = $y; $i >= $oldHeightMap; --$i){
|
||||
$update->setAndUpdateLight($x, $i, $z, 0); //Remove all light beneath, adjacent recalculation will handle the rest.
|
||||
$this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 0); //Remove all light beneath, adjacent recalculation will handle the rest.
|
||||
}
|
||||
}elseif($newHeightMap < $oldHeightMap){ //Heightmap decrease, block changed or removed, add sky light
|
||||
for($i = $y; $i >= $newHeightMap; --$i){
|
||||
$update->setAndUpdateLight($x, $i, $z, 15);
|
||||
$this->skyLightUpdate->setAndUpdateLight($x, $i, $z, 15);
|
||||
}
|
||||
}else{ //No heightmap change, block changed "underground"
|
||||
$update->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$sourceId]));
|
||||
$this->skyLightUpdate->setAndUpdateLight($x, $y, $z, max(0, $this->getHighestAdjacentBlockSkyLight($x, $y, $z) - BlockFactory::$lightFilter[$sourceId]));
|
||||
}
|
||||
|
||||
$update->execute();
|
||||
|
||||
$this->timings->doBlockSkyLightUpdates->stopTiming();
|
||||
}
|
||||
|
||||
@ -1462,13 +1468,30 @@ class Level implements ChunkManager, Metadatable{
|
||||
$id = $this->getBlockIdAt($x, $y, $z);
|
||||
$newLevel = max(BlockFactory::$light[$id], $this->getHighestAdjacentBlockLight($x, $y, $z) - BlockFactory::$lightFilter[$id]);
|
||||
|
||||
$update = new BlockLightUpdate($this);
|
||||
$update->setAndUpdateLight($x, $y, $z, $newLevel);
|
||||
$update->execute();
|
||||
if($this->blockLightUpdate === null){
|
||||
$this->blockLightUpdate = new BlockLightUpdate($this);
|
||||
}
|
||||
$this->blockLightUpdate->setAndUpdateLight($x, $y, $z, $newLevel);
|
||||
|
||||
$this->timings->doBlockLightUpdates->stopTiming();
|
||||
}
|
||||
|
||||
public function executeQueuedLightUpdates() : void{
|
||||
if($this->blockLightUpdate !== null){
|
||||
$this->timings->doBlockLightUpdates->startTiming();
|
||||
$this->blockLightUpdate->execute();
|
||||
$this->blockLightUpdate = null;
|
||||
$this->timings->doBlockLightUpdates->stopTiming();
|
||||
}
|
||||
|
||||
if($this->skyLightUpdate !== null){
|
||||
$this->timings->doBlockSkyLightUpdates->startTiming();
|
||||
$this->skyLightUpdate->execute();
|
||||
$this->skyLightUpdate = null;
|
||||
$this->timings->doBlockSkyLightUpdates->stopTiming();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on Vector3 the data from a Block object,
|
||||
* does block updates and puts the changes to the send queue.
|
||||
|
Loading…
x
Reference in New Issue
Block a user