Skip to content

Commit

Permalink
#640 port the gl check code to python3 / gobject introspection
Browse files Browse the repository at this point in the history
git-svn-id: https://xpra.org/svn/Xpra/trunk@7587 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Sep 12, 2014
1 parent cffd4af commit 501f8c4
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 64 deletions.
5 changes: 1 addition & 4 deletions src/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@ def check_pyopencl_AMD():
if clipboard_ENABLED and not server_ENABLED and not gtk2_ENABLED and not gtk3_ENABLED:
print("Warning: clipboard can only be used with the server or one of the gtk clients!")
clipboard_ENABLED = False
if opengl_ENABLED and not gtk2_ENABLED:
print("Warning: opengl can only be used with the gtk2 clients")
opengl_ENABLED = False
if shadow_ENABLED and not server_ENABLED:
print("Warning: shadow requires server to be enabled!")
shadow_ENABLED = False
Expand Down Expand Up @@ -1619,7 +1616,7 @@ def cython_add(*args, **kwargs):
toggle_packages(client_ENABLED and qt4_ENABLED, "xpra.client.qt4", "PyQt4")
toggle_packages(client_ENABLED and (gtk2_ENABLED or gtk3_ENABLED), "xpra.client.gtk_base")
toggle_packages(sound_ENABLED, "xpra.sound")
toggle_packages(client_ENABLED and gtk2_ENABLED and opengl_ENABLED, "xpra.client.gl")
toggle_packages(client_ENABLED and opengl_ENABLED, "xpra.client.gl")

toggle_packages(clipboard_ENABLED, "xpra.clipboard")
if clipboard_ENABLED:
Expand Down
132 changes: 74 additions & 58 deletions src/xpra/client/gl/gl_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,26 @@
DEFAULT_DOUBLE_BUFFERED = 1
DOUBLE_BUFFERED = os.environ.get("XPRA_OPENGL_DOUBLE_BUFFERED", str(DEFAULT_DOUBLE_BUFFERED))=="1"


def get_visual_name(visual):
import gtk.gdk
from xpra.gtk_common.gtk_util import STATIC_GRAY, GRAYSCALE, STATIC_COLOR, PSEUDO_COLOR, TRUE_COLOR, DIRECT_COLOR
if not visual:
return ""
return {
gtk.gdk.VISUAL_STATIC_GRAY : "STATIC_GRAY",
gtk.gdk.VISUAL_GRAYSCALE : "GRAYSCALE",
gtk.gdk.VISUAL_STATIC_COLOR : "STATIC_COLOR",
gtk.gdk.VISUAL_PSEUDO_COLOR : "PSEUDO_COLOR",
gtk.gdk.VISUAL_TRUE_COLOR : "TRUE_COLOR",
gtk.gdk.VISUAL_DIRECT_COLOR : "DIRECT_COLOR"}.get(visual.type, "unknown")
STATIC_GRAY : "STATIC_GRAY",
GRAYSCALE : "GRAYSCALE",
STATIC_COLOR : "STATIC_COLOR",
PSEUDO_COLOR : "PSEUDO_COLOR",
TRUE_COLOR : "TRUE_COLOR",
DIRECT_COLOR : "DIRECT_COLOR"}.get(visual.type, "unknown")

def get_visual_byte_order(visual):
import gtk.gdk
from xpra.gtk_common.gtk_util import LSB_FIRST, MSB_FIRST
if not visual:
return ""
return {
gtk.gdk.LSB_FIRST : "LSB",
gtk.gdk.MSB_FIRST : "MSB"}.get(visual.byte_order, "unknown")
LSB_FIRST : "LSB",
MSB_FIRST : "MSB"}.get(visual.byte_order, "unknown")

def visual_to_str(visual):
if not visual:
Expand All @@ -62,30 +63,29 @@ def visual_to_str(visual):
return str(d)

def get_DISPLAY_MODE(want_alpha=GL_ALPHA_SUPPORTED):
import gtk.gdkgl
#gtk.gdkgl.MODE_DEPTH
mode = 0
from xpra.client.gl.gtk_compat import MODE_RGBA, MODE_ALPHA, MODE_RGB, MODE_DOUBLE, MODE_SINGLE
#MODE_DEPTH
if want_alpha:
mode = mode | gtk.gdkgl.MODE_RGBA | gtk.gdkgl.MODE_ALPHA
mode = MODE_RGBA | MODE_ALPHA
else:
mode = mode | gtk.gdkgl.MODE_RGB
mode = MODE_RGB
if DOUBLE_BUFFERED:
mode = mode | gtk.gdkgl.MODE_DOUBLE
mode = mode | MODE_DOUBLE
else:
mode = mode | gtk.gdkgl.MODE_SINGLE
mode = mode | MODE_SINGLE
return mode

def get_MODE_names(mode):
import gtk.gdkgl
friendly_mode_names = {gtk.gdkgl.MODE_RGB : "RGB",
gtk.gdkgl.MODE_RGBA : "RGBA",
gtk.gdkgl.MODE_ALPHA : "ALPHA",
gtk.gdkgl.MODE_DEPTH : "DEPTH",
gtk.gdkgl.MODE_DOUBLE : "DOUBLE",
gtk.gdkgl.MODE_SINGLE : "SINGLE"}
from xpra.client.gl.gtk_compat import MODE_RGB, MODE_RGBA, MODE_ALPHA, MODE_DEPTH, MODE_DOUBLE, MODE_SINGLE
friendly_mode_names = {MODE_RGB : "RGB",
MODE_RGBA : "RGBA",
MODE_ALPHA : "ALPHA",
MODE_DEPTH : "DEPTH",
MODE_DOUBLE : "DOUBLE",
MODE_SINGLE : "SINGLE"}
friendly_modes = [v for k,v in friendly_mode_names.items() if k>0 and (k&mode)==k]
#special case for single (value is zero!)
if not (mode&gtk.gdkgl.MODE_DOUBLE==gtk.gdkgl.MODE_DOUBLE):
if not (mode&MODE_DOUBLE==MODE_DOUBLE):
friendly_modes.append("SINGLE")
return friendly_modes

Expand Down Expand Up @@ -113,10 +113,21 @@ def check_functions(*functions):
else:
log("All the required OpenGL functions are available: %s " % (", ".join(available)))


#sanity checks: OpenGL version and fragment program support:
def check_GL_support(gldrawable, glcontext, min_texture_size=0, force_enable=False):
if not gldrawable.gl_begin(glcontext):
raise ImportError("gl_begin failed on %s" % gldrawable)
def check_GL_support(widget, min_texture_size=0, force_enable=False):
from xpra.client.gl.gtk_compat import begin_gl, end_gl
try:
if not begin_gl(widget):
raise ImportError("failed to get an opengl context")
except Exception as e:
raise ImportError("error getting an opengl context: %s" % e)
try:
return do_check_GL_support(min_texture_size, force_enable)
finally:
end_gl(widget)

def do_check_GL_support(min_texture_size, force_enable):
props = {}
try:
#log redirection:
Expand Down Expand Up @@ -152,8 +163,9 @@ def redirect_log(logger_name):
else:
log("found valid OpenGL version: %s.%s", gl_major, gl_minor)
try:
extensions = glGetString(GL_EXTENSIONS).split(" ")
extensions = glGetString(GL_EXTENSIONS).decode().split(" ")
except:
log("error querying extensions", exc_info=True)
extensions = []
gl_check_error("OpenGL could not find the list of GL extensions - does the graphics driver support OpenGL?")
log("OpenGL extensions found: %s", ", ".join(extensions))
Expand All @@ -171,6 +183,7 @@ def redirect_log(logger_name):
("shading language version", GL_SHADING_LANGUAGE_VERSION, False)):
try:
v = glGetString(s)
v = v.decode()
log("%s: %s", d, v)
except:
if fatal:
Expand All @@ -183,6 +196,7 @@ def redirect_log(logger_name):
from OpenGL.GLU import gluGetString, GLU_VERSION, GLU_EXTENSIONS
for d,s in {"GLU version": GLU_VERSION, "GLU extensions":GLU_EXTENSIONS}.items():
v = gluGetString(s)
v = v.decode()
log("%s: %s", d, v)
props[d] = v

Expand Down Expand Up @@ -344,7 +358,7 @@ def restore_logger(logger):
restore_logger(alogger)
restore_logger(arlogger)
restore_logger(clogger)
gldrawable.gl_end()


def check_support(min_texture_size=0, force_enable=False, check_colormap=False):
#platform checks:
Expand All @@ -354,29 +368,26 @@ def check_support(min_texture_size=0, force_enable=False, check_colormap=False):
gl_check_error(warning)

props = {}
import gtk.gdk
import gtk.gdkgl, gtk.gtkgl
assert gtk.gdkgl is not None and gtk.gtkgl is not None
log("pygdkglext version=%s", gtk.gdkgl.pygdkglext_version)
props["pygdkglext_version"] = gtk.gdkgl.pygdkglext_version
log("gtkglext_version=%s", gtk.gdkgl.gdkglext_version)
props["gdkglext_version"] = gtk.gdkgl.gdkglext_version
log("pygdkglext OpenGL version=%s", gtk.gdkgl.query_version())
props["gdkgl_version"] = gtk.gdkgl.query_version()
#this will import gtk.gtkgl / gdkgl or gi.repository.GtkGLExt / GdkGLExt:
from xpra.client.gl.gtk_compat import get_info, gtkgl, gdkgl, Config_new_by_mode, MODE_DOUBLE, RGBA_TYPE
props.update(get_info())
display_mode = get_DISPLAY_MODE()
try:
glconfig = gtk.gdkgl.Config(mode=display_mode)
except gtk.gdkgl.NoMatches as e:
log("no match: %s, toggling double-buffering", e)
display_mode &= ~gtk.gdkgl.MODE_DOUBLE
glconfig = gtk.gdkgl.Config(mode=display_mode)
glconfig = Config_new_by_mode(display_mode)
if glconfig is None:
log("trying to toggle double-buffering")
display_mode &= ~MODE_DOUBLE
glconfig = Config_new_by_mode(display_mode)
if not glconfig:
raise Exception("cannot setup an OpenGL context")
props["display_mode"] = get_MODE_names(display_mode)
props["glconfig"] = glconfig
props["has_alpha"] = glconfig.has_alpha()
props["rgba"] = glconfig.is_rgba()
log("GL props=%s", props)
assert gtk.gdkgl.query_extension()
glcontext, gldrawable, glext, w = None, None, None, None
from xpra.gtk_common.gtk_util import import_gtk, gdk_window_process_all_updates
gtk = import_gtk()
assert gdkgl.query_extension()
glext, w = None, None
try:
#ugly code for win32 and others (virtualbox broken GL drivers)
#for getting a GL drawable and context: we must use a window...
Expand All @@ -389,33 +400,36 @@ def check_support(min_texture_size=0, force_enable=False, check_colormap=False):
w = gtk.Window()
w.set_decorated(False)
vbox = gtk.VBox()
glarea = gtk.gtkgl.DrawingArea(glconfig)
glarea = gtk.DrawingArea()
# Set OpenGL-capability to the widget
gtkgl.widget_set_gl_capability(glarea, glconfig, None, True, RGBA_TYPE)
glarea.set_size_request(32, 32)
vbox.add(glarea)
vbox.show_all()
w.add(vbox)
#we don't need to actually show the window!
#w.show_all()
glarea.realize()
gtk.gdk.window_process_all_updates()
gldrawable = glarea.get_gl_drawable()
glcontext = glarea.get_gl_context()
gdk_window_process_all_updates()

gl_props = check_GL_support(gldrawable, glcontext, min_texture_size, force_enable)
gl_props = check_GL_support(glarea, min_texture_size, force_enable)

if check_colormap:
rgb_visual = w.get_screen().get_rgb_visual()
rgba_visual = w.get_screen().get_rgba_visual()
gl_props["rgb_visual"] = visual_to_str(rgb_visual)
gl_props["rgba_visual"] = visual_to_str(rgba_visual)
s = w.get_screen()
for x in ("rgb_visual", "rgba_visual", "system_visual"):
try:
visual = getattr(s, "get_%s" % x)()
gl_props[x] = visual_to_str(visual)
except:
pass
#i = 0
#for v in w.get_screen().list_visuals():
#for v in s.list_visuals():
# gl_props["visual[%s]" % i] = visual_to_str(v)
# i += 1
finally:
if w:
w.destroy()
del glcontext, gldrawable, glext, glconfig
del glext, glconfig
props.update(gl_props)
return props

Expand All @@ -428,6 +442,8 @@ def main():
verbose = "-v" in sys.argv or "--verbose" in sys.argv
if verbose:
log.enable_debug()
from xpra.client.gl.gtk_compat import log as clog
clog.enable_debug()
#replace ImportError with a log message:
global gl_check_error
errors = []
Expand Down
77 changes: 77 additions & 0 deletions src/xpra/client/gl/gtk_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# coding=utf8
# This file is part of Xpra.
# Copyright (C) 2011-2014 Antoine Martin <antoine@devloop.org.uk>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.


from xpra.gtk_common.gobject_compat import is_gtk3

from xpra.log import Logger
log = Logger("gtk", "util", "opengl")


if is_gtk3():
from gi.repository import GdkGLExt, GtkGLExt #@UnresolvedImport
MODE_DEPTH = GdkGLExt.ConfigMode.DEPTH
MODE_RGBA = GdkGLExt.ConfigMode.RGBA
MODE_ALPHA = GdkGLExt.ConfigMode.ALPHA
MODE_RGB = GdkGLExt.ConfigMode.RGB
MODE_DOUBLE = GdkGLExt.ConfigMode.DOUBLE
MODE_SINGLE = GdkGLExt.ConfigMode.SINGLE

RGBA_TYPE = GdkGLExt.RenderType.RGBA_TYPE

def get_info():
return {"gdkgl_version" : GdkGLExt._version,
"gtkgl_version" : GtkGLExt._version,
}
gdkgl = GdkGLExt
gtkgl = GtkGLExt
def Config_new_by_mode(display_mode):
try:
return GdkGLExt.Config.new_by_mode(display_mode)
except Exception as e:
log("no configuration for mode: %s", e)
return None

def begin_gl(widget):
return GtkGLExt.widget_begin_gl(widget)

def end_gl(widget):
GtkGLExt.widget_end_gl(widget, False)

else:
from gtk import gdkgl, gtkgl
MODE_DEPTH = gdkgl.MODE_DEPTH
MODE_RGBA = gdkgl.MODE_RGBA
MODE_ALPHA = gdkgl.MODE_ALPHA
MODE_RGB = gdkgl.MODE_RGB
MODE_DOUBLE = gdkgl.MODE_DOUBLE
MODE_SINGLE = gdkgl.MODE_SINGLE

RGBA_TYPE = gdkgl.RGBA_TYPE

def Config_new_by_mode(display_mode):
try:
return gdkgl.Config(mode=display_mode)
except gdkgl.NoMatches as e:
log("no match: %s", e)
return None

def get_info():
return {
"pygdkglext_version" : gdkgl.pygdkglext_version,
"gtkglext_version" : gtkgl.gtkglext_version,
"gdkglext_version" : gdkgl.gdkglext_version,
"gdkgl_version" : gdkgl.query_version()
}

