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:
parent
31e4d54d28
commit
686f04ef2e
2 changed files with 18 additions and 8 deletions
|
@ -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++;
|
||||||
|
|
|
@ -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 " : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue