Skip to content

Commit

Permalink
Assertion in DocumentBroker::sendRequestedTiles fails on running cypr…
Browse files Browse the repository at this point in the history
…ess impress tests

make -C cypress_test check-desktop

asserts seen in cypress_test/cypress/wsd_logs/coolwsd_output.log of:

coolwsd: wsd/DocumentBroker.cpp:3134: void DocumentBroker::sendTileCombine(const TileCombined&): Assertion `!newTileCombined.hasDuplicates()' failed.

If we check for, and don't reuse, an old request with a different
NormalizedViewId then we could end up with multiple requests with
different NormalizedViewIds that end up in the same final tilecombine.

similarly there was no check for different modes ending up in the
same tilecombine.

just split out the logic we have to see if two tiles have the same
properties that appear as a shared set of properties for tilecombine
and use that in the two relevant places.

Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: Ieb2ee0e85f124dd57c6b050e5b669dd808cf6bbf
  • Loading branch information
caolanm committed Oct 17, 2023
1 parent bb24631 commit 395d6c9
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 16 deletions.
20 changes: 5 additions & 15 deletions wsd/DocumentBroker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3206,10 +3206,7 @@ void DocumentBroker::handleTileCombinedRequest(TileCombined& tileCombined, bool
{
if(oldTile.getTilePosX() == newTile.getTilePosX() &&
oldTile.getTilePosY() == newTile.getTilePosY() &&
oldTile.getNormalizedViewId() == newTile.getNormalizedViewId() &&
oldTile.getPart() == newTile.getPart() &&
oldTile.getTileWidth() == newTile.getTileWidth() &&
oldTile.getTileHeight() == newTile.getTileHeight())
oldTile.sameTileCombineParams(newTile))
{
oldTile.setVersion(newTile.getVersion());
oldTile.setOldWireId(newTile.getOldWireId());
Expand Down Expand Up @@ -3328,13 +3325,6 @@ void DocumentBroker::handleMediaRequest(std::string range,
}
}

static bool samePartAndSize(const TileDesc& tileA, const TileDesc& tileB)
{
return tileA.getPart() == tileB.getPart() &&
tileA.getTileWidth() == tileB.getTileWidth() &&
tileA.getTileHeight() == tileB.getTileHeight();
}

void DocumentBroker::sendRequestedTiles(const std::shared_ptr<ClientSession>& session)
{
std::unique_lock<std::mutex> lock(_mutex);
Expand Down Expand Up @@ -3419,7 +3409,7 @@ void DocumentBroker::sendRequestedTiles(const std::shared_ptr<ClientSession>& se
LOG_TRC("Forcing keyframe for tile was oldwid " << tile.getOldWireId());
tile.setOldWireId(0);
}
allSamePartAndSize &= tilesNeedsRendering.empty() || samePartAndSize(tilesNeedsRendering.back(), tile);
allSamePartAndSize &= tilesNeedsRendering.empty() || tile.sameTileCombineParams(tilesNeedsRendering.back());
tilesNeedsRendering.push_back(tile);
_debugRenderedTileCount++;
}
Expand All @@ -3434,12 +3424,12 @@ void DocumentBroker::sendRequestedTiles(const std::shared_ptr<ClientSession>& se
{
if (allSamePartAndSize)
{
// typically all requests are for the same part and tilesize
// typically all requests match sufficiently to form a single tilecombine
sendTileCombine(TileCombined::create(tilesNeedsRendering));
}
else
{
// but if not, split them by part+tilesize to send a separate
// but if not, split them by matching groups of requests to send a separate
// tilecombine for each group
std::vector<std::vector<TileDesc>> groupsNeedsRendering(1);
auto it = tilesNeedsRendering.begin();
Expand All @@ -3451,7 +3441,7 @@ void DocumentBroker::sendRequestedTiles(const std::shared_ptr<ClientSession>& se
// check if tile should go into an existing group bucket
for (size_t i = 0; i < groupsNeedsRendering.size(); ++i)
{
if (samePartAndSize(*it, groupsNeedsRendering[i][0]))
if (it->sameTileCombineParams(groupsNeedsRendering[i][0]))
{
groupsNeedsRendering[i].push_back(*it);
inserted = true;
Expand Down
11 changes: 10 additions & 1 deletion wsd/TileDesc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ class TileDesc final
return intersects(other);
}

bool onSameRow(const TileDesc& other) const
// return false if the TileDesc cannot appear in the same TileCombine
// because their fields differ for the shared tilecombine case
bool sameTileCombineParams(const TileDesc& other) const
{
if (other.getPart() != getPart() ||
other.getEditMode() != getEditMode() ||
Expand All @@ -175,6 +177,13 @@ class TileDesc final
{
return false;
}
return true;
}

bool onSameRow(const TileDesc& other) const
{
if (!sameTileCombineParams(other))
return false;

return other.getTilePosY() + other.getTileHeight() >= getTilePosY() &&
other.getTilePosY() <= getTilePosY() + getTileHeight();
Expand Down

0 comments on commit 395d6c9

Please sign in to comment.