[Libreoffice-commits] online.git: loolwsd/LOOLKit.cpp loolwsd/MessageQueue.cpp loolwsd/MessageQueue.hpp loolwsd/TileDesc.hpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Wed Sep 21 05:00:07 UTC 2016
loolwsd/LOOLKit.cpp | 4 ++
loolwsd/MessageQueue.cpp | 74 ++++++++++++++++++++++++++++++++++++++++-------
loolwsd/MessageQueue.hpp | 4 +-
loolwsd/TileDesc.hpp | 42 ++++++++++++++++++++++++++
4 files changed, 113 insertions(+), 11 deletions(-)
New commits:
commit e9f37433d7aafb0ac91e240cc4adab758036508f
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Thu Sep 15 08:40:26 2016 -0400
loolwsd: combine tiles before rendering to reduce latency
Change-Id: I5af2d2a9ddf3b5a3db5bc5f0835687d7cae5b17c
Reviewed-on: https://gerrit.libreoffice.org/29115
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index a04945c..3b4e39b 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -1279,6 +1279,10 @@ private:
{
pThis->renderCombinedTiles(tokens, pThis->_ws);
}
+ else
+ {
+ Log::error("Unexpected tile request: [" + message + "].");
+ }
}
}
catch (const std::exception& exc)
diff --git a/loolwsd/MessageQueue.cpp b/loolwsd/MessageQueue.cpp
index 0660d2b..16946e2 100644
--- a/loolwsd/MessageQueue.cpp
+++ b/loolwsd/MessageQueue.cpp
@@ -48,6 +48,8 @@ void MessageQueue::remove_if(const std::function<bool(const Payload&)>& pred)
void MessageQueue::put_impl(const Payload& value)
{
+ const auto msg = std::string(value.data(), value.size());
+ Log::trace() << "Pushing into MQ [" << msg << "]" << Log::end;
_queue.push_back(value);
}
@@ -73,6 +75,8 @@ void BasicTileQueue::put_impl(const Payload& value)
const auto msg = std::string(&value[0], value.size());
if (msg == "canceltiles")
{
+ Log::error("Unexpected canceltiles!");
+
// remove all the existing tiles from the queue
_queue.erase(std::remove_if(_queue.begin(), _queue.end(),
[](const Payload& v)
@@ -104,16 +108,6 @@ void TileQueue::put_impl(const Payload& value)
{
const auto newMsg = msg.substr(0, msg.find(" ver"));
- // TODO: implement a real re-ordering here, so that the tiles closest to
- // the cursor are returned first.
- // * we will want to put just a general "tile" message to the queue
- // * add a std::set that handles the tiles
- // * change the get_impl() to decide which tile is the correct one to
- // be returned
- // * we will also need to be informed about the position of the cursor
- // so that get_impl() returns optimal results
- //
- // For now: just don't put duplicates into the queue
for (size_t i = 0; i < _queue.size(); ++i)
{
auto& it = _queue[i];
@@ -201,4 +195,64 @@ bool TileQueue::priority(const std::string& tileMsg)
return false;
}
+MessageQueue::Payload TileQueue::get_impl()
+{
+ std::vector<TileDesc> tiles;
+ const auto front = _queue.front();
+ _queue.pop_front();
+
+ auto msg = std::string(front.data(), front.size());
+ Log::trace() << "MessageQueue Get, Size: " << _queue.size() << ", Front: " << msg << Log::end;
+
+ if (msg.compare(0, 5, "tile ") != 0 || msg.find("id=") != std::string::npos)
+ {
+ // Don't combine non-tiles or tiles with id.
+ Log::trace() << "MessageQueue res: " << msg << Log::end;
+ return front;
+ }
+
+ tiles.emplace_back(TileDesc::parse(msg));
+
+ // Combine as many tiles as possible with the top one.
+ for (size_t i = 0; i < _queue.size(); )
+ {
+ auto& it = _queue[i];
+ msg = std::string(it.data(), it.size());
+ if (msg.compare(0, 5, "tile ") != 0 ||
+ msg.find("id=") != std::string::npos)
+ {
+ // Don't combine non-tiles or tiles with id.
+ continue;
+ }
+
+ auto tile2 = TileDesc::parse(msg);
+ bool found = false;
+ Log::trace() << "combining?: " << msg << Log::end;
+
+ // Check if adjacent tiles.
+ for (auto& tile : tiles)
+ {
+ if (tile.isAdjacent(tile2))
+ {
+ tiles.emplace_back(tile2);
+ _queue.erase(_queue.begin() + i);
+ found = true;
+ break;
+ }
+ }
+
+ i += !found;
+ }
+
+ if (tiles.size() == 1)
+ {
+ msg = tiles[0].serialize("tile");
+ return Payload(msg.data(), msg.data() + msg.size());
+ }
+
+ auto tileCombined = TileCombined::create(tiles).serialize("tilecombine");
+ Log::trace() << "MessageQueue res: " << tileCombined << Log::end;
+ return Payload(tileCombined.data(), tileCombined.data() + tileCombined.size());
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/MessageQueue.hpp b/loolwsd/MessageQueue.hpp
index f1b14b2..4d1efba 100644
--- a/loolwsd/MessageQueue.hpp
+++ b/loolwsd/MessageQueue.hpp
@@ -58,7 +58,7 @@ protected:
bool wait_impl() const;
- Payload get_impl();
+ virtual Payload get_impl();
void clear_impl();
@@ -124,6 +124,8 @@ public:
protected:
virtual void put_impl(const Payload& value) override;
+ virtual Payload get_impl() override;
+
private:
/// Bring the underlying tile (if any) to the top.
diff --git a/loolwsd/TileDesc.hpp b/loolwsd/TileDesc.hpp
index 0258645..20ac257 100644
--- a/loolwsd/TileDesc.hpp
+++ b/loolwsd/TileDesc.hpp
@@ -10,6 +10,7 @@
#ifndef INCLUDED_TILEDESC_HPP
#define INCLUDED_TILEDESC_HPP
+#include <cassert>
#include <map>
#include <sstream>
#include <string>
@@ -60,6 +61,7 @@ public:
void setVersion(const int ver) { _ver = ver; }
int getImgSize() const { return _imgSize; }
void setImgSize(const int imgSize) { _imgSize = imgSize; }
+
bool intersectsWithRect(int x, int y, int w, int h) const
{
return x + w >= getTilePosX() &&
@@ -68,6 +70,26 @@ public:
y <= getTilePosY() + getTileHeight();
}
+ bool intersects(const TileDesc& other) const
+ {
+ return intersectsWithRect(other.getTilePosX(), other.getTilePosY(),
+ other.getTileWidth(), other.getTileHeight());
+ }
+
+ bool isAdjacent(const TileDesc& other) const
+ {
+ if (other.getPart() != getPart() ||
+ other.getWidth() != getWidth() ||
+ other.getHeight() != getHeight() ||
+ other.getTileWidth() != getTileWidth() ||
+ other.getTileHeight() != getTileHeight())
+ {
+ return false;
+ }
+
+ return intersects(other);
+ }
+
/// Serialize this instance into a string.
/// Optionally prepend a prefix.
std::string serialize(const std::string& prefix = "") const
@@ -334,6 +356,26 @@ public:
return parse(tokens);
}
+ static
+ TileCombined create(const std::vector<TileDesc>& tiles)
+ {
+ assert(!tiles.empty());
+
+ std::ostringstream xs;
+ std::ostringstream ys;
+ int ver = -1;
+
+ for (auto& tile : tiles)
+ {
+ xs << tile.getTilePosX() << ',';
+ ys << tile.getTilePosY() << ',';
+ ver = std::max(tile.getVersion(), ver);
+ }
+
+ return TileCombined(tiles[0].getPart(), tiles[0].getWidth(), tiles[0].getHeight(),
+ xs.str(), ys.str(), tiles[0].getTileWidth(), tiles[0].getTileHeight(), ver, "", -1);
+ }
+
private:
std::vector<TileDesc> _tiles;
int _part;
More information about the Libreoffice-commits
mailing list