From: Vadim Zeitlin Date: Tue, 5 Feb 2013 20:47:10 +0000 (+0000) Subject: Added possibility to use OpenGL for bitmap drawing to graphics benchmark. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/54d25f9d8a611303b0023a22cc3e05a086658497 Added possibility to use OpenGL for bitmap drawing to graphics benchmark. Draw the bitmap using OpenGL textures. Even without using PBO this results in much greater performance than using wxImage or raw bitmap access. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73474 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/tests/benchmarks/graphics.cpp b/tests/benchmarks/graphics.cpp index 457aa39ade..4366073f2b 100644 --- a/tests/benchmarks/graphics.cpp +++ b/tests/benchmarks/graphics.cpp @@ -19,6 +19,33 @@ #include "wx/stopwatch.h" #include "wx/crt.h" +#if wxUSE_GLCANVAS + #include "wx/glcanvas.h" + #ifdef _MSC_VER + #pragma comment(lib, "opengl32") + #endif +#endif // wxUSE_GLCANVAS + +#if wxUSE_GLCANVAS + +GLuint g_texture; +wxImage g_image; + +void InitializeTexture(int w, int h) +{ + glGenTextures(1, &g_texture); + glBindTexture(GL_TEXTURE_2D, g_texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + g_image.Create(w, h, false /* don't clear */); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGB, g_image.GetWidth(), g_image.GetHeight(), 0, + GL_RGB, GL_UNSIGNED_BYTE, g_image.GetData()); +} +#endif // wxUSE_GLCANVAS + struct GraphicsBenchmarkOptions { GraphicsBenchmarkOptions() @@ -42,7 +69,8 @@ struct GraphicsBenchmarkOptions useMemory = false; useDC = - useGC = false; + useGC = + useGL = false; } long mapMode, @@ -62,7 +90,8 @@ struct GraphicsBenchmarkOptions useMemory; bool useDC, - useGC; + useGC, + useGL; } opts; class GraphicsBenchmarkFrame : public wxFrame @@ -71,15 +100,56 @@ public: GraphicsBenchmarkFrame() : wxFrame(NULL, wxID_ANY, "wxWidgets Graphics Benchmark") { - Connect(wxEVT_PAINT, - wxPaintEventHandler(GraphicsBenchmarkFrame::OnPaint)); + SetClientSize(opts.width, opts.height); + +#if wxUSE_GLCANVAS + m_glCanvas = NULL; + + if ( opts.useGL ) + { + m_glCanvas = new wxGLCanvas(this, wxID_ANY, NULL, + wxPoint(0, 0), + wxSize(opts.width, opts.height)); + m_glContext = new wxGLContext(m_glCanvas); + m_glContext->SetCurrent(*m_glCanvas); + + glViewport(0, 0, opts.width, opts.height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1, 1, -1, 1, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + InitializeTexture(opts.width, opts.height); + + m_glCanvas->Connect( + wxEVT_PAINT, + wxPaintEventHandler(GraphicsBenchmarkFrame::OnGLRender), + NULL, + this + ); + } + else // Not using OpenGL +#endif // wxUSE_GLCANVAS + { + Connect(wxEVT_PAINT, + wxPaintEventHandler(GraphicsBenchmarkFrame::OnPaint)); + } + + Connect(wxEVT_SIZE, wxSizeEventHandler(GraphicsBenchmarkFrame::OnSize)); m_bitmap.Create(64, 64, 32); Show(); - SetClientSize(opts.width, opts.height); } +#if wxUSE_GLCANVAS + virtual ~GraphicsBenchmarkFrame() + { + delete m_glContext; + } +#endif // wxUSE_GLCANVAS + private: // Just change the image in some (quick) way to show that it's really being // updated on screen. @@ -93,6 +163,54 @@ private: n++; } } + +#if wxUSE_GLCANVAS + void OnGLRender(wxPaintEvent& WXUNUSED(event)) + { + m_glContext->SetCurrent(*m_glCanvas); + glEnable(GL_TEXTURE_2D); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + wxPrintf("Benchmarking %s: ", "OpenGL images"); + fflush(stdout); + + wxStopWatch sw; + for ( int n = 0; n < opts.numIters; n++ ) + { + UpdateRGB(g_image.GetData(), n); + + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, opts.width, opts.height, + GL_RGB, GL_UNSIGNED_BYTE, g_image.GetData()); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(-1.0, -1.0); + + glTexCoord2f(0, 1); + glVertex2f(-1.0, 1.0); + + glTexCoord2f(1, 1); + glVertex2f(1.0, 1.0); + + glTexCoord2f(1, 0); + glVertex2f(1.0, -1.0); + glEnd(); + + m_glCanvas->SwapBuffers(); + } + + const long t = sw.Time(); + + wxPrintf("%ld images done in %ldms = %gus/image or %d FPS\n", + opts.numIters, t, (1000. * t)/opts.numIters, + (1000*opts.numIters + t - 1)/t); + + wxTheApp->ExitMainLoop(); + } +#endif // wxUSE_GLCANVAS + void OnPaint(wxPaintEvent& WXUNUSED(event)) { if ( opts.usePaint ) @@ -306,6 +424,10 @@ private: wxBitmap m_bitmap; +#if wxUSE_GLCANVAS + wxGLCanvas* m_glCanvas; + wxGLContext* m_glContext; +#endif // wxUSE_GLCANVAS }; class GraphicsBenchmarkApp : public wxApp @@ -325,6 +447,9 @@ public: { wxCMD_LINE_SWITCH, "", "memory" }, { wxCMD_LINE_SWITCH, "", "dc" }, { wxCMD_LINE_SWITCH, "", "gc" }, +#if wxUSE_GLCANVAS + { wxCMD_LINE_SWITCH, "", "gl" }, +#endif // wxUSE_GLCANVAS { wxCMD_LINE_OPTION, "m", "map-mode", "", wxCMD_LINE_VAL_NUMBER }, { wxCMD_LINE_OPTION, "p", "pen-width", "", wxCMD_LINE_VAL_NUMBER }, { wxCMD_LINE_OPTION, "w", "width", "", wxCMD_LINE_VAL_NUMBER }, @@ -379,10 +504,24 @@ public: opts.useDC = parser.Found("dc"); opts.useGC = parser.Found("gc"); - if ( !(opts.useDC || opts.useGC) ) +#if wxUSE_GLCANVAS + opts.useGL = parser.Found("gl"); + if ( opts.useGL ) { - opts.useDC = - opts.useGC = true; + if ( opts.useDC || opts.useGC ) + { + wxLogError("Can't use both OpenGL and normal graphics."); + return false; + } + } + else // Not using OpenGL +#endif // wxUSE_GLCANVAS + { + if ( !(opts.useDC || opts.useGC) ) + { + opts.useDC = + opts.useGC = true; + } } return true;