def begin_gl(widget):
gldrawable = gtkgl.widget_get_gl_drawable(widget)
glcontext = gtkgl.widget_get_gl_context(widget)
return gldrawable.gl_begin(glcontext)

def end_gl(widget):
gldrawable = gtkgl.widget_get_gl_drawable(widget)
gldrawable.gl_end()
3 changes: 1 addition & 2 deletions src/xpra/client/gtk2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,7 @@ def init_opengl(self, enable_opengl):
self.opengl_props["info"] = ""
try:
__import__("xpra.client.gl", {}, {}, [])
__import__("gtk.gdkgl", {}, {}, [])
__import__("gtk.gtkgl", {}, {}, [])
__import__("xpra.client.gl.gtk_compat", {}, {}, [])
gl_check = __import__("xpra.client.gl.gl_check", {}, {}, ["check_support"])
w, h = self.get_root_size()
min_texture_size = max(w, h)
Expand Down
20 changes: 20 additions & 0 deletions src/xpra/gtk_common/gtk_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ def pixbuf_new_from_data(*args):
JUSTIFY_LEFT = gtk.Justification.LEFT
JUSTIFY_RIGHT = gtk.Justification.RIGHT

LSB_FIRST = gdk.ByteOrder.LSB_FIRST
MSB_FIRST = gdk.ByteOrder.MSB_FIRST
STATIC_GRAY = gdk.VisualType.STATIC_GRAY
GRAYSCALE = gdk.VisualType.GRAYSCALE
STATIC_COLOR = gdk.VisualType.STATIC_COLOR
PSEUDO_COLOR = gdk.VisualType.PSEUDO_COLOR
TRUE_COLOR = gdk.VisualType.TRUE_COLOR
DIRECT_COLOR = gdk.VisualType.DIRECT_COLOR

SHIFT_MASK = gdk.ModifierType.SHIFT_MASK
LOCK_MASK = gdk.ModifierType.LOCK_MASK
META_MASK = gdk.ModifierType.META_MASK
Expand Down Expand Up @@ -135,6 +144,7 @@ class OptionMenu(gtk.MenuButton):
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

gdk_window_process_all_updates = gdk.Window.process_all_updates
def gtk_main():
gdk.threads_init()
try:
Expand Down Expand Up @@ -181,6 +191,15 @@ def cairo_set_source_pixbuf(cr, pixbuf, x, y):
JUSTIFY_LEFT = gtk.JUSTIFY_LEFT
JUSTIFY_RIGHT = gtk.JUSTIFY_RIGHT

LSB_FIRST = gtk.gdk.LSB_FIRST
MSB_FIRST = gtk.gdk.MSB_FIRST
STATIC_GRAY = gtk.gdk.VISUAL_STATIC_GRAY
GRAYSCALE = gtk.gdk.VISUAL_GRAYSCALE
STATIC_COLOR = gtk.gdk.VISUAL_STATIC_COLOR
PSEUDO_COLOR = gtk.gdk.VISUAL_PSEUDO_COLOR
TRUE_COLOR = gtk.gdk.VISUAL_TRUE_COLOR
DIRECT_COLOR = gtk.gdk.VISUAL_DIRECT_COLOR

SHIFT_MASK = gtk.gdk.SHIFT_MASK
LOCK_MASK = gtk.gdk.LOCK_MASK
META_MASK = gdk.META_MASK
Expand All @@ -196,6 +215,7 @@ def cairo_set_source_pixbuf(cr, pixbuf, x, y):
def GetClipboard(selection):
return gtk.Clipboard(selection=selection)

gdk_window_process_all_updates = gdk.window_process_all_updates
def gtk_main():
if gtk.main_level()==0:
gdk.threads_init()
Expand Down

0 comments on commit 501f8c4

Please sign in to comment.