Hello again!
I've managed to create the patch, it should be in the attachment.
Here are the explanations:

* Since only 24-bit XVisualInfo's were provided, I've changed the __vglConfigDepth function in glxvisual.cpp to provide depth for the visual that is corresponding to the FBConfig on the local display. The modified version returns 32-bit visuals when needed. * The faked implementation of EXT_texture_from_pixmap OpenGL extension didn't work correctly, because the extension can only work with GLXPixmaps, not with windows and not with pbuffers. The approach I used is: fake XCompositeNameWindowPixmap, XCreatePixmap and XFreePixmap to know when the original pixmap is created, store the information on the created pixmap (with Window form XCompositeNameWindowPixmap) to use later. Then if and when the pixmap created previously is used to create a GLXPixmap, add other values to the stored information and create another pixmap using XShm. When this GLXPixmap is being used for glXBindTexImageEXT the original pixmap's contents are copied to the shm segment to be made available to the local display's XServer. The texture is then filled with data using the shm address. If the FBConfig is y-inverted (GLX_Y_INVERTED), the function modifies the GL_TEXTURE matrix to invert the texture coordinates. When glXReleaseTexImageEXT is called and if the FBConfig is inverted, the GL_TEXTURE matrix is restored to the previous state. This part covers faker-glx.cpp, faker.cpp, faker-sym.h, faker-sym.cpp, faker-mapfile.c and the newly added shmpixmap.h that provides storage for the mentioned pixmaps.

The patch should be applied to "vgl" directory (which contains "rr")

But these additions are not enough to run KDE4 in OpenGL mode. You also have to do the following:
* Go to System Settings->Desktop->Advanced.
* Check "Disable functionality checks" checkbox.
* Select "Texture From Pixmap" OpenGL mode.

Also I didn't find how to enable the option called "glStrictBinding", so I had to simply cut it from kwin/scene_opengl.cpp file from kdebase-workspace.

If everything mentioned above is accomplished, you should be able to run KDE4 in OpenGL mode over VNC.

I would be very grateful if somebody gave me feedback on that patch :)

P.S. I've been able to test it on Code2Duo P8400/2048 RAM/NV 9600 GS, Debian 5.0
diff --git a/rr/faker-glx.cpp b/rr/faker-glx.cpp
index b74f320..1d60f19 100644
--- a/rr/faker-glx.cpp
+++ b/rr/faker-glx.cpp
@@ -14,6 +14,8 @@
  */
 
 #include "faker-sym.h"
+#include "shmpixmap.h"
+#include </usr/include/GL/glu.h>
 
 #define prargd(a) rrout.print("%s=0x%.8lx(%s) ", #a, (unsigned long)a, 
a?DisplayString(a):"NULL")
 #define prargx(a) rrout.print("%s=0x%.8lx ", #a, (unsigned long)a)
