deltas: force keyframe on the next render if deltas get too large.

This should save server memory, and also complexity de-compressing
and also browser CPU re-rendering deltas from raw fzstd compressed
pixels.

Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
Change-Id: I12281fb85416a059d31b5df52b9ec8d79e4af316
This commit is contained in:
Michael Meeks 2024-06-04 15:51:33 +01:00 committed by Caolán McNamara
parent 31e4d54d28
commit 686f04ef2e
2 changed files with 18 additions and 8 deletions

View file

@ -3348,7 +3348,7 @@ void DocumentBroker::handleTileRequest(const StringVector &tokens, bool forceKey
return;
}
if (!cachedTile)
if (!cachedTile || cachedTile->tooLarge())
tile.forceKeyframe();
auto now = std::chrono::steady_clock::now();
@ -3411,9 +3411,10 @@ void DocumentBroker::handleTileCombinedRequest(TileCombined& tileCombined, bool
}
Tile cachedTile = _tileCache->lookupTile(tile);
if(!cachedTile || !cachedTile->isValid())
bool tooLarge = cachedTile && cachedTile->tooLarge();
if(!cachedTile || !cachedTile->isValid() || tooLarge)
{
if (!cachedTile)
if (!cachedTile || tooLarge)
tile.forceKeyframe();
tilesNeedsRendering.push_back(tile);
_debugRenderedTileCount++;

View file

@ -109,8 +109,6 @@ struct TileData
}
else
{
// FIXME: too many/large deltas means we should reset -
// but not here - when requesting the tiles.
_wids.push_back(id);
_offsets.push_back(_deltas.size());
if (dataSize > 1)
@ -126,6 +124,16 @@ struct TileData
return size() - oldCacheSize;
}
// At what point do we stop stacking deltas & render a keyframe ?
bool tooLarge() const
{
// keyframe gets a free size pass
if (_offsets.size() <= 1)
return false;
size_t deltaSize = size() - _offsets[1];
return deltaSize > 128 * 1024; // deltas should be cumulatively small.
}
bool isPng() const { return (_deltas.size() > 1 &&
_deltas[0] == (char)0x89); }
@ -143,18 +151,18 @@ struct TileData
std::vector<size_t> _offsets; // offset of the start of data
BlobData _deltas; // first item is a key-frame, followed by deltas at _offsets
size_t size()
size_t size() const
{
return _deltas.size();
}
const BlobData &data()
const BlobData &data() const
{
return _deltas;
}
/// if we send changes since this seq - do we need to first send the keyframe ?
bool needsKeyframe(TileWireId since)
bool needsKeyframe(TileWireId since) const
{
return since < _wids[0];
}
@ -199,6 +207,7 @@ struct TileData
{
os << i << ": " << _wids[i] << " -> " << _offsets[i] << " ";
}
os << (tooLarge() ? "too-large " : "");
}
}
};