Implement fbdev swapbuffers()
authorJon Smirl <jonsmirl@gmail.com>
Wed, 18 May 2005 01:44:11 +0000 (01:44 +0000)
committerJon Smirl <jonsmirl@gmail.com>
Wed, 18 May 2005 01:44:11 +0000 (01:44 +0000)
progs/egl/demo2.c
src/mesa/drivers/dri/fb/fb_egl.c

index e8ace3da8e2460a34ed86f3dcc71d66bc8afc0ac..4e0004d930f98412c6caa8a862833702c9c3a12c 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <GLES/egl.h>
 
-#define FRONTBUFFER
+//#define FRONTBUFFER
 
 static void _subset_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
 {
@@ -22,7 +22,7 @@ static void _subset_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
 }
 
 
-static void redraw(EGLDisplay dpy, int rot)
+static void redraw(EGLDisplay dpy, EGLSurface surf, int rot)
 {
    printf("Redraw event\n");
 
@@ -51,7 +51,7 @@ static void redraw(EGLDisplay dpy, int rot)
 #ifdef FRONTBUFFER
    glFlush();
 #else
-   EGLSwapBuffers( dpy, w ); 
+   eglSwapBuffers( dpy, surf ); 
 #endif
    glFinish();
 }
@@ -167,7 +167,7 @@ main(int argc, char *argv[])
    glShadeModel( GL_FLAT );
    
    for (i = 0; i < 6; i++) {
-      redraw(d, i*10 );
+      redraw(d, screen_surf, i*10 );
 
       printf("sleep(1)\n");   
       sleep(1);  
index 79640bbc6181115e817836dff28485c8749ec961..9541f4f39d32b4e06ba8079bc63382988368d434 100644 (file)
@@ -757,6 +757,52 @@ err:
 }
 
 
+/* If the backbuffer is on a videocard, this is extraordinarily slow!
+ */
+static EGLBoolean
+fbSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+{
+   fbContext *context = (fbContext *)_eglGetCurrentContext();
+   fbSurface *fs =  Lookup_fbSurface(draw);
+   struct gl_renderbuffer * front_renderbuffer = fs->mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+   void *frontBuffer = front_renderbuffer->Data;
+   int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch;
+   void *backBuffer = fs->mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data;
+
+   if (!_eglSwapBuffers(drv, dpy, draw))
+      return EGL_FALSE;
+
+   if (context) {
+      GLcontext *ctx = context->glCtx;
+      
+      if (ctx->Visual.doubleBufferMode) {
+        int i;
+        int offset = 0;
+         char *tmp = _mesa_malloc(currentPitch);
+
+         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
+
+         ASSERT(frontBuffer);
+         ASSERT(backBuffer);
+
+        for (i = 0; i < fs->Base.Height; i++) {
+            _mesa_memcpy(tmp, (char *) backBuffer + offset,
+                         currentPitch);
+            _mesa_memcpy((char *) frontBuffer + offset, tmp,
+                          currentPitch);
+            offset += currentPitch;
+        }
+           
+        _mesa_free(tmp);
+      }
+   }
+   else {
+      /* XXX this shouldn't be an error but we can't handle it for now */
+      _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n");
+   }
+}
+
+
 /*
  * Just to silence warning
  */
@@ -793,6 +839,7 @@ _eglMain(NativeDisplayType dpy)
    fb->Base.DestroyContext = fbDestroyContext;
    fb->Base.CreateScreenSurfaceMESA = fbCreateScreenSurfaceMESA;
    fb->Base.ShowSurfaceMESA = fbShowSurfaceMESA;
+   fb->Base.SwapBuffers = fbSwapBuffers;
    
    /* enable supported extensions */
    fb->Base.MESA_screen_surface = EGL_TRUE;