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; return;
} }
if (!cachedTile) if (!cachedTile || cachedTile->tooLarge())
tile.forceKeyframe(); tile.forceKeyframe();
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
@ -3411,9 +3411,10 @@ void DocumentBroker::handleTileCombinedRequest(TileCombined& tileCombined, bool
} }
Tile cachedTile = _tileCache->lookupTile(tile); 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(); tile.forceKeyframe();
tilesNeedsRendering.push_back(tile); tilesNeedsRendering.push_back(tile);
_debugRenderedTileCount++; _debugRenderedTileCount++;

View file

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