Kaydet (Commit) a692cdf7 authored tarafından Ashod Nakashian's avatar Ashod Nakashian Kaydeden (comit) Ashod Nakashian

LOK: tilebench improvements

* Arguments for max number of parts and tiles to render (optional).
  + Automatic estimation of maximum tiles to render based on max parts
    for Writer docs, since there is only 1 part, this caps the number
    of pages to render, similar to other doc types.
* Fixed rendering of Writer documents over and over (as many times as pages).
  + Writer has a single part, unlike other doc types.
  + No point in rendering the whole document in writer to a single tile,
    since that's completely unrealistic and impractical (it takes
    forever for large docs and artificially spikes the memory).
* Rendering starts at the current part and not the first.
  + This gives the spreadsheet of interest priority (if saved as visible).
* The tile size is now more realistic as we use the same dimensions
  as the Online client does.
* When rendering tiles at scale, we use the same dimensions as the
  Online client rather than splitting the width by 4, for realism.
* Rendering of tiles is done rows-first, rather than columns-first,
  which is similar to what the Online client does, which is more
  cache friendly, therefore more realistic.
* Enabled compiling of tilebench when GTK3 is disabled, which
  was erroneous, since tilebench doesn't have any dependency on GTK.
  + Now it's possible to compile with local Cairo/Pixman libs.

Reviewed-on: https://gerrit.libreoffice.org/44936Reviewed-by: 's avatarJan Holesovsky <kendy@collabora.com>
Tested-by: 's avatarJan Holesovsky <kendy@collabora.com>
(cherry picked from commit 7db98521)