@@ -773,13 +775,51 @@ Bool glXResetFrameCountNV(Display *dpy, int screen)
 void glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
        const int *attrib_list)
 {
+       ShmPixmapStorage* s = ShmPixmapStorage::getInstance();
+        ShmPixmapInfo* info = s->getInfoForGLXPixmap( drawable );
+        if( info != NULL )
+        {
+               int fmt = info->depth == 32 ? GL_RGBA : GL_RGB;
+               _XCopyArea( info->display, info->originalPixmap, 
info->sharedPixmap, info->gc, 0, 0, info->width, info->height, 0, 0 );
+               XSync( info->display, False );
+               glTexImage2D( GL_TEXTURE_2D, 0, fmt, info->width, info->height, 
0, GL_BGRA, GL_UNSIGNED_BYTE, info->shmInfo.shmaddr );
+
+               if( info->invert )
+               {
+                       glGetDoublev( GL_TEXTURE_MATRIX, info->matrix );
+                       double m[ 16 ] = {
+                               1.0, 0.0, 0.0, 0.0,
+                               0.0, -1.0, 0.0, 0.0,
+                               0.0, 0.0, 1.0, 0.0,
+                               0.0, 1.0, 0.0, 1.0
+                       };
+                       glMatrixMode( GL_TEXTURE );
+                       glLoadMatrixd( m );
+                       glMatrixMode( GL_MODELVIEW );
+               }
+               
+               return;
+        }
        GLXDrawable dr = ServerDrawable( dpy, drawable );
        _glXBindTexImageEXT(_localdpy, dr, buffer, attrib_list);
 }
 
 void glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
 {
-       _glXReleaseTexImageEXT(_localdpy, ServerDrawable(dpy, drawable), 
buffer);
+       ShmPixmapStorage* s = ShmPixmapStorage::getInstance();
+        ShmPixmapInfo* info = s->getInfoForGLXPixmap( drawable );
+        if( info != NULL )
+       {
+               if( info->invert )
+               {
+                       glMatrixMode( GL_TEXTURE );
+                       glLoadMatrixd( info->matrix );
+                       glMatrixMode( GL_MODELVIEW );
+               }
+               return;
+       }
+       else
+               _glXReleaseTexImageEXT(_localdpy, ServerDrawable(dpy, 
drawable), buffer);
 }
 
 #define checkfaked(f) if(!strcmp((char *)procName, #f)) retval=(void 
(*)(void))f;
diff --git a/rr/faker-mapfile.c b/rr/faker-mapfile.c
index 2b56f33..800fab2 100755
--- a/rr/faker-mapfile.c
+++ b/rr/faker-mapfile.c
@@ -125,6 +125,9 @@
                XResizeWindow;
                XServerVendor;
                XWindowEvent;
+               XFreePixmap;
+               XCreatePixmap;
+               XCompositeNameWindowPixmap;
                #ifdef sparc
                XSolarisGetVisualGamma;
                #endif
diff --git a/rr/faker-sym.cpp b/rr/faker-sym.cpp
index 3bf201a..2b50ba0 100644
--- a/rr/faker-sym.cpp
+++ b/rr/faker-sym.cpp
@@ -35,6 +35,7 @@ static void *loadsym(void *dllhnd, const char *symbol, int 
quiet)
 
 static void *gldllhnd=NULL;
 static void *x11dllhnd=NULL;
+static void* xcompdllhnd=NULL;
 
 void __vgl_loaddlsymbols(void)
 {
@@ -144,6 +145,20 @@ void __vgl_loadsymbols(void)
                        __vgl_safeexit(1);
                }
        }
+
+       dllhnd=_vgl_dlopen( "libXcomposite.so", RTLD_NOW);
+       if(!dllhnd)
+       {
+               rrout.print("[VGL] ERROR: Could not open 
libXcomposite.so\n[VGL]    %s\n",
+                       dlerror());
+               __vgl_safeexit(1);
+       }
+       else xcompdllhnd=dllhnd;
+       if(__vgl_loadxcompsymbols(dllhnd)<0)
+       {
+               rrout.print("[VGL] ERROR: Could not load Xcomposite symbols 
from libXcomposite.\n");
+               __vgl_safeexit(1);
+       }
 }
 
 static int __vgl_loadglsymbols(void *dllhnd)
@@ -272,6 +287,16 @@ static int __vgl_loadx11symbols(void *dllhnd)
        lsym(XResizeWindow);
        lsym(XServerVendor);
        lsym(XWindowEvent);
+       lsym(XFreePixmap);
+       lsym(XCreatePixmap);
+       return 0;
+}
+
+static int __vgl_loadxcompsymbols(void *dllhnd)
+{
+       dlerror();  // Clear error state
+
+       lsym(XCompositeNameWindowPixmap);
        return 0;
 }
 
@@ -279,4 +304,5 @@ void __vgl_unloadsymbols(void)
 {
        if(gldllhnd) dlclose(gldllhnd);
        if(x11dllhnd) dlclose(x11dllhnd);
+       if(xcompdllhnd) dlclose( xcompdllhnd );
 }
