[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-1-9' - 5 commits - loolwsd/DocumentBroker.cpp loolwsd/LOOLKit.cpp loolwsd/MessageQueue.cpp loolwsd/MessageQueue.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Wed Sep 14 22:52:55 UTC 2016


 loolwsd/DocumentBroker.cpp |   29 +++++++++++++---
 loolwsd/LOOLKit.cpp        |   39 ++++++++++++++++++++--
 loolwsd/MessageQueue.cpp   |   78 ++++++++++++++++++++++++++++++++++++++++++---
 loolwsd/MessageQueue.hpp   |   50 ++++++++++++++++++++++++++++
 4 files changed, 182 insertions(+), 14 deletions(-)

New commits:
commit 72c1988bc922ba7e5c9d072a2e16c62243a06bea
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Wed Sep 14 18:18:08 2016 -0400

    loolwsd: only prioritize tile messages and not tilecombine
    
    Change-Id: Ia292e5b499dd4409dc3a672e4d5360c868d6c71f
    (cherry picked from commit c01629ab2a52f6f4243df458b0505f231e392c49)

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 20428860cc7e3caa2d165df746dffc7443611031
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Wed Sep 14 18:02:03 2016 -0400

    loolwsd: remove cursor of unloading views
    
    Change-Id: I4281a5aa101f034007aa227bb18b14eeba806ea0
    (cherry picked from commit ad6d77cd3b4ccaeb1da16f100fb3bc3ac4d4c947)

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 bbcde1d091ba51beaae37402a10b757d41fc8e49
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Sep 11 13:18:22 2016 -0400

    loolwsd: queue -> tileQueue
    
    Change-Id: If61de6807fa7f52a703fe45948df911fe162f69a
    (cherry picked from commit 2db1db06c75fd67bbc73ba86707f89ee7e4f24c6)

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 2bcbdf3362433d3472e2c2ce6666172b5b52875f
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Wed Sep 14 17:42:50 2016 -0400

    loolwsd: tile prioritization per view cursor
    
    Change-Id: I1410b64982ac2db04e5a47d744a95b8d2eab5f7e
    (cherry picked from commit ece87da287433d665a175e92a576f00c639695a2)

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
commit 0108579f1da47a304650b5e43b0b046a3229735a
Author: Michael Meeks <michael at linux.site>
Date:   Wed Sep 14 22:15:43 2016 +0100

    Revert "loolwsd: don't combine tiles by row to allow for better culling"
    
    This breaks combine-tiles very significantly, viewing images
    in documents with this appears to show each tile scaling and
    rendering individually.
    
    This reverts commit 99d0ee2ac111e7199626f6c17fb7ce723dac9126.
    
    (cherry picked from commit 787ee1d2d2719f4fed161dd66eb7d3e21c512bd3)

diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp
index fe73d63..043218f 100644
--- a/loolwsd/DocumentBroker.cpp
+++ b/loolwsd/DocumentBroker.cpp
@@ -532,7 +532,8 @@ void DocumentBroker::handleTileCombinedRequest(TileCombined& tileCombined,
     Log::trace() << "TileCombined request for " << tileCombined.serialize() << Log::end;
 
     // Satisfy as many tiles from the cache.
-    std::vector<TileDesc> tiles;
+    // The rest, group by rows.
+    std::map<int, std::vector<TileDesc>> rows;
     for (auto& tile : tileCombined.getTiles())
     {
         std::unique_ptr<std::fstream> cachedTile = _tileCache->lookupTile(tile);
@@ -586,16 +587,34 @@ void DocumentBroker::handleTileCombinedRequest(TileCombined& tileCombined,
             }
         }
 
-        tiles.push_back(tile);
+        const auto tilePosY = tile.getTilePosY();
+        auto it = rows.lower_bound(tilePosY);
+        if (it != rows.end())
+        {
+            it->second.emplace_back(tile);
+        }
+        else
+        {
+            rows.emplace_hint(it, tilePosY, std::vector<TileDesc>({ tile }));
+        }
     }
 
-    for (auto& tile : tiles)
+    if (rows.empty())
     {
-        const auto tileMsg = tile.serialize("tile ");
+        // Done.
+        return;
+    }
+
+    auto& tiles = tileCombined.getTiles();
+    for (auto& row : rows)
+    {
+        tiles = row.second;
+        const auto tileMsg = tileCombined.serialize();
         Log::debug() << "TileCombined residual request for " << tileMsg << Log::end;
 
         // Forward to child to render.
-        _childProcess->getWebSocket()->sendFrame(tileMsg.data(), tileMsg.size());
+        const std::string request = "tilecombine " + tileMsg;
+        _childProcess->getWebSocket()->sendFrame(request.data(), request.size());
     }
 }
 


More information about the Libreoffice-commits mailing list