Change-Id: I6ad2e97f39572778dd7d0c12d14550841c1d6963
Reviewed-on: https://gerrit.libreoffice.org/46984Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarAshod Nakashian <ashnakash@gmail.com>
üst 39d10229
...@@ -70,7 +70,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \ ...@@ -70,7 +70,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
svptest \ svptest \
svpclient \ svpclient \
pixelctl ) \ pixelctl ) \
$(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), tilebench) \ $(if $(filter LINUX %BSD SOLARIS,$(OS)), tilebench) \
$(if $(filter LINUX MACOSX SOLARIS WNT %BSD,$(OS)),icontest \ $(if $(filter LINUX MACOSX SOLARIS WNT %BSD,$(OS)),icontest \
outdevgrind) \ outdevgrind) \
vcldemo \ vcldemo \
......
...@@ -15,7 +15,6 @@ $(eval $(call gb_Executable_set_include,tilebench,\ ...@@ -15,7 +15,6 @@ $(eval $(call gb_Executable_set_include,tilebench,\
)) ))
$(eval $(call gb_Executable_use_libraries,tilebench,\ $(eval $(call gb_Executable_use_libraries,tilebench,\
libreofficekitgtk \
sal \ sal \
)) ))
......
...@@ -24,10 +24,13 @@ ifneq ($(ENABLE_GTK3),) ...@@ -24,10 +24,13 @@ ifneq ($(ENABLE_GTK3),)
$(eval $(call gb_Module_add_targets,libreofficekit,\ $(eval $(call gb_Module_add_targets,libreofficekit,\
Library_libreofficekitgtk \ Library_libreofficekitgtk \
Executable_gtktiledviewer \ Executable_gtktiledviewer \
))
endif # ($(ENABLE_GTK3),)
$(eval $(call gb_Module_add_targets,libreofficekit,\
Executable_tilebench \ Executable_tilebench \
Package_selectionhandles \ Package_selectionhandles \
)) ))
endif # ($(ENABLE_GTK3),)
endif endif
......
...@@ -10,10 +10,12 @@ ...@@ -10,10 +10,12 @@
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <cmath>
#include <vector> #include <vector>
#include <osl/time.h> #include <osl/time.h>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <LibreOfficeKit/LibreOfficeKitInit.h> #include <LibreOfficeKit/LibreOfficeKitInit.h>
#include <LibreOfficeKit/LibreOfficeKit.hxx> #include <LibreOfficeKit/LibreOfficeKit.hxx>
...@@ -21,7 +23,7 @@ using namespace lok; ...@@ -21,7 +23,7 @@ using namespace lok;
static int help() static int help()
{ {
fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document]\n" ); fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document] [max parts|-1] [max tiles|-1]\n" );
fprintf( stderr, "renders a selection of small tiles from the document, checksums them and times the process\n" ); fprintf( stderr, "renders a selection of small tiles from the document, checksums them and times the process\n" );
return 1; return 1;
} }
...@@ -36,13 +38,17 @@ static double getTimeNow() ...@@ -36,13 +38,17 @@ static double getTimeNow()
int main( int argc, char* argv[] ) int main( int argc, char* argv[] )
{ {
static const double origin = getTimeNow();
struct TimeRecord { struct TimeRecord {
const char *mpName; const char *mpName;
double mfTime; double mfTime;
TimeRecord() : mpName(nullptr), mfTime(getTimeNow()) { } TimeRecord() : mpName(nullptr), mfTime(getTimeNow()) { }
explicit TimeRecord(const char *pName) : explicit TimeRecord(const char *pName) :
mpName(pName ), mfTime(getTimeNow()) { } mpName(pName), mfTime(getTimeNow())
{
fprintf(stderr, "%3.3fs - %s\n", (mfTime - origin), mpName);
}
}; };
std::vector< TimeRecord > aTimes; std::vector< TimeRecord > aTimes;
if( argc < 2 || if( argc < 2 ||
...@@ -55,11 +61,20 @@ int main( int argc, char* argv[] ) ...@@ -55,11 +61,20 @@ int main( int argc, char* argv[] )
return 1; return 1;
} }
// Use realistic dimensions, similar to the Online client.
long nTilePixelWidth = 512;
long nTilePixelHeight = 512;
long nTileTwipWidth = 3840;
long nTileTwipHeight = 3840;
aTimes.emplace_back("initialization"); aTimes.emplace_back("initialization");
// coverity[tainted_string] - build time test tool // coverity[tainted_string] - build time test tool
Office *pOffice = lok_cpp_init(argv[1]); Office *pOffice = lok_cpp_init(argv[1]);
aTimes.emplace_back(); aTimes.emplace_back();
const int max_parts = (argc > 3 ? atoi(argv[3]) : -1);
const int max_tiles = (argc > 4 ? atoi(argv[4]) : -1);
if (argv[2] != nullptr) if (argv[2] != nullptr)
{ {
aTimes.emplace_back("load document"); aTimes.emplace_back("load document");
...@@ -67,12 +82,17 @@ int main( int argc, char* argv[] ) ...@@ -67,12 +82,17 @@ int main( int argc, char* argv[] )
aTimes.emplace_back(); aTimes.emplace_back();
aTimes.emplace_back("getparts"); aTimes.emplace_back("getparts");
int nParts = pDocument->getParts(); const int nOriginalPart = pDocument->getPart();
// Writer really has 1 part (the full doc).
const int nTotalParts = (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT ? 1 : pDocument->getParts());
const int nParts = (max_parts < 0 ? nTotalParts : std::min(max_parts, nTotalParts));
fprintf(stderr, "Parts to render: %d, Total Parts: %d, Max parts: %d, Max tiles: %d\n", nParts, nTotalParts, max_parts, max_tiles);
aTimes.emplace_back(); aTimes.emplace_back();
aTimes.emplace_back("get size of parts"); aTimes.emplace_back("get size of parts");
for (int nPart = 0; nPart < nParts; nPart++) for (int n = 0; n < nParts; ++n)
{ {
const int nPart = (nOriginalPart + n) % nTotalParts;
char* pName = pDocument->getPartName(nPart); char* pName = pDocument->getPartName(nPart);
pDocument->setPart(nPart); pDocument->setPart(nPart);
long nWidth = 0, nHeight = 0; long nWidth = 0, nHeight = 0;
...@@ -82,40 +102,49 @@ int main( int argc, char* argv[] ) ...@@ -82,40 +102,49 @@ int main( int argc, char* argv[] )
} }
aTimes.emplace_back(); aTimes.emplace_back();
unsigned char pPixels[256*256*4]; std::vector<unsigned char> vBuffer(nTilePixelWidth * nTilePixelHeight * 4);
for (int nPart = 0; nPart < nParts; nPart++) unsigned char* pPixels = &vBuffer[0];
for (int n = 0; n < nParts; ++n)
{ {
{ const int nPart = (nOriginalPart + n) % nTotalParts;
char* pName = pDocument->getPartName(nPart); char* pName = pDocument->getPartName(nPart);
fprintf (stderr, "render '%s'\n", pName);
free (pName);
}
pDocument->setPart(nPart); pDocument->setPart(nPart);
long nWidth = 0, nHeight = 0; long nWidth = 0, nHeight = 0;
pDocument->getDocumentSize(&nWidth, &nHeight); pDocument->getDocumentSize(&nWidth, &nHeight);
fprintf (stderr, "render '%s' -> %ld, %ld\n", pName, nWidth, nHeight);
free (pName);
{ // whole document if (pDocument->getDocumentType() != LOK_DOCTYPE_TEXT)
aTimes.emplace_back("render whole document"); { // whole part; meaningful only for non-writer documents.
pDocument->paintTile(pPixels, 256, 256, aTimes.emplace_back("render whole part");
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
0, 0, nWidth, nHeight); // not square 0, 0, nWidth, nHeight); // not square
aTimes.emplace_back(); aTimes.emplace_back();
} }
{ // 1:1 { // 1:1
aTimes.emplace_back("render sub-region at 1:1"); aTimes.emplace_back("render sub-region at 1:1");
// Estimate the maximum tiles based on the number of parts requested, if Writer.
int nMaxTiles = max_tiles;
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
nMaxTiles = (int)ceil(max_parts * 16128. / nTilePixelHeight) * ceil((double)nWidth / nTilePixelWidth);
int nTiles = 0; int nTiles = 0;
int nSplit = nWidth / 4; for (int nY = 0; nY < nHeight - 1; nY += nTilePixelHeight)
for (int nX = 0; nX < 4; nX++)
{ {
for (int nY = 0; nY < nHeight / nSplit; nY++) for (int nX = 0; nX < nWidth - 1; nX += nTilePixelWidth)
{ {
int nTilePosX = nX * nSplit; if (nMaxTiles >= 0 && nTiles >= nMaxTiles)
int nTilePosY = nY * nSplit; {
pDocument->paintTile(pPixels, 256, 256, nY = nHeight;
nTilePosX, nTilePosY, 256, 256); break;
}
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nX, nY, nTilePixelWidth, nTilePixelHeight);
nTiles++; nTiles++;
fprintf (stderr, " rendered tile %d at %d, %d\n", fprintf (stderr, " rendered 1:1 tile %d at %d, %d\n",
nTiles, nTilePosX, nTilePosY); nTiles, nX, nY);
} }
} }
aTimes.emplace_back(); aTimes.emplace_back();
...@@ -123,19 +152,26 @@ int main( int argc, char* argv[] ) ...@@ -123,19 +152,26 @@ int main( int argc, char* argv[] )
{ // scaled { // scaled
aTimes.emplace_back("render sub-regions at scale"); aTimes.emplace_back("render sub-regions at scale");
// Estimate the maximum tiles based on the number of parts requested, if Writer.
int nMaxTiles = max_tiles;
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
nMaxTiles = (int)ceil(max_parts * 16128. / nTileTwipHeight) * ceil((double)nWidth / nTileTwipWidth);
int nTiles = 0; int nTiles = 0;
int nSplit = nWidth / 4; for (int nY = 0; nY < nHeight - 1; nY += nTileTwipHeight)
for (int nX = 0; nX < 4; nX++)
{ {
for (int nY = 0; nY < nHeight / nSplit; nY++) for (int nX = 0; nX < nWidth - 1; nX += nTileTwipWidth)
{ {
int nTilePosX = nX * nSplit; if (nMaxTiles >= 0 && nTiles >= nMaxTiles)
int nTilePosY = nY * nSplit; {
pDocument->paintTile(pPixels, 256, 256, nY = nHeight;
nTilePosX, nTilePosY, nSplit, nSplit); break;
}
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nX, nY, nTileTwipWidth, nTileTwipHeight);
nTiles++; nTiles++;
fprintf (stderr, " rendered tile %d at %d, %d\n", fprintf (stderr, " rendered scaled tile %d at %d, %d\n",
nTiles, nTilePosX, nTilePosY); nTiles, nX, nY);
} }
} }
aTimes.emplace_back(); aTimes.emplace_back();
...@@ -153,7 +189,7 @@ int main( int argc, char* argv[] ) ...@@ -153,7 +189,7 @@ int main( int argc, char* argv[] )
fprintf (stderr, "profile run:\n"); fprintf (stderr, "profile run:\n");
for (size_t i = 0; i < aTimes.size() - 1; i++) for (size_t i = 0; i < aTimes.size() - 1; i++)
{ {
double nDelta = aTimes[i+1].mfTime - aTimes[i].mfTime; const double nDelta = aTimes[i+1].mfTime - aTimes[i].mfTime;
fprintf (stderr, " %s - %2.4f(ms)\n", aTimes[i].mpName, nDelta * 1000.0); fprintf (stderr, " %s - %2.4f(ms)\n", aTimes[i].mpName, nDelta * 1000.0);
if (aTimes[i+1].mpName == nullptr) if (aTimes[i+1].mpName == nullptr)
i++; // skip it. i++; // skip it.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment