예제 #1
0
class GLDrawingArea(GLWindowBackingBase):
    def __repr__(self):
        return "gtk%i.GLDrawingArea(%s, %s, %s)" % (
            gtk_version(), self.wid, self.size, self.pixel_format)

    def idle_add(self, *args, **kwargs):
        glib.idle_add(*args, **kwargs)

    def init_gl_config(self, window_alpha):
        self.context = GLContext(window_alpha)
        self.window_context = None

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

    def init_backing(self):
        da = gtk.DrawingArea()
        #da.connect('configure_event', self.on_configure_event)
        #da.connect('draw', self.on_draw)
        #double-buffering is enabled by default anyway, so this is redundant:
        #da.set_double_buffered(True)
        da.set_size_request(*self.size)
        da.set_events(da.get_events() | POINTER_MOTION_MASK
                      | POINTER_MOTION_HINT_MASK)
        da.show()
        self._backing = da

    def get_bit_depth(self, pixel_depth):
        return self.context.get_bit_depth() or pixel_depth or 24

    def gl_context(self):
        b = self._backing
        if not b:
            return None
        gdk_window = b.get_window()
        assert gdk_window
        self.window_context = self.context.get_paint_context(gdk_window)
        return self.window_context

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

    def close(self):
        GLWindowBackingBase.close(self)
        c = self.context
        if c:
            self.context = None
            c.destroy()

    def cairo_draw(self, _context):
        w, h = self.size
        with self.gl_context():
            self.gl_init()
            self.present_fbo(0, 0, w, h)
예제 #2
0
class GLDrawingArea(GLWindowBackingBase):
    def __init__(self, wid: int, window_alpha: bool, pixel_depth: int = 0):
        self.on_realize_cb = []
        super().__init__(wid, window_alpha, pixel_depth)

    def __repr__(self):
        return "GLDrawingArea(%s, %s, %s)" % (self.wid, self.size,
                                              self.pixel_format)

    def idle_add(self, *args, **kwargs):
        GLib.idle_add(*args, **kwargs)

    def init_gl_config(self):
        self.context = GLContext(self._alpha_enabled)  #pylint: disable=not-callable
        self.window_context = None

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

    def init_backing(self):
        da = Gtk.DrawingArea()
        da.connect_after("realize", self.on_realize)
        #da.connect('configure_event', self.on_configure_event)
        #da.connect('draw', self.on_draw)
        #double-buffering is enabled by default anyway, so this is redundant:
        #da.set_double_buffered(True)
        da.set_size_request(*self.size)
        da.set_events(da.get_events() | Gdk.EventMask.POINTER_MOTION_MASK
                      | Gdk.EventMask.POINTER_MOTION_HINT_MASK)
        da.show()
        self._backing = da

    def on_realize(self, *args):
        onrcb = self.on_realize_cb
        log("GLDrawingArea.on_realize%s callbacks=%s", args, onrcb)
        self.on_realize_cb = []
        gl_context = self.gl_context()
        with gl_context:
            for x, args in onrcb:
                try:
                    x(gl_context, *args)
                except Exception:
                    log.error("Error calling realize callback %s",
                              x,
                              exc_info=True)

    def with_gl_context(self, cb, *args):
        da = self._backing
        if da and da.get_mapped():
            gl_context = self.gl_context()
            if gl_context:
                with gl_context:
                    cb(gl_context, *args)
            else:
                cb(None, *args)
        else:
            log("GLDrawingArea.with_gl_context delayed: %s%s", cb,
                ellipsizer(args))
            self.on_realize_cb.append((cb, args))

    def get_bit_depth(self, pixel_depth=0):
        return pixel_depth or self.context.get_bit_depth() or 24

    def gl_context(self):
        b = self._backing
        if not b:
            return None
        gdk_window = b.get_window()
        if not gdk_window:
            raise Exception("backing %s does not have a gdk window!" % b)
        self.window_context = self.context.get_paint_context(gdk_window)
        return self.window_context

    def do_gl_show(self, rect_count):
        if self.is_double_buffered():
            # Show the backbuffer on screen
            log("%s.do_gl_show(%s) swapping buffers now", rect_count, self)
            self.window_context.swap_buffers()
        else:
            #glFlush was enough
            pass

    def close_gl_config(self):
        c = self.context
        if c:
            self.context = None
            c.destroy()

    def draw_fbo(self, _context):
        w, h = self.size
        with self.gl_context():
            self.gl_init()
            self.present_fbo(0, 0, w, h)