loolwsd/LOOLKit.cpp | 39 +++++++++++++++++++++-- loolwsd/MessageQueue.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++--- loolwsd/MessageQueue.hpp | 50 +++++++++++++++++++++++++++++- 3 files changed, 158 insertions(+), 9 deletions(-)
New commits: commit c01629ab2a52f6f4243df458b0505f231e392c49 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Wed Sep 14 18:18:08 2016 -0400 loolwsd: only prioritize tile messages and not tilecombine Change-Id: Ia292e5b499dd4409dc3a672e4d5360c868d6c71f diff --git a/loolwsd/MessageQueue.cpp b/loolwsd/MessageQueue.cpp index 756e568..0660d2b 100644 --- a/loolwsd/MessageQueue.cpp +++ b/loolwsd/MessageQueue.cpp @@ -158,6 +158,11 @@ void TileQueue::reprioritize(const CursorPosition& cursorPosition) { auto& it = _queue[i]; const std::string msg(it.data(), it.size()); + if (msg.compare(0, 5, "tile ") != 0) + { + continue; + } + auto tile = TileDesc::parse(msg); //FIXME: Expensive, avoid. if (tile.intersectsWithRect(cursorPosition.X, cursorPosition.Y, cursorPosition.Width, cursorPosition.Height)) @@ -178,6 +183,11 @@ void TileQueue::reprioritize(const CursorPosition& cursorPosition) bool TileQueue::priority(const std::string& tileMsg) { + if (tileMsg.compare(0, 5, "tile ") != 0) + { + return false; + } + auto tile = TileDesc::parse(tileMsg); //FIXME: Expensive, avoid. for (auto& pair : _cursorPositions) commit ad6d77cd3b4ccaeb1da16f100fb3bc3ac4d4c947 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Wed Sep 14 18:02:03 2016 -0400 loolwsd: remove cursor of unloading views Change-Id: I4281a5aa101f034007aa227bb18b14eeba806ea0 diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 387a0d5..583b173 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -940,6 +940,7 @@ private: // Broadcast the demise and removal of session. notifyOtherSessions(sessionId, "remview: " + std::to_string(session.getViewId())); + _tileQueue->removeCursorPosition(session.getViewId()); if (_loKitDocument == nullptr) { commit 2db1db06c75fd67bbc73ba86707f89ee7e4f24c6 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Sep 11 13:18:22 2016 -0400 loolwsd: queue -> tileQueue Change-Id: If61de6807fa7f52a703fe45948df911fe162f69a diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 2207e7d..387a0d5 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -398,14 +398,14 @@ public: const std::string& jailId, const std::string& docKey, const std::string& url, - std::shared_ptr<TileQueue> queue, + std::shared_ptr<TileQueue> tileQueue, const std::shared_ptr<WebSocket>& ws) : _multiView(std::getenv("LOK_VIEW_CALLBACK")), _loKit(loKit), _jailId(jailId), _docKey(docKey), _url(url), - _queue(std::move(queue)), + _tileQueue(std::move(tileQueue)), _ws(ws), _docPassword(""), _haveDocPassword(false), @@ -419,6 +419,7 @@ public: Log::info("Document ctor for url [" + _url + "] on child [" + _jailId + "] LOK_VIEW_CALLBACK=" + std::to_string(_multiView) + "."); assert(_loKit && _loKit->get()); + _callbackThread.start(*this); } @@ -1230,7 +1231,7 @@ private: { while (true) { - const auto input = pThis->_queue->get(); + const auto input = pThis->_tileQueue->get(); const std::string message(input.data(), input.size()); StringTokenizer tokens(message, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); @@ -1269,7 +1270,7 @@ private: std::string _renderOpts; std::shared_ptr<lok::Document> _loKitDocument; - std::shared_ptr<TileQueue> _queue; + std::shared_ptr<TileQueue> _tileQueue; std::shared_ptr<WebSocket> _ws; // Document password provided commit ece87da287433d665a175e92a576f00c639695a2 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Wed Sep 14 17:42:50 2016 -0400 loolwsd: tile prioritization per view cursor Change-Id: I1410b64982ac2db04e5a47d744a95b8d2eab5f7e diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 73ade5b..2207e7d 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -813,6 +813,35 @@ private: std::unique_lock<std::mutex> lock(pDescr->Doc->_mutex); + if (nType == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR || + nType == LOK_CALLBACK_CELL_CURSOR) + { + Poco::StringTokenizer tokens(payload, ",", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); + auto cursorX = std::stoi(tokens[0]); + auto cursorY = std::stoi(tokens[1]); + auto cursorWidth = std::stoi(tokens[2]); + auto cursorHeight = std::stoi(tokens[3]); + + pDescr->Doc->_tileQueue->updateCursorPosition(0, 0, cursorX, cursorY, cursorWidth, cursorHeight); + } + else if (nType == LOK_CALLBACK_INVALIDATE_VIEW_CURSOR || + nType == LOK_CALLBACK_CELL_VIEW_CURSOR) + { + Poco::JSON::Parser parser; + const auto result = parser.parse(payload); + const auto& command = result.extract<Poco::JSON::Object::Ptr>(); + auto viewId = command->get("viewId").toString(); + auto part = command->get("part").toString(); + auto text = command->get("rectangle").toString(); + Poco::StringTokenizer tokens(text, ",", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); + auto cursorX = std::stoi(tokens[0]); + auto cursorY = std::stoi(tokens[1]); + auto cursorWidth = std::stoi(tokens[2]); + auto cursorHeight = std::stoi(tokens[3]); + + pDescr->Doc->_tileQueue->updateCursorPosition(std::stoi(viewId), std::stoi(part), cursorX, cursorY, cursorWidth, cursorHeight); + } + // Forward to the same view only. // Demultiplexing is done by Core. // TODO: replace with a map to be faster. diff --git a/loolwsd/MessageQueue.cpp b/loolwsd/MessageQueue.cpp index 027051e..756e568 100644 --- a/loolwsd/MessageQueue.cpp +++ b/loolwsd/MessageQueue.cpp @@ -11,6 +11,7 @@ #include <algorithm> +#include <TileDesc.hpp> #include <Log.hpp> MessageQueue::~MessageQueue() @@ -95,9 +96,10 @@ void BasicTileQueue::put_impl(const Payload& value) void TileQueue::put_impl(const Payload& value) { + const auto msg = std::string(value.data(), value.size()); + Log::trace() << "Putting [" << msg << "]" << Log::end; if (!_queue.empty()) { - const auto msg = std::string(value.data(), value.size()); if (msg.compare(0, 4, "tile") == 0 || msg.compare(0, 10, "tilecombine") == 0) { const auto newMsg = msg.substr(0, msg.find(" ver")); @@ -117,18 +119,76 @@ void TileQueue::put_impl(const Payload& value) auto& it = _queue[i]; const std::string old(it.data(), it.size()); const auto oldMsg = old.substr(0, old.find(" ver")); - Log::error(std::to_string(i) + ": " + oldMsg); + Log::trace() << "TileQueue #" << i << ": " << oldMsg << Log::end; if (newMsg == oldMsg) { - Log::trace() << "Replacing duplicate tile: " << oldMsg << " -> " << newMsg << Log::end; + Log::debug() << "Replacing duplicate tile: " << oldMsg << " -> " << newMsg << Log::end; _queue[i] = value; + + if (priority(msg)) + { + // Bump to top. + Log::debug() << "And bumping tile to top: " << msg << Log::end; + _queue.erase(_queue.begin() + i); + _queue.push_front(value); + } + return; } } } } - BasicTileQueue::put_impl(value); + if (priority(msg)) + { + Log::debug() << "Priority tile [" << msg << "]" << Log::end; + _queue.push_front(value); + } + else + { + BasicTileQueue::put_impl(value); + } +} + +/// Bring the underlying tile (if any) to the top. +/// There should be only one overlapping tile at most. +void TileQueue::reprioritize(const CursorPosition& cursorPosition) +{ + for (size_t i = 0; i < _queue.size(); ++i) + { + auto& it = _queue[i]; + const std::string msg(it.data(), it.size()); + auto tile = TileDesc::parse(msg); //FIXME: Expensive, avoid. + + if (tile.intersectsWithRect(cursorPosition.X, cursorPosition.Y, cursorPosition.Width, cursorPosition.Height)) + { + if (i != 0) + { + // Bump to top. + Log::trace() << "Bumping tile to top: " << msg << Log::end; + const Payload payload = it; + _queue.erase(_queue.begin() + i); + _queue.push_front(payload); + } + + return; + } + } +} + +bool TileQueue::priority(const std::string& tileMsg) +{ + auto tile = TileDesc::parse(tileMsg); //FIXME: Expensive, avoid. + + for (auto& pair : _cursorPositions) + { + if (tile.intersectsWithRect(pair.second.X, pair.second.Y, pair.second.Width, pair.second.Height)) + { + return true; + } + } + + return false; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/MessageQueue.hpp b/loolwsd/MessageQueue.hpp index 8330f0f..f1b14b2 100644 --- a/loolwsd/MessageQueue.hpp +++ b/loolwsd/MessageQueue.hpp @@ -11,8 +11,9 @@ #define INCLUDED_MESSAGEQUEUE_HPP #include <condition_variable> -#include <mutex> #include <deque> +#include <map> +#include <mutex> #include <vector> /** Thread-safe message queue (FIFO). @@ -85,8 +86,55 @@ that the ones closest to the cursor position are returned first. */ class TileQueue : public BasicTileQueue { +private: + + class CursorPosition + { + public: + int Part; + int X; + int Y; + int Width; + int Height; + }; + +public: + + void updateCursorPosition(int viewId, int part, int x, int y, int width, int height) + { + auto cursorPosition = CursorPosition({part, x, y, width, height}); + auto it = _cursorPositions.find(viewId); + if (it != _cursorPositions.end()) + { + it->second = cursorPosition; + } + else + { + _cursorPositions[viewId] = cursorPosition; + } + + reprioritize(cursorPosition); + } + + void removeCursorPosition(int viewId) + { + _cursorPositions.erase(viewId); + } + protected: virtual void put_impl(const Payload& value) override; + +private: + + /// Bring the underlying tile (if any) to the top. + /// There should be only one overlapping tile at most. + void reprioritize(const CursorPosition& cursorPosition); + + /// Check if the given tile msg underlies a cursor. + bool priority(const std::string& tileMsg); + +private: + std::map<int, CursorPosition> _cursorPositions; }; #endif _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits