Browse Source

Add pixel conversion speed test

Add a tests directory where we can put tests programs that can
be useful during testing. Start with a speed test for the pixel
conversion routines.
tags/v1.3.90
Pierre Ossman 9 years ago
parent
commit
236c03cc33
5 changed files with 312 additions and 0 deletions
  1. 2
    0
      CMakeLists.txt
  2. 6
    0
      tests/CMakeLists.txt
  3. 201
    0
      tests/pixelconv.cxx
  4. 76
    0
      tests/util.cxx
  5. 27
    0
      tests/util.h

+ 2
- 0
CMakeLists.txt View File

@@ -416,6 +416,8 @@ if(BUILD_VIEWER)
add_subdirectory(media)
endif()

add_subdirectory(tests)


include(cmake/BuildPackages.cmake)


+ 6
- 0
tests/CMakeLists.txt View File

@@ -0,0 +1,6 @@
include_directories(${CMAKE_SOURCE_DIR}/common)

add_library(test_util STATIC util.cxx)

add_executable(pixelconv pixelconv.cxx)
target_link_libraries(pixelconv test_util rfb)

+ 201
- 0
tests/pixelconv.cxx View File

@@ -0,0 +1,201 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <rfb/PixelFormat.h>
#include <rfb/PixelTransformer.h>

#include "util.h"

static const int tile = 64;
static const int fbsize = 4096;

static rdr::U8 *fb1, *fb2;

static rfb::PixelTransformer *pt = NULL;

typedef void (*testfn) (rfb::PixelFormat&, rfb::PixelFormat&, rdr::U8*, rdr::U8*);

struct TestEntry {
const char *label;
testfn fn;
};

static void testMemcpy(rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf,
rdr::U8 *dst, rdr::U8 *src)
{
int h;
h = tile;
while (h--) {
memcpy(dst, src, tile * dstpf.bpp/8);
dst += fbsize * dstpf.bpp/8;
src += fbsize * dstpf.bpp/8;
}
}

static void testPixelTransformer(rfb::PixelFormat &dstpf,
rfb::PixelFormat &srcpf,
rdr::U8 *dst, rdr::U8 *src)
{
pt->translateRect(src, fbsize, rfb::Rect(0, 0, tile, tile),
dst, fbsize, rfb::Point(0, 0));
}

static void testToRGB(rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf,
rdr::U8 *dst, rdr::U8 *src)
{
srcpf.rgbFromBuffer(dst, src, tile, fbsize, tile);
}

static void testFromRGB(rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf,
rdr::U8 *dst, rdr::U8 *src)
{
dstpf.bufferFromRGB(dst, src, tile, fbsize, tile);
}

static void doTest(testfn fn, rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf)
{
if (!srcpf.isLittleEndian() && (fn == testPixelTransformer)) {
printf("NaN");
return;
}

startCpuCounter();

for (int i = 0;i < 10000;i++) {
int x, y;
rdr::U8 *dst, *src;
x = rand() % (fbsize - tile);
y = rand() % (fbsize - tile);
dst = fb1 + (x + y * fbsize) * dstpf.bpp/8;
src = fb2 + (x + y * fbsize) * srcpf.bpp/8;
fn(dstpf, srcpf, dst, src);
}

endCpuCounter();

float data, time;

data = (double)tile * tile * 10000;
time = getCpuCounter();

printf("%g", data / (1000.0*1000.0) / time);
}

struct TestEntry tests[] = {
{"memcpy", testMemcpy},
{"PixelTransformer", testPixelTransformer},
{"rgbFromBuffer", testToRGB},
{"bufferFromRGB", testFromRGB},
};

static void doTests(rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf)
{
int i;
char dstb[256], srcb[256];

dstpf.print(dstb, sizeof(dstb));
srcpf.print(srcb, sizeof(srcb));

if (srcpf.isLittleEndian()) {
delete pt;
pt = new rfb::PixelTransformer;
pt->init(srcpf, NULL, dstpf);
}

printf("%s,%s", srcb, dstb);

for (i = 0;i < sizeof(tests)/sizeof(tests[0]);i++) {
printf(",");
doTest(tests[i].fn, dstpf, srcpf);
}

printf("\n");
}

