示例#1
0
 def init_gl_config(self, window_alpha):
     #setup gl config:
     alpha = GL_ALPHA_SUPPORTED and window_alpha
     display_mode = get_DISPLAY_MODE(want_alpha=alpha)
     self.glconfig = Config_new_by_mode(display_mode)
     if self.glconfig is None and CAN_DOUBLE_BUFFER:
         log("trying to toggle double-buffering")
         display_mode &= ~MODE_DOUBLE
         self.glconfig = Config_new_by_mode(display_mode)
     if not self.glconfig:
         raise Exception("cannot setup an OpenGL context")
示例#2
0
def check_support(force_enable=False, check_colormap=False):
    #platform checks:
    from xpra.platform.gui import gl_check
    warning = gl_check()
    if warning:
        if force_enable:
            log.warn("Warning: trying to continue despite '%s'" % warning)
        else:
            gl_check_error(warning)

    props = {}
    #this will import gtk.gtkgl / gdkgl or gi.repository.GtkGLExt / GdkGLExt:
    try:
        from xpra.client.gl.gtk_base.gtk_compat import get_info, gdkgl, Config_new_by_mode, GLDrawingArea
        assert GLDrawingArea
    except RuntimeError as e:
        gl_check_error(str(e))
        return {}
    props.update(get_info())
    for want_alpha in (GL_ALPHA_SUPPORTED, not GL_ALPHA_SUPPORTED):
        for double_buffered in (CAN_DOUBLE_BUFFER, not CAN_DOUBLE_BUFFER):
            display_mode = get_DISPLAY_MODE(want_alpha, double_buffered)
            log("get_DISPLAY_MODE(%s, %s)=%s", want_alpha, double_buffered,
                display_mode)
            glconfig = Config_new_by_mode(display_mode)
            log("Config_new_by_mode(%s)=%s", display_mode, glconfig)
            if glconfig:
                break
    if not glconfig:
        gl_check_error("cannot setup an OpenGL context")
        return {}
    props["display_mode"] = get_MODE_names(display_mode)
    #on OSX, we had to patch out get_depth...
    #so take extra precautions when querying properties:
    for x, fn_name in {
            "has_alpha": "has_alpha",
            "rgba": "is_rgba",
            "stereo": "is_stereo",
            "double-buffered": "is_double_buffered",
            "depth": "get_depth",
            "has-depth-buffer": "has_depth_buffer",
            "has-stencil-buffer": "has_stencil_buffer",
    }.items():
        fn = getattr(glconfig, fn_name, None)
        if fn:
            props[x] = fn()
        else:
            log("%s does not support %s()", glconfig, fn_name)
    for x in ("RED_SIZE", "GREEN_SIZE", "BLUE_SIZE", "ALPHA_SIZE",
              "AUX_BUFFERS", "DEPTH_SIZE", "STENCIL_SIZE", "ACCUM_RED_SIZE",
              "ACCUM_GREEN_SIZE", "ACCUM_BLUE_SIZE", "SAMPLE_BUFFERS",
              "SAMPLES"):
        prop = getattr(gdkgl, x)
        if not prop:
            continue
        try:
            v = glconfig.get_attrib(prop)[0]
            props[x.lower().replace("_", "-")] = v
        except:
            pass
    log("GL props=%s", props)

    if TEST_GTKGL_RENDERING:
        gl_props = test_gtkgl_rendering(glconfig, force_enable, check_colormap)
        if not gl_props:
            #if we fail the test rendering, don't return anything
            #so the client will know this backend should not be used
            return {}
        props.update(gl_props)
    else:
        log("gtkgl rendering test skipped")
    return props
示例#3
0
class GTKGLWindowBackingBase(GLWindowBackingBase):
    def idle_add(self, *args, **kwargs):
        glib.idle_add(*args, **kwargs)

    def init_gl_config(self, window_alpha):
        #setup gl config:
        alpha = GL_ALPHA_SUPPORTED and window_alpha
        display_mode = get_DISPLAY_MODE(want_alpha=alpha)
        self.glconfig = Config_new_by_mode(display_mode)
        if self.glconfig is None and CAN_DOUBLE_BUFFER:
            log("trying to toggle double-buffering")
            display_mode &= ~MODE_DOUBLE
            self.glconfig = Config_new_by_mode(display_mode)
        if not self.glconfig:
            raise Exception("cannot setup an OpenGL context")

    def is_double_buffered(self):
        return self.glconfig.is_double_buffered()

    def init_backing(self):
        self._backing = GLDrawingArea(self.glconfig)
        #must be overriden in subclasses to setup self._backing
        assert self._backing
        log("init_backing() backing=%s, alpha_enabled=%s", self._backing,
            self._alpha_enabled)
        if self._alpha_enabled:
            assert GL_ALPHA_SUPPORTED, "BUG: cannot enable alpha if GL backing does not support it!"
            screen = self._backing.get_screen()
            rgba = screen.get_rgba_colormap()
            display = screen.get_display()
            if not display.supports_composite() and not OSX:
                log.warn(
                    "display %s does not support compositing, transparency disabled",
                    display.get_name())
                self._alpha_enabled = False
            elif rgba:
                log("%s.__init__() using rgba colormap %s", self, rgba)
                self._backing.set_colormap(rgba)
            else:
                log.warn(
                    "Warning: failed to enable transparency, no RGBA colormap")
                self._alpha_enabled = False
        self._backing.set_events(self._backing.get_events()
                                 | POINTER_MOTION_MASK
                                 | POINTER_MOTION_HINT_MASK)

    def get_bit_depth(self, pixel_depth=0):
        gl_depth = self.glconfig.get_depth()
        log(
            "get_bit_depth() glconfig depth=%i, HIGH_BIT_DEPTH=%s, requested pixel depth=%i",
            gl_depth, HIGH_BIT_DEPTH, pixel_depth)
        bit_depth = 24
        if HIGH_BIT_DEPTH:
            if pixel_depth == 0:
                #auto detect
                if POSIX and gl_depth >= 24:
                    bit_depth = gl_depth
            elif pixel_depth > 0:
                bit_depth = pixel_depth
        log("get_bit_depth()=%i", bit_depth)
        return bit_depth

    def gl_context(self):
        b = self._backing
        if not b:
            log("cannot get an OpenGL context: no backing defined")
            return None
        if not is_realized(b):
            log.error("Error: OpenGL backing %s is not realized", b)
            return None
        w, h = self.size
        if w <= 0 or h <= 0:
            log.error("Error: invalid OpenGL backing size: %ix%i", w, h)
            return None
        try:
            context = GtkGLExtContext(b)
        except Exception as e:
            log("gl_context()", exc_info=True)
            log.error("Error: %s", e)
            return None
        log("%s.gl_context() GL Pixmap backing size: %d x %d, context=%s",
            self, w, h, context)
        return context

    def do_gl_show(self, _rect_count):
        if self.glconfig.is_double_buffered():
            # Show the backbuffer on screen
            log("%s.gl_show() swapping buffers now", self)
            gldrawable = self.get_gl_drawable()
            gldrawable.swap_buffers()
        else:
            #glFlush was enough
            pass

    def close(self):
        GLWindowBackingBase.close(self)
        self.glconfig = None