diff --git a/rr/faker-sym.h b/rr/faker-sym.h
index 4fb75db..ed239f7 100644
--- a/rr/faker-sym.h
+++ b/rr/faker-sym.h
@@ -396,6 +396,11 @@ funcdef1(char *, XServerVendor, Display *, dpy, return);
 
 funcdef4(int, XWindowEvent, Display *, dpy, Window, win, long, event_mask,
        XEvent *, xe, return);
+funcdef2(int, XFreePixmap, Display*, dpy, Pixmap, pixmap, return);
+
+funcdef5( Pixmap, XCreatePixmap, Display*, dpy, Drawable, d, unsigned int, 
width, unsigned int, height, unsigned int, depth, return );
+
+funcdef2( Pixmap, XCompositeNameWindowPixmap, Display*, dpy, Window, window, 
return );
 
 // From dlfaker
 
diff --git a/rr/faker.cpp b/rr/faker.cpp
index cb519e3..054d3ee 100644
--- a/rr/faker.cpp
+++ b/rr/faker.cpp
@@ -36,6 +36,10 @@
 #include "vglconfigstart.h"
 #include <sys/types.h>
 #include <unistd.h>
+#include "shmpixmap.h"
+#include <iostream>
+#include </usr/include/GL/glxext.h>
+#include <X11/extensions/Xcomposite.h>
 
 #ifdef SUNOGL
 extern "C" {
@@ -103,6 +107,8 @@ static void __vgl_cleanup(void)
        if(glxdhash::isalloc()) glxdh.killhash();
        if(winhash::isalloc()) winh.killhash();
 
+       ShmPixmapStorage::killInstance();
+
        __vgl_unloadsymbols();
 }
 
@@ -390,6 +396,48 @@ Display *XOpenDisplay(_Xconst char* name)
        return dpy;
 }
 
