summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2016-12-20 12:32:37 +0100
committerPierre Ossman <ossman@cendio.se>2017-01-04 15:37:34 +0100
commit38a1c70260f3457977f073cc1535a542877e8671 (patch)
tree1172fe1a9244bc17ba9113bd473fe3fd4e6caf42 /tests
parent2e33286868c69a9117b1062392b9c6368d9c9b52 (diff)
downloadtigervnc-38a1c70260f3457977f073cc1535a542877e8671.tar.gz
tigervnc-38a1c70260f3457977f073cc1535a542877e8671.zip
Add test to measure framebuffer performance
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt17
-rw-r--r--tests/fbperf.cxx225
-rw-r--r--tests/util.cxx44
-rw-r--r--tests/util.h5
4 files changed, 291 insertions, 0 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index bfd69dcd..164660a3 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -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()
diff --git a/tests/fbperf.cxx b/tests/fbperf.cxx
new file mode 100644
index 00000000..53334a6d
--- /dev/null
+++ b/tests/fbperf.cxx
@@ -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;
+}
diff --git a/tests/util.cxx b/tests/util.cxx
index 4683d351..17a83698 100644
--- a/tests/util.cxx
+++ b/tests/util.cxx
@@ -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;
+}
diff --git a/tests/util.h b/tests/util.h
index 16f2ba2f..2b8ab4a8 100644
--- a/tests/util.h
+++ b/tests/util.h
@@ -34,4 +34,9 @@ void endCpuCounter(cpucounter_t c);
double getCpuCounter(cpucounter_t c);
+void startTimeCounter(void);
+void endTimeCounter(void);
+
+double getTimeCounter(void);
+
#endif