示例#4
0
def check_support(force_enable=False, check_colormap=False):
    #platform checks:
    from xpra.platform.gui import gl_check
    warning = gl_check()
    if warning:
        if force_enable:
            log.warn("Warning: trying to continue despite '%s'" % warning)
        else:
            gl_check_error(warning)

    props = {}
    #this will import gtk.gtkgl / gdkgl or gi.repository.GtkGLExt / GdkGLExt:
    try:
        from xpra.client.gl.gtk_base.gtk_compat import get_info, gdkgl, Config_new_by_mode, GLDrawingArea
    except RuntimeError as e:
        gl_check_error(str(e))
        return {}
    props.update(get_info())
    display_mode = get_DISPLAY_MODE()
    glconfig = Config_new_by_mode(display_mode)
    if glconfig is None and CAN_DOUBLE_BUFFER:
        log("trying to toggle double-buffering")
        display_mode &= ~MODE_DOUBLE
        glconfig = Config_new_by_mode(display_mode)
    if not glconfig:
        gl_check_error("cannot setup an OpenGL context")
        return {}
    props["display_mode"] = get_MODE_names(display_mode)
    #on OSX, we had to patch out get_depth...
    #so take extra precautions when querying properties:
    for x, fn_name in {
            "has_alpha": "has_alpha",
            "rgba": "is_rgba",
            "stereo": "is_stereo",
            "double-buffered": "is_double_buffered",
            "depth": "get_depth",
            "has-depth-buffer": "has_depth_buffer",
            "has-stencil-buffer": "has_stencil_buffer",
    }.items():
        fn = getattr(glconfig, fn_name, None)
        if fn:
            props[x] = fn()
        else:
            log("%s does not support %s()", glconfig, fn_name)
    for x in ("RED_SIZE", "GREEN_SIZE", "BLUE_SIZE", "ALPHA_SIZE",
              "AUX_BUFFERS", "DEPTH_SIZE", "STENCIL_SIZE", "ACCUM_RED_SIZE",
              "ACCUM_GREEN_SIZE", "ACCUM_BLUE_SIZE", "SAMPLE_BUFFERS",
              "SAMPLES"):
        prop = getattr(gdkgl, x)
        if not prop:
            continue
        try:
            v = glconfig.get_attrib(prop)[0]
            props[x.lower().replace("_", "-")] = v
        except:
            pass
    log("GL props=%s", props)

    if TEST_GTKGL_RENDERING:
        log("testing gtkgl rendering")
        from xpra.client.gl.gl_window_backing_base import paint_context_manager
        try:
            with paint_context_manager:
                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...
                    #(which we do not even show on screen)
                    #
                    #here is the old simpler alternative which does not work on some platforms:
                    # glext = gtk.gdkgl.ext(gdk.Pixmap(gdk.get_default_root_window(), 1, 1))
                    # gldrawable = glext.set_gl_capability(glconfig)
                    # glcontext = gtk.gdkgl.Context(gldrawable, direct=True)
                    w = gtk.Window()
                    w.set_decorated(False)
                    vbox = gtk.VBox()
                    glarea = GLDrawingArea(glconfig)
                    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()
                    gdk_window_process_all_updates()

                    gl_props = check_GL_support(glarea, force_enable)

                    if check_colormap:
                        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 s.list_visuals():
                        #    gl_props["visual[%s]" % i] = visual_to_str(v)
                        #    i += 1
                finally:
                    if w:
                        w.destroy()
                    del glext, glconfig
        except Exception as e:
            log("check_support failed", exc_info=True)
            log.error("Error: gtkgl rendering failed its sanity checks:")
            log.error(" %s", e)
            return {}
        else:
            props.update(gl_props)
    else:
        log("gtkgl rendering test skipped")
    return props