[Libreoffice-commits] online.git: 9 commits - loleaflet/src loolwsd/ChildProcessSession.cpp loolwsd/ChildProcessSession.hpp loolwsd/LOKitClient.cpp loolwsd/loolmap.c loolwsd/LOOLProtocol.cpp loolwsd/LOOLProtocol.hpp loolwsd/LOOLSession.hpp loolwsd/loolwsd.spec.in loolwsd/Makefile.am loolwsd/MasterProcessSession.cpp loolwsd/MasterProcessSession.hpp loolwsd/Rectangle.hpp loolwsd/Util.cpp loolwsd/Util.hpp
Andras Timar
andras.timar at collabora.com
Thu Jan 14 05:01:54 PST 2016
loleaflet/src/layer/tile/CalcTileLayer.js | 40 ++++----
loleaflet/src/layer/tile/ImpressTileLayer.js | 40 ++++----
loleaflet/src/layer/tile/WriterTileLayer.js | 40 ++++----
loolwsd/ChildProcessSession.cpp | 135 ++++++++++++++++++++++++++-
loolwsd/ChildProcessSession.hpp | 2
loolwsd/LOKitClient.cpp | 3
loolwsd/LOOLProtocol.cpp | 15 ++-
loolwsd/LOOLProtocol.hpp | 2
loolwsd/LOOLSession.hpp | 2
loolwsd/Makefile.am | 2
loolwsd/MasterProcessSession.cpp | 13 ++
loolwsd/MasterProcessSession.hpp | 2
loolwsd/Rectangle.hpp | 81 ++++++++++++++++
loolwsd/Util.cpp | 25 +++--
loolwsd/Util.hpp | 6 +
loolwsd/loolmap.c | 8 -
loolwsd/loolwsd.spec.in | 3
17 files changed, 348 insertions(+), 71 deletions(-)
New commits:
commit 3ec262e01b23d5f0bff716f12faacd7831170f2a
Author: Andras Timar <andras.timar at collabora.com>
Date: Thu Jan 14 13:45:33 2016 +0100
loolwsd: add loolbroker, loolkit and loolmap to rpm
diff --git a/loolwsd/loolwsd.spec.in b/loolwsd/loolwsd.spec.in
index a45eea4..9028a2b 100644
--- a/loolwsd/loolwsd.spec.in
+++ b/loolwsd/loolwsd.spec.in
@@ -56,6 +56,9 @@ echo "0 0 */1 * * root find /var/cache/loolwsd -name \"*.png\" -a -atime +10 -ex
%files
/usr/bin/loolwsd
/usr/bin/loolwsd-systemplate-setup
+/usr/bin/loolmap
+/usr/bin/loolkit
+/usr/bin/loolbroker
%{_unitdir}/loolwsd.service
/var/adm/fillup-templates/sysconfig.loolwsd
/etc/cron.d/loolwsd.cron
commit 7cf9cdd4c8cae3d6b5b2e0ffdf033c85629a6a7c
Author: Andras Timar <andras.timar at collabora.com>
Date: Thu Jan 14 13:43:54 2016 +0100
loolwsd: add QueueHandler.hpp to dist tarball
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index b07c4b7..0da19e6 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -29,7 +29,7 @@ loolmap_SOURCES = loolmap.c
noinst_HEADERS = LOKitHelper.hpp LOOLProtocol.hpp LOOLSession.hpp MasterProcessSession.hpp ChildProcessSession.hpp \
LOOLWSD.hpp LoadTest.hpp MessageQueue.hpp TileCache.hpp Util.hpp Png.hpp Common.hpp Capabilities.hpp \
- Rectangle.hpp \
+ Rectangle.hpp QueueHandler.hpp \
bundled/include/LibreOfficeKit/LibreOfficeKit.h bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
bundled/include/LibreOfficeKit/LibreOfficeKitInit.h bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h
commit 207925266caa5bf447a35fbe0062423ecfe714b1
Author: Andras Timar <andras.timar at collabora.com>
Date: Wed Jan 13 21:10:07 2016 +0100
loolwsd: add Rectangle.hpp to dist tarball
(cherry picked from commit 69222ace7a67ca8adc9a21a988436aad92883b51)
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index d32bd3d..b07c4b7 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -29,7 +29,7 @@ loolmap_SOURCES = loolmap.c
noinst_HEADERS = LOKitHelper.hpp LOOLProtocol.hpp LOOLSession.hpp MasterProcessSession.hpp ChildProcessSession.hpp \
LOOLWSD.hpp LoadTest.hpp MessageQueue.hpp TileCache.hpp Util.hpp Png.hpp Common.hpp Capabilities.hpp \
- QueueHandler.hpp \
+ Rectangle.hpp \
bundled/include/LibreOfficeKit/LibreOfficeKit.h bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
bundled/include/LibreOfficeKit/LibreOfficeKitInit.h bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h
commit c22842442bd769933d3c963864a54d95ef070429
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Tue Jan 12 12:20:53 2016 +0100
Send tilecombine command when invalidating tiles
(cherry picked from commit 2f58be7613f2bd663693b7022f7ca5e38f5c1f41)
diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 8ac137e..6ee5cb3 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -30,7 +30,10 @@ L.CalcTileLayer = L.TileLayer.extend({
var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
- var toRequest = [];
+
+ var tilePositionsX = "";
+ var tilePositionsY = "";
+ var needsNewTiles = false;
for (var key in this._tiles) {
var coords = this._tiles[key].coords;
@@ -45,15 +48,14 @@ L.CalcTileLayer = L.TileLayer.extend({
this._tiles[key]._invalidCount = 1;
}
if (visibleArea.intersects(bounds)) {
- var msg = 'tile ' +
- 'part=' + coords.part + ' ' +
- 'width=' + this._tileSize + ' ' +
- 'height=' + this._tileSize + ' ' +
- 'tileposx=' + tileTopLeft.x + ' ' +
- 'tileposy=' + tileTopLeft.y + ' ' +
- 'tilewidth=' + this._tileWidthTwips + ' ' +
- 'tileheight=' + this._tileHeightTwips;
- toRequest.push({msg: msg, key: key, coords: coords});
+ if (tilePositionsX !== "")
+ tilePositionsX += ',';
+ tilePositionsX += tileTopLeft.x;
+
+ if (tilePositionsY !== "")
+ tilePositionsY += ',';
+ tilePositionsY += tileTopLeft.y;
+ needsNewTiles = true;
}
else {
// tile outside of the visible area, just remove it
@@ -63,12 +65,18 @@ L.CalcTileLayer = L.TileLayer.extend({
}
}
- // Sort tiles so that we request those closer to the cursor first
- var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
- cursorPos = cursorPos.divideBy(this._tileSize);
- toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
- for (var i = 0; i < toRequest.length; i++) {
- this._map._socket.sendMessage(toRequest[i].msg, toRequest[i].key);
+ if (needsNewTiles)
+ {
+ var message = 'tilecombine ' +
+ 'part=' + command.part + ' ' +
+ 'width=' + this._tileSize + ' ' +
+ 'height=' + this._tileSize + ' ' +
+ 'tileposx=' + tilePositionsX + ' ' +
+ 'tileposy=' + tilePositionsY + ' ' +
+ 'tilewidth=' + this._tileWidthTwips + ' ' +
+ 'tileheight=' + this._tileHeightTwips;
+
+ this._map._socket.sendMessage(message, "");
}
for (key in this._tileCache) {
diff --git a/loleaflet/src/layer/tile/ImpressTileLayer.js b/loleaflet/src/layer/tile/ImpressTileLayer.js
index 85cc275..3e76cbe 100644
--- a/loleaflet/src/layer/tile/ImpressTileLayer.js
+++ b/loleaflet/src/layer/tile/ImpressTileLayer.js
@@ -21,7 +21,10 @@ L.ImpressTileLayer = L.TileLayer.extend({
var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
- var toRequest = [];
+
+ var tilePositionsX = "";
+ var tilePositionsY = "";
+ var needsNewTiles = false;
for (var key in this._tiles) {
var coords = this._tiles[key].coords;
@@ -36,15 +39,14 @@ L.ImpressTileLayer = L.TileLayer.extend({
this._tiles[key]._invalidCount = 1;
}
if (visibleArea.intersects(bounds)) {
- var msg = 'tile ' +
- 'part=' + coords.part + ' ' +
- 'width=' + this._tileSize + ' ' +
- 'height=' + this._tileSize + ' ' +
- 'tileposx=' + tileTopLeft.x + ' ' +
- 'tileposy=' + tileTopLeft.y + ' ' +
- 'tilewidth=' + this._tileWidthTwips + ' ' +
- 'tileheight=' + this._tileHeightTwips;
- toRequest.push({msg: msg, key: key, coords: coords});
+ if (tilePositionsX !== "")
+ tilePositionsX += ',';
+ tilePositionsX += tileTopLeft.x;
+
+ if (tilePositionsY !== "")
+ tilePositionsY += ',';
+ tilePositionsY += tileTopLeft.y;
+ needsNewTiles = true;
}
else {
// tile outside of the visible area, just remove it
@@ -54,12 +56,18 @@ L.ImpressTileLayer = L.TileLayer.extend({
}
}
- // Sort tiles so that we request those closer to the cursor first
- var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
- cursorPos = cursorPos.divideBy(this._tileSize);
- toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
- for (var i = 0; i < toRequest.length; i++) {
- this._map._socket.sendMessage(toRequest[i].msg, toRequest[i].key);
+ if (needsNewTiles)
+ {
+ var message = 'tilecombine ' +
+ 'part=' + command.part + ' ' +
+ 'width=' + this._tileSize + ' ' +
+ 'height=' + this._tileSize + ' ' +
+ 'tileposx=' + tilePositionsX + ' ' +
+ 'tileposy=' + tilePositionsY + ' ' +
+ 'tilewidth=' + this._tileWidthTwips + ' ' +
+ 'tileheight=' + this._tileHeightTwips;
+
+ this._map._socket.sendMessage(message, "");
}
for (key in this._tileCache) {
diff --git a/loleaflet/src/layer/tile/WriterTileLayer.js b/loleaflet/src/layer/tile/WriterTileLayer.js
index 7dca8ea..3c0ad8f 100644
--- a/loleaflet/src/layer/tile/WriterTileLayer.js
+++ b/loleaflet/src/layer/tile/WriterTileLayer.js
@@ -22,7 +22,10 @@ L.WriterTileLayer = L.TileLayer.extend({
var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
- var toRequest = [];
+
+ var tilePositionsX = "";
+ var tilePositionsY = "";
+ var needsNewTiles = false;
for (var key in this._tiles) {
var coords = this._tiles[key].coords;
@@ -37,15 +40,14 @@ L.WriterTileLayer = L.TileLayer.extend({
this._tiles[key]._invalidCount = 1;
}
if (visibleArea.intersects(bounds)) {
- var msg = 'tile ' +
- 'part=' + coords.part + ' ' +
- 'width=' + this._tileSize + ' ' +
- 'height=' + this._tileSize + ' ' +
- 'tileposx=' + tileTopLeft.x + ' ' +
- 'tileposy=' + tileTopLeft.y + ' ' +
- 'tilewidth=' + this._tileWidthTwips + ' ' +
- 'tileheight=' + this._tileHeightTwips;
- toRequest.push({msg: msg, key: key, coords: coords});
+ if (tilePositionsX !== "")
+ tilePositionsX += ',';
+ tilePositionsX += tileTopLeft.x;
+
+ if (tilePositionsY !== "")
+ tilePositionsY += ',';
+ tilePositionsY += tileTopLeft.y;
+ needsNewTiles = true;
}
else {
// tile outside of the visible area, just remove it
@@ -55,12 +57,18 @@ L.WriterTileLayer = L.TileLayer.extend({
}
}
- // Sort tiles so that we request those closer to the cursor first
- var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
- cursorPos = cursorPos.divideBy(this._tileSize);
- toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
- for (var i = 0; i < toRequest.length; i++) {
- this._map._socket.sendMessage(toRequest[i].msg, toRequest[i].key);
+ if (needsNewTiles)
+ {
+ var message = 'tilecombine ' +
+ 'part=' + command.part + ' ' +
+ 'width=' + this._tileSize + ' ' +
+ 'height=' + this._tileSize + ' ' +
+ 'tileposx=' + tilePositionsX + ' ' +
+ 'tileposy=' + tilePositionsY + ' ' +
+ 'tilewidth=' + this._tileWidthTwips + ' ' +
+ 'tileheight=' + this._tileHeightTwips;
+
+ this._map._socket.sendMessage(message, "");
}
for (key in this._tileCache) {
commit 721cbbcbb37009e845edb97f1cc472acea9d4869
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Thu Jan 14 13:00:04 2016 +0100
Add "tilecombine" command to render more tiles in one call
When invalidating we need to rerender more tiles at once.
This change optimizes that with a new command which rerenders a
larger area once and then separates the rendered buffer into more
tiles. This generally decreases the invalidation time by 2-4 times
and in some cases (when invalidating images in document) up to 9
times.
diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index 25d1de9..2c10576 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -24,6 +24,7 @@
#include "LOKitHelper.hpp"
#include "LOOLProtocol.hpp"
#include "Util.hpp"
+#include "Rectangle.hpp"
using namespace LOOLProtocol;
@@ -125,6 +126,10 @@ bool ChildProcessSession::_handleInput(const char *buffer, int length)
{
sendTile(buffer, length, tokens);
}
+ else if (tokens[0] == "tilecombine")
+ {
+ sendCombinedTiles(buffer, length, tokens);
+ }
else
{
// All other commands are such that they always require a LibreOfficeKitDocument session,
@@ -423,6 +428,132 @@ void ChildProcessSession::sendTile(const char* /*buffer*/, int /*length*/, Strin
sendBinaryFrame(output.data(), output.size());
}
+void ChildProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*length*/, StringTokenizer& tokens)
+{
+ int part, pixelWidth, pixelHeight, tileWidth, tileHeight;
+ std::string tilePositionsX, tilePositionsY;
+
+ if (tokens.count() < 8 ||
+ !getTokenInteger(tokens[1], "part", part) ||
+ !getTokenInteger(tokens[2], "width", pixelWidth) ||
+ !getTokenInteger(tokens[3], "height", pixelHeight) ||
+ !getTokenString (tokens[4], "tileposx", tilePositionsX) ||
+ !getTokenString (tokens[5], "tileposy", tilePositionsY) ||
+ !getTokenInteger(tokens[6], "tilewidth", tileWidth) ||
+ !getTokenInteger(tokens[7], "tileheight", tileHeight))
+ {
+ sendTextFrame("error: cmd=tilecombine kind=syntax");
+ return;
+ }
+
+ if (part < 0 || pixelWidth <= 0 || pixelHeight <= 0
+ || tileWidth <= 0 || tileHeight <= 0
+ || tilePositionsX.empty() || tilePositionsY.empty())
+ {
+ sendTextFrame("error: cmd=tilecombine kind=invalid");
+ return;
+ }
+
+ Util::Rectangle renderArea;
+
+ StringTokenizer positionXtokens(tilePositionsX, ",", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+ StringTokenizer positionYtokens(tilePositionsY, ",", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+
+ size_t numberOfPositions = positionYtokens.count();
+ // check that number of positions for X and Y is the same
+ if (numberOfPositions != positionYtokens.count())
+ {
+ sendTextFrame("error: cmd=tilecombine kind=invalid");
+ return;
+ }
+
+ std::vector<Util::Rectangle> tiles;
+ tiles.reserve(numberOfPositions);
+
+ for (size_t i = 0; i < numberOfPositions; i++)
+ {
+ int x, y;
+
+ if (!stringToInteger(positionXtokens[i], x))
+ {
+ sendTextFrame("error: cmd=tilecombine kind=syntax");
+ return;
+ }
+ if (!stringToInteger(positionYtokens[i], y))
+ {
+ sendTextFrame("error: cmd=tilecombine kind=syntax");
+ return;
+ }
+
+ Util::Rectangle rectangle(x, y, tileWidth, tileHeight);
+
+ if (tiles.empty())
+ {
+ renderArea = rectangle;
+ }
+ else
+ {
+ renderArea.extend(rectangle);
+ }
+
+ tiles.push_back(rectangle);
+ }
+
+ if (_docType != "text" && part != _loKitDocument->pClass->getPart(_loKitDocument))
+ {
+ _loKitDocument->pClass->setPart(_loKitDocument, part);
+ }
+
+ LibreOfficeKitTileMode mode = static_cast<LibreOfficeKitTileMode>(_loKitDocument->pClass->getTileMode(_loKitDocument));
+
+ int tilesByX = renderArea.getWidth() / tileWidth;
+ int tilesByY = renderArea.getHeight() / tileHeight;
+
+ int pixmapWidth = tilesByX * pixelWidth;
+ int pixmapHeight = tilesByY * pixelHeight;
+
+ const size_t pixmapSize = 4 * pixmapWidth * pixmapHeight;
+
+ std::vector<unsigned char> pixmap(pixmapSize, 0);
+
+ Poco::Timestamp timestamp;
+ _loKitDocument->pClass->paintTile(_loKitDocument, pixmap.data(), pixmapWidth, pixmapHeight,
+ renderArea.getLeft(), renderArea.getTop(),
+ renderArea.getWidth(), renderArea.getHeight());
+
+ Log::debug() << "paintTile (Multiple) called, tile at [" << renderArea.getLeft() << ", " << renderArea.getTop() << "]"
+ << " (" << renderArea.getWidth() << ", " << renderArea.getHeight() << ") rendered in "
+ << double(timestamp.elapsed())/1000 << "ms" << Log::end;
+
+ for (Util::Rectangle& tileRect : tiles)
+ {
+ std::string response = "tile: part=" + std::to_string(part) +
+ " width=" + std::to_string(pixelWidth) +
+ " height=" + std::to_string(pixelHeight) +
+ " tileposx=" + std::to_string(tileRect.getLeft()) +
+ " tileposy=" + std::to_string(tileRect.getTop()) +
+ " tilewidth=" + std::to_string(tileWidth) +
+ " tileheight=" + std::to_string(tileHeight) + "\n";
+
+ std::vector<char> output;
+ output.reserve(pixelWidth * pixelHeight * 4 + response.size());
+ output.resize(response.size());
+
+ std::copy(response.begin(), response.end(), output.begin());
+
+ int positionX = (tileRect.getLeft() - renderArea.getLeft()) / tileWidth;
+ int positionY = (tileRect.getTop() - renderArea.getTop()) / tileHeight;
+
+ if (!Util::encodeSubBufferToPNG(pixmap.data(), positionX * pixelWidth, positionY * pixelHeight, pixelWidth, pixelHeight, pixmapWidth, pixmapHeight, output, mode))
+ {
+ sendTextFrame("error: cmd=tile kind=failure");
+ return;
+ }
+
+ sendBinaryFrame(output.data(), output.size());
+ }
+}
+
bool ChildProcessSession::clientZoom(const char* /*buffer*/, int /*length*/, StringTokenizer& tokens)
{
int tilePixelWidth, tilePixelHeight, tileTwipWidth, tileTwipHeight;
diff --git a/loolwsd/ChildProcessSession.hpp b/loolwsd/ChildProcessSession.hpp
index 062e4cf..12d7d02 100644
--- a/loolwsd/ChildProcessSession.hpp
+++ b/loolwsd/ChildProcessSession.hpp
@@ -59,6 +59,8 @@ public:
virtual void sendTile(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
+ virtual void sendCombinedTiles(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
+
virtual void sendFontRendering(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
bool clientZoom(const char *buffer, int length, Poco::StringTokenizer& tokens);
diff --git a/loolwsd/LOOLSession.hpp b/loolwsd/LOOLSession.hpp
index a5f3678..c03de93 100644
--- a/loolwsd/LOOLSession.hpp
+++ b/loolwsd/LOOLSession.hpp
@@ -75,6 +75,8 @@ protected:
virtual void sendTile(const char *buffer, int length, Poco::StringTokenizer& tokens) = 0;
+ virtual void sendCombinedTiles(const char *buffer, int length, Poco::StringTokenizer& tokens) = 0;
+
virtual void sendFontRendering(const char *buffer, int length, Poco::StringTokenizer& tokens) = 0;
// Fields common to sessions in master and jailed processes:
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index e427328..32a3098 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -289,6 +289,7 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
tokens[0] != "setpage" &&
tokens[0] != "status" &&
tokens[0] != "tile" &&
+ tokens[0] != "tilecombine" &&
tokens[0] != "uno")
{
sendTextFrame("error: cmd=" + tokens[0] + " kind=unknown");
@@ -328,6 +329,10 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
{
sendTile(buffer, length, tokens);
}
+ else if (tokens[0] == "tilecombine")
+ {
+ sendCombinedTiles(buffer, length, tokens);
+ }
else
{
// All other commands are such that they always require a
@@ -570,6 +575,14 @@ void MasterProcessSession::sendTile(const char *buffer, int length, StringTokeni
forwardToPeer(buffer, length);
}
+void MasterProcessSession::sendCombinedTiles(const char *buffer, int length, StringTokenizer& /*tokens*/)
+{
+ // This is for invalidation - we should not have cached tiles
+ if (_peer.expired())
+ dispatchChild();
+ forwardToPeer(buffer, length);
+}
+
void MasterProcessSession::dispatchChild()
{
short nRequest = 3;
diff --git a/loolwsd/MasterProcessSession.hpp b/loolwsd/MasterProcessSession.hpp
index 380def8..42ed9e9 100644
--- a/loolwsd/MasterProcessSession.hpp
+++ b/loolwsd/MasterProcessSession.hpp
@@ -47,6 +47,8 @@ public:
virtual void sendTile(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
+ virtual void sendCombinedTiles(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
+
virtual void sendFontRendering(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
void dispatchChild();
commit 9af47a69d3073936b6bf563f707c894d0cb5a00b
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Tue Jan 12 12:11:49 2016 +0100
add simple Rectangle struct implementation
(cherry picked from commit 5c25dd61cb6a27da47c6e3776024cd7d622082b8)
diff --git a/loolwsd/Rectangle.hpp b/loolwsd/Rectangle.hpp
new file mode 100644
index 0000000..bac02b4
--- /dev/null
+++ b/loolwsd/Rectangle.hpp
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_RECTANGLE_HPP
+#define INCLUDED_RECTANGLE_HPP
+
+#include <limits>
+
+namespace Util
+{
+
+struct Rectangle
+{
+ int _x1;
+ int _y1;
+ int _x2;
+ int _y2;
+
+ Rectangle()
+ : _x1(std::numeric_limits<int>::max())
+ , _y1(std::numeric_limits<int>::max())
+ , _x2(std::numeric_limits<int>::min())
+ , _y2(std::numeric_limits<int>::min())
+ {}
+
+ Rectangle(int x, int y, int width, int height)
+ : _x1(x)
+ , _y1(y)
+ , _x2(x + width)
+ , _y2(y + height)
+ {}
+
+ void extend(Rectangle& rectangle)
+ {
+ if (rectangle._x1 < _x1)
+ _x1 = rectangle._x1;
+ if (rectangle._x2 > _x2)
+ _x2 = rectangle._x2;
+ if (rectangle._y1 < _y1)
+ _y1 = rectangle._y1;
+ if (rectangle._y2 > _y2)
+ _y2 = rectangle._y2;
+ }
+
+ int getLeft()
+ {
+ return _x1;
+ }
+
+ int getTop()
+ {
+ return _y1;
+ }
+
+ int getWidth()
+ {
+ return _x2 - _x1;
+ }
+
+ int getHeight()
+ {
+ return _y2 - _y1;
+ }
+
+ bool isValid()
+ {
+ return _x1 <= _x2 && _y1 <= _y2;
+ }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 8ee650346998a4863aac1c60d01c8927087ba303
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Tue Jan 12 12:07:13 2016 +0100
add function to convert string to integer
(cherry picked from commit f7acce6f20bf362b741542d66e2879c1638bab7c)
diff --git a/loolwsd/LOOLProtocol.cpp b/loolwsd/LOOLProtocol.cpp
index 0d358c2..20c5d8e 100644
--- a/loolwsd/LOOLProtocol.cpp
+++ b/loolwsd/LOOLProtocol.cpp
@@ -40,10 +40,23 @@ namespace LOOLProtocol
if (secondTokens.count() > 1)
patch = secondTokens[1];
}
-
return std::make_tuple(major, minor, patch);
}
+ bool stringToInteger(const std::string& input, int& value)
+ {
+ try
+ {
+ value = std::stoi(input);
+ }
+ catch (std::invalid_argument&)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
bool getTokenInteger(const std::string& token, const std::string& name, int& value)
{
size_t nextIdx;
diff --git a/loolwsd/LOOLProtocol.hpp b/loolwsd/LOOLProtocol.hpp
index 1478713..26a8f4b 100644
--- a/loolwsd/LOOLProtocol.hpp
+++ b/loolwsd/LOOLProtocol.hpp
@@ -78,6 +78,8 @@ namespace LOOLProtocol
// Negative numbers for error.
std::tuple<signed, signed, std::string> ParseVersion(const std::string& version);
+ bool stringToInteger(const std::string& input, int& value);
+
bool getTokenInteger(const std::string& token, const std::string& name, int& value);
bool getTokenString(const std::string& token, const std::string& name, std::string& value);
bool getTokenKeyword(const std::string& token, const std::string& name, const std::map<std::string, int>& map, int& value);
commit 26d30c88dea37960673324e7c6ab684b4905223a
Author: Andras Timar <andras.timar at collabora.com>
Date: Thu Jan 14 12:40:59 2016 +0100
loolwsd: -Werror,-Wunused-variable
diff --git a/loolwsd/loolmap.c b/loolwsd/loolmap.c
index 922a6c3..3a863ae 100644
--- a/loolwsd/loolmap.c
+++ b/loolwsd/loolmap.c
@@ -69,10 +69,6 @@ static void total_smaps(unsigned proc_id, const char *file, const char *cmdline)
FILE *file_pointer;
char buffer[BUFFER_SIZE];
- unsigned long long private_dirty = 0ull;
- unsigned long long private_clean = 0ull;
- unsigned long long shared_dirty = 0ull;
- unsigned long long shared_clean = 0ull;
unsigned long long total_private_dirty = 0ull;
unsigned long long total_private_clean = 0ull;
unsigned long long total_shared_dirty = 0ull;
@@ -91,25 +87,21 @@ static void total_smaps(unsigned proc_id, const char *file, const char *cmdline)
{
if (strncmp("Shared_Dirty", smap_key, 12) == 0)
{
- shared_dirty = smap_value;
total_shared_dirty += smap_value;
continue;
}
if (strncmp("Shared_Clean", smap_key, 12) == 0)
{
- shared_clean = smap_value;
total_shared_clean += smap_value;
continue;
}
if (strncmp("Private_Dirty", smap_key, 13) == 0)
{
- private_dirty = smap_value;
total_private_dirty += smap_value;
continue;
}
if (strncmp("Private_Clean", smap_key, 13) == 0)
{
- private_clean = smap_value;
total_private_clean += smap_value;
continue;
}
commit 9071f7c9bc8125bc3ba15afa14f731beb904d183
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.com>
Date: Tue Jan 12 12:00:42 2016 +0100
encode PNG from buffer at arbitrary buffer position
This commit add 2 methods to encode a buffer to PNG: the "old"
method which encodes the whole buffer to a PNG, and a new method
to encode a part of a buffer (sub image) to PNG. The first method
is only added for convenience.
diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index c84650d..25d1de9 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -293,7 +293,7 @@ void ChildProcessSession::sendFontRendering(const char* /*buffer*/, int /*length
if (pixmap != nullptr)
{
- if (!Util::encodePNGAndAppendToBuffer(pixmap, width, height, output, LOK_TILEMODE_RGBA))
+ if (!Util::encodeBufferToPNG(pixmap, width, height, output, LOK_TILEMODE_RGBA))
{
sendTextFrame("error: cmd=renderfont kind=failure");
delete[] pixmap;
@@ -414,7 +414,7 @@ void ChildProcessSession::sendTile(const char* /*buffer*/, int /*length*/, Strin
<< "] rendered in " << (timestamp.elapsed()/1000.) << " ms" << Log::end;
LibreOfficeKitTileMode mode = static_cast<LibreOfficeKitTileMode>(_loKitDocument->pClass->getTileMode(_loKitDocument));
- if (!Util::encodePNGAndAppendToBuffer(pixmap.data(), width, height, output, mode))
+ if (!Util::encodeBufferToPNG(pixmap.data(), width, height, output, mode))
{
sendTextFrame("error: cmd=tile kind=failure");
return;
diff --git a/loolwsd/LOKitClient.cpp b/loolwsd/LOKitClient.cpp
index b6db978..b03c2fd 100644
--- a/loolwsd/LOKitClient.cpp
+++ b/loolwsd/LOKitClient.cpp
@@ -167,7 +167,8 @@ protected:
std::vector<char> png;
LibreOfficeKitTileMode mode = static_cast<LibreOfficeKitTileMode>(loKitDocument->pClass->getTileMode(loKitDocument));
- Util::encodePNGAndAppendToBuffer(pixmap.data(), canvasWidth, canvasHeight, png, mode);
+
+ Util::encodeBufferToPNG(pixmap.data(), canvasWidth, canvasHeight, png, mode);
TemporaryFile pngFile;
std::ofstream pngStream(pngFile.path(), std::ios::binary);
diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp
index addef5b..ed8757d 100644
--- a/loolwsd/Util.cpp
+++ b/loolwsd/Util.cpp
@@ -226,8 +226,18 @@ namespace Util
return false;
}
- bool encodePNGAndAppendToBuffer(unsigned char *pixmap, int width, int height, std::vector<char>& output, LibreOfficeKitTileMode mode)
+ bool encodeBufferToPNG(unsigned char *pixmap, int width, int height, std::vector<char>& output, LibreOfficeKitTileMode mode)
{
+
+ return encodeSubBufferToPNG(pixmap, 0, 0, width, height, width, height, output, mode);
+ }
+
+ bool encodeSubBufferToPNG(unsigned char *pixmap, int startX, int startY, int width, int height,
+ int bufferWidth, int bufferHeight, std::vector<char>& output, LibreOfficeKitTileMode mode)
+ {
+ if (bufferWidth < width || bufferHeight < height)
+ return false;
+
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_infop info_ptr = png_create_info_struct(png_ptr);
@@ -245,19 +255,16 @@ namespace Util
png_write_info(png_ptr, info_ptr);
- switch (mode)
+ if (mode == LOK_TILEMODE_BGRA)
{
- case LOK_TILEMODE_RGBA:
- break;
- case LOK_TILEMODE_BGRA:
png_set_write_user_transform_fn (png_ptr, unpremultiply_data);
- break;
- default:
- assert(false);
}
for (int y = 0; y < height; ++y)
- png_write_row(png_ptr, pixmap + y * width * 4);
+ {
+ size_t position = ((startY + y) * bufferWidth * 4) + (startX * 4);
+ png_write_row(png_ptr, pixmap + position);
+ }
png_write_end(png_ptr, info_ptr);
diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp
index 04aed30..702fe98 100644
--- a/loolwsd/Util.hpp
+++ b/loolwsd/Util.hpp
@@ -50,7 +50,11 @@ namespace Util
// Sadly, older libpng headers don't use const for the pixmap pointer parameter to
// png_write_row(), so can't use const here for pixmap.
- bool encodePNGAndAppendToBuffer(unsigned char *pixmap, int width, int height, std::vector<char>& output, LibreOfficeKitTileMode mode);
+ bool encodeBufferToPNG(unsigned char* pixmap, int width, int height,
+ std::vector<char>& output, LibreOfficeKitTileMode mode);
+ bool encodeSubBufferToPNG(unsigned char* pixmap, int startX, int startY, int width, int height,
+ int bufferWidth, int bufferHeight,
+ std::vector<char>& output, LibreOfficeKitTileMode mode);
// Call WebSocket::shutdown() ignoring Poco::IOException
void shutdownWebSocket(Poco::Net::WebSocket& ws);
More information about the Libreoffice-commits
mailing list