xpra icon
Bug tracker and wiki

Ticket #1569: gtkglx-v2.patch

File gtkglx-v2.patch, 11.8 KB (added by Antoine Martin, 3 years ago)

working patch

  • xpra/client/gl/gl_window_backing_base.py

     
    1717OPENGL_DEBUG = envbool("XPRA_OPENGL_DEBUG", False)
    1818SCROLL_ENCODING = envbool("XPRA_SCROLL_ENCODING", True)
    1919PAINT_FLUSH = envbool("XPRA_PAINT_FLUSH", True)
    20 HIGH_BIT_DEPTH = envbool("XPRA_HIGH_BIT_DEPTH", True)
    21 FORCE_HIGH_BIT_DEPTH = envbool("XPRA_FORCE_HIGH_BIT_DEPTH", False)
    2220
    2321CURSOR_IDLE_TIMEOUT = envint("XPRA_CURSOR_IDLE_TIMEOUT", 6)
    2422TEXTURE_CURSOR = envbool("XPRA_OPENGL_TEXTURE_CURSOR", False)
  • xpra/client/gl/gtk2/gl_client_window.py

     
    99
    1010import gobject
    1111
     12from xpra.util import envbool
    1213from collections import namedtuple
    1314from xpra.client.gtk2.gtk2_window_base import GTK2WindowBase
    14 from xpra.client.gl.gtk2.gl_window_backing import GLPixmapBacking
    1515
     16backing_class = None
     17if envbool("XPRA_OPENGL_NATIVE", True):
     18    try:
     19        from xpra.client.gl.gtk_base.gl_drawing_area import GLDrawingArea
     20        backing_class = GLDrawingArea
     21    except ImportError as e:
     22        log("cannot use native GLDrawingArea glue: %s", e)
     23if not backing_class:
     24    from xpra.client.gl.gtk2.gl_window_backing import GLPixmapBacking
     25    backing_class = GLPixmapBacking
     26log("GL backing class: %s", backing_class)
    1627
    1728Rectangle = namedtuple("Rectangle", "x,y,width,height")
    1829DrawEvent = namedtuple("DrawEvent", "area")
     
    2435
    2536
    2637    def get_backing_class(self):
    27         return GLPixmapBacking
     38        return backing_class
    2839
    2940
    3041    def __str__(self):
  • xpra/client/gl/gtk3/gl_client_window.py

     
    77from xpra.log import Logger
    88log = Logger("opengl", "window")
    99
     10from xpra.util import envbool
    1011from xpra.client.gtk3.client_window import ClientWindow
    11 from xpra.client.gl.gtk3.gl_window_backing import GLPixmapBacking
    1212
     13backing_class = None
     14if envbool("XPRA_OPENGL_NATIVE", True):
     15    try:
     16        from xpra.client.gl.gtk_base.gl_drawing_area import GLDrawingArea
     17        backing_class = GLDrawingArea
     18    except ImportError as e:
     19        log("cannot use native GLDrawingArea glue: %s", e)
     20if not backing_class:
     21    from xpra.client.gl.gtk3.gl_window_backing import GLPixmapBacking
     22    backing_class = GLPixmapBacking
     23log("GL backing class: %s", backing_class)
    1324
     25
    1426class GLClientWindow(ClientWindow):
    1527
    1628    def get_backing_class(self):
    17         return GLPixmapBacking
     29        return GLDrawingArea
    1830
    1931
    2032    def __str__(self):
  • xpra/client/gl/gtk_base/gl_drawing_area.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2017 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6import sys
     7from xpra.log import Logger
     8log = Logger("opengl", "paint")
     9
     10from xpra.platform.gl_context import GLContext
     11if not GLContext:
     12    raise ImportError("no OpenGL context implementation for %s" % sys.platform)
     13
     14from xpra.client.gl.gl_window_backing_base import GLWindowBackingBase
     15from xpra.gtk_common.gobject_compat import import_glib, import_gtk, is_gtk3
     16from xpra.gtk_common.gtk_util import POINTER_MOTION_MASK, POINTER_MOTION_HINT_MASK
     17glib = import_glib()
     18gtk = import_gtk()
     19
     20
     21class GLDrawingArea(GLWindowBackingBase):
     22
     23    def __repr__(self):
     24        return "gtk%i.GLDrawingArea(%s, %s, %s)" % (2+is_gtk3(), self.wid, self.size, self.pixel_format)
     25
     26    def idle_add(self, *args, **kwargs):
     27        glib.idle_add(*args, **kwargs)
     28
     29    def init_gl_config(self, _window_alpha):
     30        self.context = GLContext()
     31        self.window_context = None
     32
     33    def is_double_buffered(self):
     34        return self.context.is_double_buffered()
     35
     36    def init_backing(self):
     37        da = gtk.DrawingArea()
     38        #da.connect('configure_event', self.on_configure_event)
     39        #da.connect('draw', self.on_draw)
     40        da.set_double_buffered(True)
     41        da.set_size_request(*self.size)
     42        da.set_events(da.get_events() | POINTER_MOTION_MASK | POINTER_MOTION_HINT_MASK)
     43        da.show()
     44        self._backing = da
     45
     46    def get_bit_depth(self, pixel_depth):
     47        return self.context.get_bit_depth() or pixel_depth or 24
     48
     49    def gl_context(self):
     50        gdk_window = self._backing.get_window()
     51        assert gdk_window
     52        self.window_context = self.context.get_paint_context(gdk_window)
     53        return self.window_context
     54
     55    def do_gl_show(self, _rect_count):
     56        if self.is_double_buffered():
     57            # Show the backbuffer on screen
     58            log("%s.gl_show() swapping buffers now", self)
     59            self.window_context.swap_buffers()
     60        else:
     61            #glFlush was enough
     62            pass
     63
     64    def close(self):
     65        GLWindowBackingBase.close(self)
     66        c = self.context
     67        if c:
     68            self.context = None
     69            c.destroy()
     70
     71    def cairo_draw(self, _context):
     72        w, h = self.size
     73        with self.gl_context():
     74            self.gl_init()
     75            self.present_fbo(0, 0, w, h)
  • xpra/client/gl/gtk_base/gtkgl_check.py

     
    77
    88import sys
    99
    10 from xpra.client.gl.gl_check import check_PyOpenGL_support, GL_ALPHA_SUPPORTED, gl_check_error
     10from xpra.client.gl.gl_check import check_PyOpenGL_support, GL_ALPHA_SUPPORTED, CAN_DOUBLE_BUFFER, DOUBLE_BUFFERED, gl_check_error
    1111
    1212from xpra.util import envbool
    13 from xpra.os_util import WIN32, PYTHON3
    1413from xpra.log import Logger
    1514log = Logger("opengl")
    1615
    1716
    18 #not working with gtk3 yet?
    19 CAN_DOUBLE_BUFFER = not PYTHON3
    20 #needed on win32?:
    21 DEFAULT_DOUBLE_BUFFERED = WIN32 or CAN_DOUBLE_BUFFER
    22 DOUBLE_BUFFERED = envbool("XPRA_OPENGL_DOUBLE_BUFFERED", DEFAULT_DOUBLE_BUFFERED)
    2317TEST_GTKGL_RENDERING = envbool("XPRA_TEST_GTKGL_RENDERING", 1)
    2418
    2519from xpra.gtk_common.gtk_util import STATIC_GRAY, GRAYSCALE, STATIC_COLOR, PSEUDO_COLOR, TRUE_COLOR, DIRECT_COLOR
  • xpra/client/gtk_base/gtk_client_base.py

     
    734734        try:
    735735            opengllog("init_opengl: going to import xpra.client.gl")
    736736            __import__("xpra.client.gl", {}, {}, [])
    737             __import__("xpra.client.gl.gtk_base.gtk_compat", {}, {}, [])
    738             gl_check = __import__("xpra.client.gl.gtk_base.gtkgl_check", {}, {}, ["check_support"])
    739             opengllog("init_opengl: gl_check=%s", gl_check)
    740             self.opengl_props = gl_check.check_support(force_enable=(enable_opengl is True))
     737            if False:
     738                __import__("xpra.client.gl.gtk_base.gtk_compat", {}, {}, [])
     739                gl_check = __import__("xpra.client.gl.gtk_base.gtkgl_check", {}, {}, ["check_support"])
     740                opengllog("init_opengl: gl_check=%s", gl_check)
     741                self.opengl_props = gl_check.check_support(force_enable=(enable_opengl is True))
     742            else:
     743                self.opengl_props = {}
    741744            opengllog("init_opengl: found props %s", self.opengl_props)
    742745            GTK_GL_CLIENT_WINDOW_MODULE = "xpra.client.gl.gtk%s.gl_client_window" % (2+int(is_gtk3()))
    743746            opengllog("init_opengl: trying to load GL client window module '%s'", GTK_GL_CLIENT_WINDOW_MODULE)
  • xpra/platform/gl_context.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2017 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6GLContext = None
     7
     8from xpra.platform import platform_import
     9platform_import(globals(), "gl_context", False, "GLContext")
  • xpra/platform/xposix/gl_context.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2017 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6from xpra.log import Logger
     7log = Logger("opengl")
     8
     9from xpra.util import envbool
     10from xpra.x11.bindings.display_source import get_display_ptr        #@UnresolvedImport
     11from xpra.gtk_common.gobject_compat import get_xid
     12from xpra.gtk_common.gtk_util import display_get_default
     13from ctypes import c_int, byref
     14from OpenGL import GLX
     15
     16
     17DOUBLE_BUFFERED = envbool("XPRA_OPENGL_DOUBLE_BUFFERED", True)
     18
     19
     20def c_attrs(props):
     21    attrs = []
     22    for k,v in props.items():
     23        attrs += [k, v]
     24    attrs += [0, 0]
     25    return (c_int * len(attrs))(*attrs)
     26
     27def get_xdisplay():
     28    ptr = get_display_ptr()
     29    from OpenGL.raw.GLX._types import struct__XDisplay
     30    from ctypes import cast, POINTER
     31    return cast(ptr, POINTER(struct__XDisplay))
     32   
     33
     34class GLXWindowContext(object):
     35
     36    def __init__(self, glx_context, xid):
     37        self.context = glx_context
     38        self.xid = xid
     39        self.xdisplay = get_xdisplay()
     40        self.valid = False
     41
     42    def __enter__(self):
     43        if not GLX.glXMakeCurrent(self.xdisplay, self.xid, self.context):
     44            raise Exception("glXMakeCurrent failed")
     45        self.valid = True
     46
     47    def __exit__(self, *_args):
     48        self.valid = False
     49
     50    def swap_buffers(self):
     51        assert self.valid
     52        GLX.glXSwapBuffers(self.xdisplay, self.xid)
     53
     54    def __repr__(self):
     55        return "gtk3.GLXWindowContext(%#x)" % self.xid
     56
     57
     58class GLXContext(object):
     59
     60    def __init__(self):
     61        display = display_get_default()
     62        screen = display.get_default_screen()
     63        attrs = c_attrs({
     64            GLX.GLX_RGBA            : True,
     65            GLX.GLX_RED_SIZE        : 8,
     66            GLX.GLX_GREEN_SIZE      : 8,
     67            GLX.GLX_BLUE_SIZE       : 8,
     68            GLX.GLX_DOUBLEBUFFER    : int(DOUBLE_BUFFERED),
     69            })
     70        self.xdisplay = get_xdisplay()
     71        xvinfo = GLX.glXChooseVisual(self.xdisplay, screen.get_number(), attrs)
     72        def getconfig(attrib):
     73            value = c_int()
     74            r = GLX.glXGetConfig(self.xdisplay, xvinfo, attrib, byref(value))
     75            assert r==0, "glXGetConfig returned %i" % r
     76            return value.value
     77        self.bit_depth = getconfig(GLX.GLX_RED_SIZE) + getconfig(GLX.GLX_GREEN_SIZE) + getconfig(GLX.GLX_BLUE_SIZE)
     78        self.context = GLX.glXCreateContext(self.xdisplay, xvinfo, None, True)
     79
     80    def get_bit_depth(self):
     81        return self.bit_depth
     82
     83    def is_double_buffered(self):
     84        return DOUBLE_BUFFERED
     85
     86    def get_paint_context(self, gdk_window):
     87        assert self.context and gdk_window
     88        return GLXWindowContext(self.context, get_xid(gdk_window))
     89
     90    def destroy(self):
     91        c = self.context
     92        if c:
     93            self.context = None
     94            GLX.glXDestroyContext(self.xdisplay, c)
     95
     96    def __repr__(self):
     97        return "GLXContext"
     98
     99GLContext = GLXContext