Browse Source

Add test to measure framebuffer performance

tags/v1.7.90
Pierre Ossman 7 years ago
parent
commit
38a1c70260
4 changed files with 291 additions and 0 deletions
  1. 17
    0
      tests/CMakeLists.txt
  2. 225
    0
      tests/fbperf.cxx
  3. 44
    0
      tests/util.cxx
  4. 5
    0
      tests/util.h

+ 17
- 0
tests/CMakeLists.txt View File

@@ -16,3 +16,20 @@ target_link_libraries(encperf test_util rfb)

add_executable(hostport hostport.cxx)
target_link_libraries(hostport rfb)

set(FBPERF_SOURCES
fbperf.cxx
../vncviewer/FLTKPixelBuffer.cxx
../vncviewer/PlatformPixelBuffer.cxx)
if(WIN32)
set(FBPERF_SOURCES ${FBPERF_SOURCES} ../vncviewer/Win32PixelBuffer.cxx)
elseif(APPLE)
set(FBPERF_SOURCES ${FBPERF_SOURCES} ../vncviewer/OSXPixelBuffer.cxx)
else()
set(FBPERF_SOURCES ${FBPERF_SOURCES} ../vncviewer/X11PixelBuffer.cxx)
endif()
add_executable(fbperf ${FBPERF_SOURCES})
target_link_libraries(fbperf test_util rfb ${FLTK_LIBRARIES} ${GETTEXT_LIBRARIES})
if(APPLE)
target_link_libraries(fbperf "-framework Cocoa" "-framework Carbon")
endif()

+ 225
- 0
tests/fbperf.cxx View File

@@ -0,0 +1,225 @@
/* Copyright 2016 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 <sys/time.h>

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/fl_draw.H>

#include <rdr/Exception.h>
#include <rfb/util.h>

#include "../vncviewer/PlatformPixelBuffer.h"
#include "../vncviewer/FLTKPixelBuffer.h"

#if defined(WIN32)
#include "../vncviewer/Win32PixelBuffer.h"
#elif defined(__APPLE__)
#include "../vncviewer/OSXPixelBuffer.h"
#else
#include "../vncviewer/X11PixelBuffer.h"
#endif

#include "util.h"

class TestWindow: public Fl_Window {
public:
TestWindow();
~TestWindow();

virtual void draw();

protected:
virtual void flush();

void update();
virtual void changefb();

static void timer(void* data);

public:
unsigned long long pixels, frames;
double time;

protected:
PlatformPixelBuffer* fb;
};

class PartialTestWindow: public TestWindow {
protected:
virtual void changefb();
};

TestWindow::TestWindow() :
Fl_Window(1024, 768, "Framebuffer Performance Test")
{
rdr::U32 pixel;

pixels = 0;
frames = 0;
time = 0;

try {
#if defined(WIN32)
fb = new Win32PixelBuffer(w(), h());
#elif defined(__APPLE__)
fb = new OSXPixelBuffer(w(), h());
#else
fb = new X11PixelBuffer(w(), h());
#endif
} catch (rdr::Exception& e) {
fb = new FLTKPixelBuffer(w(), h());
}

pixel = 0;
fb->fillRect(fb->getRect(), &pixel);
}

TestWindow::~TestWindow()
{
delete fb;

Fl::remove_idle(timer, this);
}

void TestWindow::draw()
{
int X, Y, W, H;

// We cannot update the damage region from inside the draw function,
// so delegate this to an idle function
Fl::add_idle(timer, this);

// Check what actually needs updating
fl_clip_box(0, 0, w(), h(), X, Y, W, H);
if ((W == 0) || (H == 0))
return;

fb->draw(X, Y, X, Y, W, H);

pixels += W*H;
frames++;
}

void TestWindow::flush()
{
startTimeCounter();
Fl_Window::flush();
#if !defined(WIN32) && !defined(__APPLE__)
// Make sure we measure any work we queue up
XSync(fl_display, False);
#endif
endTimeCounter();

time += getTimeCounter();
}

void TestWindow::update()
{
rfb::Rect r;

startTimeCounter();

while (fb->isRendering())
Fl::wait();

changefb();

r = fb->getDamage();
damage(FL_DAMAGE_USER1, r.tl.x, r.tl.y, r.width(), r.height());

#if !defined(WIN32) && !defined(__APPLE__)
// Make sure we measure any work we queue up
XSync(fl_display, False);
#endif

endTimeCounter();

time += getTimeCounter();
}

void TestWindow::changefb()
{
rdr::U32 pixel;

pixel = rand();
fb->fillRect(fb->getRect(), &pixel);
}

void TestWindow::timer(void* data)
{
TestWindow* self;

Fl::remove_idle(timer, data);

self = (TestWindow*)data;
self->update();
}

void PartialTestWindow::changefb()
{
rfb::Rect r;
rdr::U32 pixel;

r = fb->getRect();
r.tl.x += w() / 4;
r.tl.y += h() / 4;
r.br.x -= w() / 4;
r.br.y -= h() / 4;

pixel = rand();
fb->fillRect(r, &pixel);
}

static void dotest(TestWindow* win)
{
struct timeval start;
char s[1024];

win->show();

gettimeofday(&start, NULL);
while (rfb::msSince(&start) < 10000)
Fl::wait();

fprintf(stderr, "Rendering time: %g ms/frame\n",
win->time * 1000.0 / win->frames);
rfb::siPrefix(win->pixels / win->time,
"pixels/s", s, sizeof(s));
fprintf(stderr, "Rendering rate: %s\n", s);
}

int main(int argc, char** argv)
{
TestWindow* win;

fprintf(stderr, "Full window update:\n\n");
win = new TestWindow();
dotest(win);
delete win;
fprintf(stderr, "\n");

fprintf(stderr, "Partial window update:\n\n");
win = new PartialTestWindow();
dotest(win);
delete win;
fprintf(stderr, "\n");

return 0;
}

+ 44
- 0
tests/util.cxx View File

@@ -24,6 +24,7 @@
#include <windows.h>
#else
#include <sys/resource.h>
#include <sys/time.h>
#endif

#include "util.h"
@@ -132,3 +133,46 @@ double getCpuCounter(cpucounter_t c)

return sysSeconds + userSeconds;
}

#ifdef WIN32
static LARGE_INTEGER timeStart, timeEnd;
#else
static struct timeval timeStart, timeEnd;
#endif

void startTimeCounter(void)
{
#ifdef WIN32
QueryPerformanceCounter(&timeStart);
#else
gettimeofday(&timeStart, NULL);
#endif
}

void endTimeCounter(void)
{
#ifdef WIN32
QueryPerformanceCounter(&timeEnd);
#else
gettimeofday(&timeEnd, NULL);
#endif
}

double getTimeCounter(void)
{
double time;

#ifdef WIN32
LARGE_INTEGER freq;

QueryPerformanceFrequency(&freq);

time = timeEnd.QuadPart - timeStart.QuadPart;
time = time / freq.QuadPart;
#else
time = (double)timeEnd.tv_sec - timeStart.tv_sec;
time += (double)(timeEnd.tv_usec - timeStart.tv_usec) / 1000000.0;
#endif

return time;
}

+ 5
- 0
tests/util.h View File

@@ -34,4 +34,9 @@ void endCpuCounter(cpucounter_t c);

double getCpuCounter(cpucounter_t c);

void startTimeCounter(void);
void endTimeCounter(void);

double getTimeCounter(void);

#endif

Loading…
Cancel
Save