+int    XFreePixmap     ( Display* dpy, Pixmap pixmap )
+{
+       int ret = _XFreePixmap( dpy, pixmap );
+
+       ShmPixmapStorage* s = ShmPixmapStorage::getInstance();
+       ShmPixmapInfo* info = s->getInfoForPixmap( pixmap );
+       if( info != NULL )
+               s->removeInfo( info );
+
+       return ret;
+}
+
+Pixmap XCreatePixmap   ( Display* dpy, Drawable d, unsigned int width, 
unsigned int height, unsigned int depth )
+{
+       Pixmap ret      = _XCreatePixmap( dpy, d, width, height, depth );
+
+       ShmPixmapStorage* s = ShmPixmapStorage::getInstance();
+        s->addInfo( dpy, None, width, height, depth, ret );
+
+       return ret;
+}
+
+Pixmap XCompositeNameWindowPixmap( Display* dpy, Window window )
+{
+       Pixmap ret      = _XCompositeNameWindowPixmap( dpy, window );
+
+       Window          root;
+       int             x;
+       int             y;
+       unsigned int    width;
+       unsigned int    height;
+       unsigned int    border;
+       unsigned int    depth;
+
+       XGetGeometry( dpy, window, &root, &x, &y, &width, &height, &border, 
&depth );
+
+       ShmPixmapStorage* s = ShmPixmapStorage::getInstance();
+        s->addInfo( dpy, window, width, height, depth, ret );
+
+       return ret;
+}
+
 Window XCreateWindow(Display *dpy, Window parent, int x, int y,
        unsigned int width, unsigned int height, unsigned int border_width,
        int depth, unsigned int c_class, Visual *visual, unsigned long 
valuemask,
@@ -489,6 +537,18 @@ static void _HandleEvent(Display *dpy, XEvent *xe)
        pbwin *pbw=NULL;
        if(xe && xe->type==ConfigureNotify)
        {
+               ShmPixmapStorage* s     = ShmPixmapStorage::getInstance();
+               ShmPixmapInfo* info     = s->getInfoForWindow( 
xe->xconfigure.window );
+               if( info != NULL )
+               {
+                       if( info->shmCreated )
+                               s->resize( info, xe->xconfigure.width, 
xe->xconfigure.height );
+                       else
+                       {
+                               info->width     = xe->xconfigure.width;
+                               info->height    = xe->xconfigure.height;
+                       }
+               }
                if(winh.findpb(dpy, xe->xconfigure.window, pbw))
                {
                                opentrace(_HandleEvent);  
prargi(xe->xconfigure.width);
@@ -593,6 +653,35 @@ Bool XCheckTypedWindowEvent(Display *dpy, Window win, int 
event_type, XEvent *xe
 
 int XConfigureWindow(Display *dpy, Window win, unsigned int value_mask, 
XWindowChanges *values)
 {
+       ShmPixmapStorage* s     = ShmPixmapStorage::getInstance();
+        ShmPixmapInfo* info     = s->getInfoForWindow( win );
+        if( info != NULL && values != NULL )
+        {
+               int width = 0;
+               int height = 0;
+               if( value_mask & CWWidth )
+                       width   = values->width;
+               if( value_mask & CWHeight )
+                       height  = values->height;
+               if( info->shmCreated )
+               {
+                       if( width != 0 || height != 0 )
+                       {
+                               if( width == 0 )
+                                       width   = info->width;
+                               if( height == 0 )
+                                       height  = info->height;
+                               s->resize( info, width, height );
+                               return _XConfigureWindow( dpy, win, value_mask, 
values );
+                       }
+               }
+               else
+               {
+                       info->width     = width;
+                       info->height    = height;
+               }
+        }
+
        int retval=0;
        TRY();
 
@@ -613,6 +702,22 @@ int XConfigureWindow(Display *dpy, Window win, unsigned 
int value_mask, XWindowC
 
 int XResizeWindow(Display *dpy, Window win, unsigned int width, unsigned int 
height)
 {
+       ShmPixmapStorage* s     = ShmPixmapStorage::getInstance();
+       ShmPixmapInfo* info     = s->getInfoForWindow( win );
+       if( info != NULL )
+       {
+               if( info->shmCreated )
+               {
+                       s->resize( info, width, height );
+                       return _XResizeWindow( dpy, win, width, height );
+               }
+               else
+               {
+                       info->width     = width;
+                       info->height    = height;
+               }
+       }
+
        int retval=0;
        TRY();
 
@@ -631,6 +736,23 @@ int XResizeWindow(Display *dpy, Window win, unsigned int 
width, unsigned int hei
 
 int XMoveResizeWindow(Display *dpy, Window win, int x, int y, unsigned int 
width, unsigned int height)
 {
+       ShmPixmapStorage* s     = ShmPixmapStorage::getInstance();
+        ShmPixmapInfo* info     = s->getInfoForWindow( win );
+        if( info != NULL )
+        {
+               if( info->shmCreated )
+               {
+                       s->resize( info, width, height );
+                       return _XMoveResizeWindow( dpy, win, x, y, width, 
height );
+               }
+               else
+               {
+                       info->width     = width;
+                       info->height    = height;
+               }
+        }
+        
+
        int retval=0;
        TRY();
 
@@ -668,6 +790,15 @@ int XCopyArea(Display *dpy, Drawable src, Drawable dst, GC 
gc, int src_x, int sr
                return retval;
        }
 
+       ShmPixmapStorage* s = ShmPixmapStorage::getInstance();
+        ShmPixmapInfo* info = s->getInfoForPixmap( dst );
+        if( info == NULL )
+                info = s->getInfoForGLXPixmap( dst );
+        if( info == NULL )
+                info = s->getInfoForWindow( dst );
+        if( info != NULL )
+                return _XCopyArea( dpy, src, dst, gc, src_x, src_y, w, h, 
dest_x, dest_y );
+
                opentrace(XCopyArea);  prargd(dpy);  prargx(src);  prargx(dst); 
 prargx(gc);
                prargi(src_x);  prargi(src_y);  prargi(w);  prargi(h);  
prargi(dest_x);
                prargi(dest_y);  prargx(read);  prargx(draw);  starttrace();
@@ -1335,6 +1466,17 @@ GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig 
config, Pixmap pm, const int
 
        CATCH();
 
+       ShmPixmapStorage* s = ShmPixmapStorage::getInstance();
+        ShmPixmapInfo* info = s->getInfoForPixmap( pm );
+        if( info != NULL )
+       {
+               int value = 0;
+               _glXGetFBConfigAttrib( dpy, config, 0x20D4, &value );
+               s->addShm( info );
+               info->glxPixmap = drawable;
+               info->invert    = ( value != 0 );
+       }
+
        return drawable;
 }
 
diff --git a/rr/glxvisual.cpp b/rr/glxvisual.cpp
index 599ac33..99ca8df 100644
--- a/rr/glxvisual.cpp
+++ b/rr/glxvisual.cpp
@@ -422,11 +422,18 @@ int __vglConfigDepth(GLXFBConfig c)
        render_type=__vglServerVisualAttrib(c, GLX_RENDER_TYPE);
        if(render_type==GLX_RGBA_BIT)
        {
-               r=__vglServerVisualAttrib(c, GLX_RED_SIZE);
+       /*      r=__vglServerVisualAttrib(c, GLX_RED_SIZE);
                g=__vglServerVisualAttrib(c, GLX_GREEN_SIZE);
                b=__vglServerVisualAttrib(c, GLX_BLUE_SIZE);
                depth=r+g+b;
                if(depth<8) depth=1;  // Monochrome
+       */
+
+               XVisualInfo* info = glXGetVisualFromFBConfig( _localdpy, c );
+
+               if( info )
+                       return info->depth;
+               depth = 1;
        }
        else
        {
diff --git a/rr/shmpixmap.h b/rr/shmpixmap.h
new file mode 100644
index 0000000..3aa8717
--- /dev/null
+++ b/rr/shmpixmap.h
@@ -0,0 +1,185 @@
+#pragma once
+
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#include <GL/gl.h>
+
+#include <list>
+#include <iostream>
+
+extern Display* _localdpy;
+
+struct ShmPixmapInfo
+{
+       friend class ShmPixmapStorage;
+       
+       Display*        display;
+       XShmSegmentInfo shmInfo;
+       Pixmap          originalPixmap;
+       GC              gc;
+       Pixmap          sharedPixmap;
+       GLXPixmap       glxPixmap;
+       int             width;
+       int             height;
+       int             depth;
+       Window          win;
+       bool            shmCreated;
+       double          matrix[ 16 ];
+       bool            invert;
+};
+
+class ShmPixmapStorage
+{
+private:
+       typedef std::list< ShmPixmapInfo* >             Storage;
+       typedef std::list< ShmPixmapInfo* >::iterator   Iterator;
+  
+private:
+       ShmPixmapStorage()
+       {
+               instance_       = this;
+       }
+       ~ShmPixmapStorage()
+       {
+               instance_       = NULL;
+       }
+       
+public:
+       ShmPixmapInfo*  getInfoForPixmap        ( Pixmap value )
+       {
+               for( Iterator i = storage_.begin(); i != storage_.end(); ++ i )
+                       if( ( *i )->originalPixmap == value )
+                               return ( *i );
+                       
+               return NULL;
+       }
+       ShmPixmapInfo*  getInfoForGLXPixmap     ( GLXPixmap value )
+       {
+               for( Iterator i = storage_.begin(); i != storage_.end(); ++ i )
+                       if( ( *i )->glxPixmap == value )
+                               return ( *i );
+                       
+               return NULL;
+       }
+       ShmPixmapInfo*  getInfoForWindow        ( Window value )
+       {
+               for( Iterator i = storage_.begin(); i != storage_.end(); ++ i )
+                        if( ( *i )->win == value )
+                                return ( *i );
+
+                return NULL;
+       }
+       
+       void    addInfo ( Display* dpy, Window window, int width, int height, 
int depth, Pixmap value )
+       {
+               ShmPixmapInfo* info     = new ShmPixmapInfo;
+               info->display           = dpy;
+               info->win               = window;
+               info->width             = width;
+               info->height            = height;
+               info->depth             = depth;
+               info->originalPixmap    = value;
+               info->shmCreated        = false;
+               info->invert            = false;
+               storage_.push_back( info );
+       }
+       
+       void    addShm  ( ShmPixmapInfo* value )
+       {
+               XGCValues gcv;
+               unsigned long size      = value->width * value->height * 
value->depth;
+               value->shmInfo.shmid    = shmget( IPC_PRIVATE, size, IPC_CREAT 
| 0777 );
+               value->shmInfo.shmaddr  = ( char* )( shmat( 
value->shmInfo.shmid, 0, 0 ) );
+               value->shmInfo.readOnly = False;
+               XShmAttach( value->display, &value->shmInfo );
+               value->gc               = XCreateGC( value->display, 
value->originalPixmap, 0, &gcv );
+               value->sharedPixmap     = XShmCreatePixmap
+               (
+                       value->display,
+                       value->originalPixmap,
+                       value->shmInfo.shmaddr,
+                       &value->shmInfo,
+                       value->width,
+                       value->height,
+                       value->depth
+               );
+               XSync( value->display, False );
+               value->shmCreated       = true;
+       }
+       
+       void    resize          ( ShmPixmapInfo* value, unsigned int width, 
unsigned int height )
+       {
+               value->width    = width;
+               value->height   = height;
+               
+               if( value->shmCreated )
+               {
+                       XShmDetach( value->display, &value->shmInfo );
+                       _XFreePixmap( value->display, value->sharedPixmap );
+                       shmdt( value->shmInfo.shmaddr );
+                       shmctl( value->shmInfo.shmid, IPC_RMID, 0 );
+               }
+               
+               unsigned long size      = value->width * value->height * 
value->depth;
+               value->shmInfo.shmid    = shmget( IPC_PRIVATE, size, IPC_CREAT 
| 0777 );
+               value->shmInfo.shmaddr  = ( char* )( shmat( 
value->shmInfo.shmid, 0, 0 ) );
+               value->shmInfo.readOnly = False;
+               XShmAttach( value->display, &value->shmInfo );
+               value->sharedPixmap     = XShmCreatePixmap
+               (
+                       value->display,
+                       value->originalPixmap,
+                       value->shmInfo.shmaddr,
+                       &value->shmInfo,
+                       value->width,
+                       value->height,
+                       value->depth
+               );
+               XSync( value->display, False );
+               value->shmCreated       = true;
+       }
+       
+       void    removeInfo      ( ShmPixmapInfo* value )
+       {
+               Iterator i;
+               for( i = storage_.begin(); i != storage_.end(); ++ i )
+                       if( ( *i ) == value )
+                               break;
+               
+               if( i == storage_.end() )
+                       return;
+               
+               storage_.erase( i );
+               
+               if( value->shmCreated )
+               {
+                       XShmDetach( value->display, &value->shmInfo );
+                       _XFreePixmap( value->display, value->sharedPixmap );
+                       shmdt( value->shmInfo.shmaddr );
+                       shmctl( value->shmInfo.shmid, IPC_RMID, 0 );
+               }
+               
+               delete value;
+       }
+       
+       static ShmPixmapStorage*        getInstance     ()
+       {
+               if( instance_ == NULL )
+                       instance_ = new ShmPixmapStorage();
+               return instance_;
+       }
+       static void                     killInstance    ()
+       {
+               if( instance_ != NULL )
+               {
+                       delete instance_;
+                       instance_       = NULL;
+               }
+       }
+
+private:
+       static ShmPixmapStorage*        instance_;
+       Storage                         storage_;
+};
+
+ShmPixmapStorage*      ShmPixmapStorage::instance_     = NULL;
------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
VirtualGL-Users mailing list
VirtualGL-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/virtualgl-users

Reply via email to