Kaydet (Commit) 8a2414e4 authored tarafından Michael Meeks's avatar Michael Meeks

Re-factor to allow dialog profiling.

Change-Id: I2268cc7b1db23c520ce3699d4e478d7c5bf6820f
Reviewed-on: https://gerrit.libreoffice.org/56764Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
Tested-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst bfedfeda
...@@ -22,10 +22,14 @@ ...@@ -22,10 +22,14 @@
using namespace lok; using namespace lok;
static int help() static int help( const char *error = nullptr )
{ {
fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document] [max parts|-1] [max tiles|-1]\n" ); if (error)
fprintf( stderr, "renders a selection of small tiles from the document, checksums them and times the process\n" ); fprintf (stderr, "Error: %s\n\n", error);
fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document]\n");
fprintf( stderr, "\trenders a selection of small tiles from the document, checksums them and times the process\n" );
fprintf( stderr, "\t--tile\t[max parts|-1] [max tiles|-1]\n" );
fprintf( stderr, "\t--dialog\t<.uno:Command>\n" );
return 1; return 1;
} }
...@@ -37,6 +41,20 @@ static double getTimeNow() ...@@ -37,6 +41,20 @@ static double getTimeNow()
static_cast<double>(aValue.Nanosec) / (1000*1000*1000); static_cast<double>(aValue.Nanosec) / (1000*1000*1000);
} }
static double origin;
struct TimeRecord {
const char *mpName;
double mfTime;
TimeRecord() : mpName(nullptr), mfTime(getTimeNow()) { }
explicit TimeRecord(const char *pName) :
mpName(pName), mfTime(getTimeNow())
{
fprintf(stderr, "%3.3fs - %s\n", (mfTime - origin), mpName);
}
};
static std::vector< TimeRecord > aTimes;
/// Dump an array of RGBA or BGRA to an RGB PPM file. /// Dump an array of RGBA or BGRA to an RGB PPM file.
static void dumpTile(const int nWidth, const int nHeight, const int mode, const char* pBuffer) static void dumpTile(const int nWidth, const int nHeight, const int mode, const char* pBuffer)
{ {
...@@ -79,22 +97,129 @@ static void dumpTile(const int nWidth, const int nHeight, const int mode, const ...@@ -79,22 +97,129 @@ static void dumpTile(const int nWidth, const int nHeight, const int mode, const
} }
} }
int main( int argc, char* argv[] ) void testTile( Document *pDocument, int max_parts,
int max_tiles, bool dump )
{ {
static const double origin = getTimeNow(); const int mode = pDocument->getTileMode();
struct TimeRecord {
const char *mpName; aTimes.emplace_back("getparts");
double mfTime; const int nOriginalPart = (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT ? 1 : pDocument->getPart());
// Writer really has 1 part (the full doc).
TimeRecord() : mpName(nullptr), mfTime(getTimeNow()) { } const int nTotalParts = (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT ? 1 : pDocument->getParts());
explicit TimeRecord(const char *pName) : const int nParts = (max_parts < 0 ? nTotalParts : std::min(max_parts, nTotalParts));
mpName(pName), mfTime(getTimeNow()) aTimes.emplace_back();
aTimes.emplace_back("get size of parts");
long nWidth = 0;
long nHeight = 0;
for (int n = 0; n < nParts; ++n)
{
const int nPart = (nOriginalPart + n) % nTotalParts;
char* pName = pDocument->getPartName(nPart);
pDocument->setPart(nPart);
pDocument->getDocumentSize(&nWidth, &nHeight);
fprintf (stderr, " '%s' -> %ld, %ld\n", pName, nWidth, nHeight);
free (pName);
}
aTimes.emplace_back();
// Use realistic dimensions, similar to the Online client.
long nTilePixelWidth = 512;
long nTilePixelHeight = 512;
long nTileTwipWidth = 3840;
long nTileTwipHeight = 3840;
// Estimate the maximum tiles based on the number of parts requested, if Writer.
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
max_tiles = static_cast<int>(ceil(max_parts * 16128. / nTilePixelHeight) * ceil(static_cast<double>(nWidth) / nTilePixelWidth));
fprintf(stderr, "Parts to render: %d, Total Parts: %d, Max parts: %d, Max tiles: %d\n", nParts, nTotalParts, max_parts, max_tiles);
std::vector<unsigned char> vBuffer(nTilePixelWidth * nTilePixelHeight * 4);
unsigned char* pPixels = &vBuffer[0];
for (int n = 0; n < nParts; ++n)
{
const int nPart = (nOriginalPart + n) % nTotalParts;
char* pName = pDocument->getPartName(nPart);
pDocument->setPart(nPart);
pDocument->getDocumentSize(&nWidth, &nHeight);
fprintf (stderr, "render '%s' -> %ld, %ld\n", pName, nWidth, nHeight);
free (pName);
if (dump || pDocument->getDocumentType() != LOK_DOCTYPE_TEXT)
{ {
fprintf(stderr, "%3.3fs - %s\n", (mfTime - origin), mpName); // whole part; meaningful only for non-writer documents.
aTimes.emplace_back("render whole part");
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nWidth/2, 2000, 1000, 1000); // not square
aTimes.emplace_back();
if (dump)
dumpTile(nTilePixelWidth, nTilePixelHeight, mode, reinterpret_cast<char*>(pPixels));
}
{ // 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;
int nTiles = 0;
for (int nY = 0; nY < nHeight - 1; nY += nTilePixelHeight)
{
for (int nX = 0; nX < nWidth - 1; nX += nTilePixelWidth)
{
if (nMaxTiles >= 0 && nTiles >= nMaxTiles)
{
nY = nHeight;
break;
}
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nX, nY, nTilePixelWidth, nTilePixelHeight);
nTiles++;
fprintf (stderr, " rendered 1:1 tile %d at %d, %d\n",
nTiles, nX, nY);
}
}
aTimes.emplace_back();
}
{ // scaled
aTimes.emplace_back("render sub-regions at scale");
int nMaxTiles = max_tiles;
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
nMaxTiles = static_cast<int>(ceil(max_parts * 16128. / nTileTwipHeight) * ceil(static_cast<double>(nWidth) / nTileTwipWidth));
int nTiles = 0;
for (int nY = 0; nY < nHeight - 1; nY += nTileTwipHeight)
{
for (int nX = 0; nX < nWidth - 1; nX += nTileTwipWidth)
{
if (nMaxTiles >= 0 && nTiles >= nMaxTiles)
{
nY = nHeight;
break;
}
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nX, nY, nTileTwipWidth, nTileTwipHeight);
nTiles++;
fprintf (stderr, " rendered scaled tile %d at %d, %d\n",
nTiles, nX, nY);
}
}
aTimes.emplace_back();
} }
}; }
std::vector< TimeRecord > aTimes; }
if( argc < 2 ||
void testDialog( Document *pDocument, const char *uno_cmd )
{
fprintf (stderr, "Stress test a dialog...\n");
(void)pDocument; (void)uno_cmd;
}
int main( int argc, char* argv[] )
{
origin = getTimeNow();
if( argc < 4 ||
( argc > 1 && ( !strcmp( argv[1], "--help" ) || !strcmp( argv[1], "-h" ) ) ) ) ( argc > 1 && ( !strcmp( argv[1], "--help" ) || !strcmp( argv[1], "-h" ) ) ) )
return help(); return help();
...@@ -115,129 +240,39 @@ int main( int argc, char* argv[] ) ...@@ -115,129 +240,39 @@ int main( int argc, char* argv[] )
aTimes.emplace_back(); aTimes.emplace_back();
const int max_parts = (argc > 3 ? atoi(argv[3]) : -1); const char *doc_url = argv[2];
int max_tiles = (argc > 4 ? atoi(argv[4]) : -1); const char *mode = argv[3];
const bool dump = true; Document *pDocument = nullptr;
if (argv[2] != nullptr) aTimes.emplace_back("load document");
{ if (doc_url != nullptr)
aTimes.emplace_back("load document"); pDocument = pOffice->documentLoad(doc_url);
Document *pDocument(pOffice->documentLoad(argv[2])); aTimes.emplace_back();
aTimes.emplace_back();
const int mode = pDocument->getTileMode();
aTimes.emplace_back("getparts");
const int nOriginalPart = (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT ? 1 : 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));
aTimes.emplace_back();
aTimes.emplace_back("get size of parts");
long nWidth = 0;
long nHeight = 0;
for (int n = 0; n < nParts; ++n)
{
const int nPart = (nOriginalPart + n) % nTotalParts;
char* pName = pDocument->getPartName(nPart);
pDocument->setPart(nPart);
pDocument->getDocumentSize(&nWidth, &nHeight);
fprintf (stderr, " '%s' -> %ld, %ld\n", pName, nWidth, nHeight);
free (pName);
}
aTimes.emplace_back();
// Use realistic dimensions, similar to the Online client.
long nTilePixelWidth = 512;
long nTilePixelHeight = 512;
long nTileTwipWidth = 3840;
long nTileTwipHeight = 3840;
// Estimate the maximum tiles based on the number of parts requested, if Writer.
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
max_tiles = static_cast<int>(ceil(max_parts * 16128. / nTilePixelHeight) * ceil(static_cast<double>(nWidth) / nTilePixelWidth));
fprintf(stderr, "Parts to render: %d, Total Parts: %d, Max parts: %d, Max tiles: %d\n", nParts, nTotalParts, max_parts, max_tiles);
std::vector<unsigned char> vBuffer(nTilePixelWidth * nTilePixelHeight * 4);
unsigned char* pPixels = &vBuffer[0];
for (int n = 0; n < nParts; ++n) if (pDocument)
{
if (!strcmp(mode, "--tile"))
{ {
const int nPart = (nOriginalPart + n) % nTotalParts; const int max_parts = (argc > 4 ? atoi(argv[4]) : -1);
char* pName = pDocument->getPartName(nPart); int max_tiles = (argc > 5 ? atoi(argv[5]) : -1);
pDocument->setPart(nPart); const bool dump = true;
pDocument->getDocumentSize(&nWidth, &nHeight);
fprintf (stderr, "render '%s' -> %ld, %ld\n", pName, nWidth, nHeight);
free (pName);
if (dump || pDocument->getDocumentType() != LOK_DOCTYPE_TEXT)
{
// whole part; meaningful only for non-writer documents.
aTimes.emplace_back("render whole part");
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nWidth/2, 2000, 1000, 1000); // not square
aTimes.emplace_back();
if (dump)
dumpTile(nTilePixelWidth, nTilePixelHeight, mode, reinterpret_cast<char*>(pPixels));
}
{ // 1:1 testTile (pDocument, max_parts, max_tiles, dump);
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;
int nTiles = 0;
for (int nY = 0; nY < nHeight - 1; nY += nTilePixelHeight)
{
for (int nX = 0; nX < nWidth - 1; nX += nTilePixelWidth)
{
if (nMaxTiles >= 0 && nTiles >= nMaxTiles)
{
nY = nHeight;
break;
}
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nX, nY, nTilePixelWidth, nTilePixelHeight);
nTiles++;
fprintf (stderr, " rendered 1:1 tile %d at %d, %d\n",
nTiles, nX, nY);
}
}
aTimes.emplace_back();
}
{ // scaled
aTimes.emplace_back("render sub-regions at scale");
int nMaxTiles = max_tiles;
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
nMaxTiles = static_cast<int>(ceil(max_parts * 16128. / nTileTwipHeight) * ceil(static_cast<double>(nWidth) / nTileTwipWidth));
int nTiles = 0;
for (int nY = 0; nY < nHeight - 1; nY += nTileTwipHeight)
{
for (int nX = 0; nX < nWidth - 1; nX += nTileTwipWidth)
{
if (nMaxTiles >= 0 && nTiles >= nMaxTiles)
{
nY = nHeight;
break;
}
pDocument->paintTile(pPixels, nTilePixelWidth, nTilePixelHeight,
nX, nY, nTileTwipWidth, nTileTwipHeight);
nTiles++;
fprintf (stderr, " rendered scaled tile %d at %d, %d\n",
nTiles, nX, nY);
}
}
aTimes.emplace_back();
}
} }
else if (!strcmp (mode, "--dialog"))
aTimes.emplace_back("destroy document"); {
delete pDocument; if (argc > 4)
aTimes.emplace_back(); testDialog (pDocument, argv[4]);
else
return help("missing argument to --dialog");
} else
return help ("unknown parameter");
} }
aTimes.emplace_back("destroy document");
delete pDocument;
aTimes.emplace_back();
delete pOffice; delete pOffice;
double nTotal = 0.0; double nTotal = 0.0;
......
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