[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [E-devel] Benchmark: Brute force copy from GL pbuffer to image as data



On Thu, 23 Nov 2006 23:53:16 +0100 (CET) centipede@takhis.net babbled:

> Sorry for lack of response. Illness and loss of internet connection. This
> conversation is modem powered.
> 
> As I mentioned a little while ago, I wanted to benchmark the speed at
> which an OpenGL rendering into a buffer can be moved out of video memory,
> into the system memory and then back into an Evas Image and rendered to
> the screen.
> 
> Would anybody be surprised if I said that it really isn't fast... ahem.
> Just had to try. Pseudo code of a main loop:

I'd tell you "why did you even try? I could have told you that!" :) It's not a
sane path to go down. reading pixels back from the video card is simply death-
asking for pain. the rule to follow here is "DON'T DO IT" :)

> 1) Render frame to a PBuffer
> 2) Get the data using glReadPixels
> 3) Put the frame back into an image using evas_object_image_data_set
> 
> Compile as a C++ program:
> 
> gcc bench_gl_evas.cpp -o bench_gl_evas `ecore-config --libs --cflags`
> `evas-config --libs --cflags` -lGL -lGLU -lstdc++
> 
> Regards Rene Jensen
> 
> 
> 
> ------ bench_gl_evas.cpp -----------------------
> 
> #include <iostream>
> #include <fstream>
> #include <X11/Xlib.h>
> #include <X11/Xutil.h>
> #include <GL/gl.h>
> #include <GL/glu.h>
> #include <GL/glx.h>
> 
> #include <Ecore.h>
> #include <Ecore_Evas.h>
> #include <Evas.h>
> 
> static const int    PBUFFER_WIDTH = 512;
> static const int    PBUFFER_HEIGHT = 512;
> struct Vertex
> {
>     float tu, tv;
>     float x, y, z;
> };
> Vertex g_cubeVertices[] =
> {
>     { 0.0f,0.0f, -1.0f,-1.0f, 1.0f },
>     { 1.0f,0.0f,  1.0f,-1.0f, 1.0f },
>     { 1.0f,1.0f,  1.0f, 1.0f, 1.0f },
>     { 0.0f,1.0f, -1.0f, 1.0f, 1.0f },
>     { 1.0f,0.0f, -1.0f,-1.0f,-1.0f },
>     { 1.0f,1.0f, -1.0f, 1.0f,-1.0f },
>     { 0.0f,1.0f,  1.0f, 1.0f,-1.0f },
>     { 0.0f,0.0f,  1.0f,-1.0f,-1.0f },
>     { 0.0f,1.0f, -1.0f, 1.0f,-1.0f },
>     { 0.0f,0.0f, -1.0f, 1.0f, 1.0f },
>     { 1.0f,0.0f,  1.0f, 1.0f, 1.0f },
>     { 1.0f,1.0f,  1.0f, 1.0f,-1.0f },
>     { 1.0f,1.0f, -1.0f,-1.0f,-1.0f },
>     { 0.0f,1.0f,  1.0f,-1.0f,-1.0f },
>     { 0.0f,0.0f,  1.0f,-1.0f, 1.0f },
>     { 1.0f,0.0f, -1.0f,-1.0f, 1.0f },
>     { 1.0f,0.0f,  1.0f,-1.0f,-1.0f },
>     { 1.0f,1.0f,  1.0f, 1.0f,-1.0f },
>     { 0.0f,1.0f,  1.0f, 1.0f, 1.0f },
>     { 0.0f,0.0f,  1.0f,-1.0f, 1.0f },
>     { 0.0f,0.0f, -1.0f,-1.0f,-1.0f },
>     { 1.0f,0.0f, -1.0f,-1.0f, 1.0f },
>     { 1.0f,1.0f, -1.0f, 1.0f, 1.0f },
>     { 0.0f,1.0f, -1.0f, 1.0f,-1.0f }
> };
> 
> // This class is simply a fancy way of rendering a scene and getting it
> //  as an ARGB array of integers
> //
> class RenderNode
> {
> public:
>     unsigned long*        data;
>     Display*            display;
>     GLXPbuffer            pbuffer;
>     GLXContext            pbufferContext;
> 
>     void init ()
>     {
>         // Open the X display
>         display = XOpenDisplay(0);
>         if (! display)
>             throw "Can't open X display";
> 
>         int nItems;
>         int attrib[] =
>         {
>             GLX_DOUBLEBUFFER,  False,
>             GLX_RED_SIZE,      1,
>             GLX_GREEN_SIZE,    1,
>             GLX_BLUE_SIZE,     1,
>             GLX_DEPTH_SIZE,    1,
>             GLX_RENDER_TYPE,   GLX_RGBA_BIT,
>             GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
>             None
>         };
> 
>         int pbufAttrib[] =
>         {
>             GLX_PBUFFER_WIDTH, PBUFFER_WIDTH,
>             GLX_PBUFFER_HEIGHT, PBUFFER_HEIGHT,
>             GLX_LARGEST_PBUFFER, False,
>             None
>         };
> 
>         GLXFBConfig *fbconfig = glXChooseFBConfig (
>             display, DefaultScreen(display),
>             attrib, &nItems);
> 
>         if (fbconfig == 0)
>             throw "Can't choose fbconfig";
> 
>         pbuffer = glXCreatePbuffer (
>             display, fbconfig[0], pbufAttrib);
>         XVisualInfo* visinfo = glXGetVisualFromFBConfig(
>             display, fbconfig[0] );
>         if (! visinfo)
>             throw "Error: init - Couldn't get wanted visual";
> 
>         pbufferContext = glXCreateNewContext(display, fbconfig[0],
>             GLX_RGBA_TYPE, NULL, GL_TRUE);
>         if (! pbufferContext)
>             throw "Can't make pbuffer context";
> 
>         XFree( fbconfig );
>         XFree( visinfo );
> 
>         data = new unsigned long[PBUFFER_WIDTH*PBUFFER_HEIGHT];
>     }
> 
>     void render ()
>     {
>         if (! glXMakeContextCurrent(
>                 display, pbuffer, pbuffer, pbufferContext))
>             throw "Can't make context current";
>         static float time = 20.0;
>         time += 0.1;
> 
>         glClearColor( 0,0,0, 1.0f );
>         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
> 
>         glMatrixMode( GL_PROJECTION );
>         glLoadIdentity();
>         gluPerspective( 45.0f,
>             PBUFFER_WIDTH / PBUFFER_HEIGHT, 0.1f, 10.0f );
> 
>         glMatrixMode( GL_MODELVIEW );
>         glLoadIdentity();
>         glTranslatef( 0.0f, 0.0f, -5.0f );
>         glRotatef( time, 1.0f, 0.0f, 0.0f );
>         glRotatef( time, 0.0f, 1.0f, 0.0f );
> 
>         glInterleavedArrays( GL_T2F_V3F, 0, g_cubeVertices );
>         glDrawArrays( GL_QUADS, 0, 24 );
> 
>         glFlush();
> 
>         glReadPixels (0,0, PBUFFER_WIDTH, PBUFFER_HEIGHT,
>             GL_BGRA, GL_UNSIGNED_BYTE, data);
>     }
> };
> 
> 
> 
> 
> Ecore_Evas *ee;
> Evas *evas;
> Evas_Object *bg;
> RenderNode* renderNode;
> 
> // This timer callback will transfer the data in the renderNode to
> //  an image and then refresh the Evas to make the changed image visible.
> int timer_cb (void *data)
> {
>     renderNode->render();
>     evas_object_image_data_set (
>         (Evas_Object*)bg, renderNode->data);
>     evas_object_image_data_update_add (bg, 0,0,
>         PBUFFER_WIDTH, PBUFFER_HEIGHT);
> 
>     return 1;
> }
> 
> int main(int argc, const char** argv)
> {
>     renderNode = new RenderNode();
>     renderNode->init();
> 
>     ecore_init();
>     ecore_app_args_set(argc, argv);
>     if (!ecore_evas_init()) return -1;
>     ee = ecore_evas_software_x11_new(NULL, 0, 0, 0,
>         PBUFFER_WIDTH, PBUFFER_HEIGHT);
>     if (!ee) return -1;
> 
>     ecore_evas_title_set(ee, "EE Test");
>     ecore_evas_show(ee);
>     evas = ecore_evas_get(ee);
> 
>     bg = evas_object_image_add(evas);
>     evas_object_image_size_set (bg, PBUFFER_WIDTH,PBUFFER_HEIGHT);
>     evas_object_move(bg, 0, 0);
>     evas_object_resize(bg, PBUFFER_WIDTH, PBUFFER_HEIGHT);
>     evas_object_layer_set(bg, 0);
>     evas_object_color_set(bg, 255, 255, 220, 255);
>     evas_object_show(bg);
>     evas_object_image_data_set (bg, renderNode->data);
>     evas_object_image_size_set (bg, PBUFFER_WIDTH,PBUFFER_HEIGHT);
>     evas_object_image_fill_set (bg, 0,0,PBUFFER_WIDTH, PBUFFER_HEIGHT);
>     ecore_timer_add(0.01, timer_cb, bg);
> 
>     ecore_main_loop_begin();
> 
>     //while (true)
>     //{
>         //ecore_main_loop_iterate();
>         //renderNode->render();
>         //evas_object_image_data_set (bg, renderNode->data);
>         //evas_object_image_data_update_add (
>         //    bg, 0,0,PBUFFER_WIDTH, PBUFFER_HEIGHT);
>     //}
> 
> 
>     return 0;
> }
> 
> 
> 
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> enlightenment-devel mailing list
> enlightenment-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> 


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler)    raster@rasterman.com
裸好多
Tokyo, Japan (東京 日本)