int main(int argc, char **argv)
{
int bufsize;

time_t t;
char datebuffer[256];

int i;

bufsize = fbsize * fbsize * 4;

fb1 = new rdr::U8[bufsize];
fb2 = new rdr::U8[bufsize];

for (int i = 0;i < bufsize;i++) {
fb1[i] = rand();
fb2[i] = rand();
}

time(&t);
strftime(datebuffer, sizeof(datebuffer), "%Y-%m-%d %H:%M UTC", gmtime(&t));

printf("# Pixel Conversion Test %s\n", datebuffer);
printf("#\n");
printf("# Frame buffer: %dx%d pixels\n", fbsize, fbsize);
printf("# Tile size: %dx%d pixels\n", tile, tile);
printf("#\n");
printf("# Note: Results are Mpixels/sec\n");
printf("#\n");

printf("Source format,Destination Format");
for (i = 0;i < sizeof(tests)/sizeof(tests[0]);i++)
printf(",%s", tests[i].label);
printf("\n");

rfb::PixelFormat dstpf, srcpf;

/* rgb888 targets */

dstpf.parse("rgb888");

srcpf.parse("rgb888");
doTests(dstpf, srcpf);

srcpf.parse("bgr888");
doTests(dstpf, srcpf);

srcpf.parse("rgb565");
doTests(dstpf, srcpf);

srcpf.parse("rgb232");
doTests(dstpf, srcpf);

/* rgb565 targets */

dstpf.parse("rgb565");

srcpf.parse("rgb888");
doTests(dstpf, srcpf);

srcpf.parse("bgr565");
doTests(dstpf, srcpf);

srcpf.parse("rgb232");
doTests(dstpf, srcpf);

/* rgb565 with endian conversion (both ways) */

dstpf = rfb::PixelFormat(32, 24, false, true, 255, 255, 255, 0, 8, 16);
srcpf = rfb::PixelFormat(32, 24, true, true, 255, 255, 255, 0, 8, 16);

doTests(srcpf, dstpf);

doTests(dstpf, srcpf);

dstpf = rfb::PixelFormat(16, 16, false, true, 31, 63, 31, 0, 5, 11);
srcpf = rfb::PixelFormat(16, 16, true, true, 31, 63, 31, 0, 5, 11);

doTests(srcpf, dstpf);

doTests(dstpf, srcpf);

return 0;
}


+ 76
- 0
tests/util.cxx View File

@@ -0,0 +1,76 @@
/* Copyright 2013-2014 Pierre Ossman <ossman@cendio.se> for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#include <stdint.h>

#ifdef WIN32
#include <windows.h>
#else
#include <sys/resource.h>
#endif

#ifdef WIN32
static FILETIME cpuCounters[2];
#else
struct rusage cpuCounters[2];
#endif

static void measureCpu(void *counter)
{
#ifdef WIN32
FILETIME dummy1, dummy2, dummy3;

GetProcessTimes(GetCurrentProcess(), &dummy1, &dummy2,
&dummy3, (FILETIME*)counter);
#else
getrusage(RUSAGE_SELF, (struct rusage*)counter);
#endif
}

void startCpuCounter(void)
{
measureCpu(&cpuCounters[0]);
}

void endCpuCounter(void)
{
measureCpu(&cpuCounters[1]);
}

double getCpuCounter(void)
{
double seconds;

#ifdef WIN32
uint64_t counters[2];

counters[0] = (uint64_t)cpuCounters[0].dwHighDateTime << 32 |
cpuCounters[0].dwLowDateTime;
counters[1] = (uint64_t)cpuCounters[1].dwHighDateTime << 32 |
cpuCounters[1].dwLowDateTime;

seconds = (double)(counters[1] - counters[2]) / 10000000.0;
#else
seconds = (double)(cpuCounters[1].ru_utime.tv_sec -
cpuCounters[0].ru_utime.tv_sec);
seconds += (double)(cpuCounters[1].ru_utime.tv_usec -
cpuCounters[0].ru_utime.tv_usec) / 1000000.0;
#endif

return seconds;
}

+ 27
- 0
tests/util.h View File

@@ -0,0 +1,27 @@
/* Copyright 2013-2014 Pierre Ossman <ossman@cendio.se> for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#ifndef __TESTS_UTIL_H__
#define __TESTS_UTIL_H__

void startCpuCounter(void);
void endCpuCounter(void);

double getCpuCounter(void);

#endif

Loading…
Cancel
Save