xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #147: gl-rgb24.patch

File gl-rgb24.patch, 8.9 KB (added by Antoine Martin, 9 years ago)

better gl patch

  • xpra/client.py

     
    6565from xpra.maths import std_unit
    6666
    6767from xpra.client_window import ClientWindow
    68 ClientWindowClass = ClientWindow
    69 #the GL backend only works with gtk2
    70 USE_OPENGL = False
     68USE_OPENGL = os.environ.get("XPRA_OPENGL", "1")=="1"
     69GLClientWindowClass = None
     70#the GL backend only works with gtk2:
    7171if USE_OPENGL and not is_gtk3():
    7272    try:
    7373        from xpra.gl_client_window import GLClientWindow
    74         ClientWindowClass = GLClientWindow
     74        GLClientWindowClass = GLClientWindow
    7575    except ImportError, e:
    76         log.info("Disabled OpenGL output: %s" % e)
     76        log.warn("Disabled OpenGL output: %s" % e)
     77        USE_OPENGL = False
    7778
    7879def nn(x):
    7980    if x is None:
     
    789790            auto_refresh_delay = 0                          #server takes care of it
    790791        else:
    791792            auto_refresh_delay = self.auto_refresh_delay    #we do it
     793        ClientWindowClass = ClientWindow
     794        if not self.mmap_enabled and GLClientWindowClass:
     795            ClientWindowClass = GLClientWindowClass
    792796        window = ClientWindowClass(self, wid, x, y, w, h, metadata, override_redirect, client_properties, auto_refresh_delay)
    793797        self._id_to_window[wid] = window
    794798        self._window_to_id[window] = wid
  • xpra/codec_constants.py

     
    44# Parti is released under the terms of the GNU GPL v2, or, at your option, any
    55# later version. See the file COPYING for details.
    66
    7 YUV420P = 0
    8 YUV422P = 1
    9 YUV444P = 2
     7YUV420P = 420
     8YUV422P = 422
     9YUV444P = 444
  • xpra/gl_window_backing.py

     
    1616from xpra.codec_constants import YUV420P, YUV422P, YUV444P
    1717from xpra.gl_colorspace_conversions import GL_COLORSPACE_CONVERSIONS
    1818from xpra.window_backing import PixmapBacking
     19from xpra.scripts.main import ENCODINGS
    1920from OpenGL.GL import GL_PROJECTION, GL_MODELVIEW, GL_VERTEX_ARRAY, \
    2021    GL_TEXTURE_COORD_ARRAY, GL_FRAGMENT_PROGRAM_ARB, \
    21     GL_PROGRAM_ERROR_STRING_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, \
     22    GL_PROGRAM_ERROR_STRING_ARB, GL_RGB, GL_PROGRAM_FORMAT_ASCII_ARB, \
    2223    GL_TEXTURE_RECTANGLE_ARB, GL_UNPACK_ROW_LENGTH, \
    2324    GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, GL_NEAREST, \
    2425    GL_UNSIGNED_BYTE, GL_LUMINANCE, GL_LINEAR, \
     
    3132    glTexImage2D, \
    3233    glMultiTexCoord2i, \
    3334    glVertex2i, glEnd
    34 from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glBindProgramARB, glProgramStringARB
     35from OpenGL.GL.ARB.vertex_program import glGenProgramsARB, glDeleteProgramsARB, glBindProgramARB, glProgramStringARB
    3536
    3637"""
    3738This is the gtk2 + OpenGL version.
    3839"""
    3940class GLPixmapBacking(PixmapBacking):
     41    RGB24 = 1   #make sure this never clashes with codec_constants!
    4042
    4143    def __init__(self, wid, w, h, mmap_enabled, mmap):
    4244        PixmapBacking.__init__(self, wid, w, h, mmap_enabled, mmap)
     
    8284
    8385    def gl_expose_event(self, glarea, event):
    8486        log("GL expose_event(%s, %s) area=%s", glarea, event, event.area)
    85         if self.pixel_format is not None:
     87        if self.pixel_format in (YUV420P, YUV422P, YUV444P):
    8688            self.render_image()
    8789
     90    def do_paint_pixbuf(self, pixbuf, x, y, width, height, options, callbacks):
     91        log.info("do_paint_pixbuf(%s, %s, %s, %s, %s, %s, %s)", pixbuf, x, y, width, height, options, callbacks)
     92        img_data = pixbuf.get_pixels()
     93        rowstride = pixbuf.get_rowstride()
     94        self.do_paint_rgb24(img_data, x, y, width, height, rowstride, options, callbacks)
     95
     96    def do_paint_rgb24(self, img_data, x, y, width, height, rowstride, options, callbacks):
     97        """ must be called from UI thread """
     98        log.info("do_paint_rgb24(%s bytes, %s, %s, %s, %s, %s, %s, %s)", len(img_data), x, y, width, height, rowstride, options, callbacks)
     99        assert "rgb24" in ENCODINGS
     100
     101        drawable = self.glarea.get_gl_drawable()
     102        context = self.glarea.get_gl_context()
     103        if not drawable.gl_begin(context):
     104            raise Exception("** Cannot create OpenGL rendering context!")
     105        assert self.textures is not None
     106
     107        #cleanup if we were doing yuv previously:
     108        if self.pixel_format!=GLPixmapBacking.RGB24:
     109            glDisable(GL_FRAGMENT_PROGRAM_ARB)
     110            glDeleteProgramsARB(3, self.yuv_shader)
     111            self.yuv_shader = None
     112        self.pixel_format = GLPixmapBacking.RGB24
     113        w, h = self.size
     114
     115        glEnable(GL_TEXTURE_RECTANGLE_ARB)
     116        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self.textures[0])
     117        glPixelStorei(GL_UNPACK_ROW_LENGTH, rowstride/3)
     118
     119        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
     120        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
     121        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0)       
     122        glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, img_data)
     123        drawable.gl_end()
     124
     125        if not drawable.gl_begin(context):
     126            raise Exception("** Cannot create OpenGL rendering context!")
     127        glBegin(GL_QUADS);
     128        for x,y in ((0, 0), (0, h), (w, h), (w, 0)):
     129            glMultiTexCoord2i(GL_TEXTURE0, x, y)
     130            glVertex2i(x, y)
     131        glEnd()
     132
     133        drawable.swap_buffers()
     134        drawable.gl_end()
     135
     136        self.fire_paint_callbacks(callbacks, True)
     137        return  False
     138
    88139    def do_video_paint(self, coding, img_data, x, y, width, height, options, callbacks):
    89140        log("do_video_paint: options=%s, decoder=%s", options, type(self._video_decoder))
    90141        err, rowstrides, img_data = self._video_decoder.decompress_image_to_yuv(img_data, options)
     
    107158            return 1, 2, 2
    108159        elif pixel_format==YUV422P:
    109160            return 1, 2, 1
    110         elif pixel_format==YUV444P:
     161        elif pixel_format==YUV444P or pixel_format==GLPixmapBacking.RGB24:
    111162            return 1, 1, 1
    112163        raise Exception("invalid pixel format: %s" % pixel_format)
    113164
     
    169220        return True
    170221
    171222    def render_image(self):
    172         if self.pixel_format is None:
     223        if self.pixel_format not in (YUV420P, YUV422P, YUV444P, GLPixmapBacking.RGB24):
    173224            #not ready to render yet
    174225            return
    175226        drawable = self.glarea.get_gl_drawable()
    176227        context = self.glarea.get_gl_context()
     228        if not drawable.gl_begin(context):
     229            raise Exception("** Cannot create OpenGL rendering context!")
    177230        log("GL render_image() size=%s", self.size)
     231        divs = self.get_subsampling_divs(self.pixel_format)
     232
    178233        w, h = self.size
    179         if not drawable.gl_begin(context):
    180             raise Exception("** Cannot create OpenGL rendering context!")
    181234        glEnable(GL_FRAGMENT_PROGRAM_ARB)
    182235        glBegin(GL_QUADS);
    183         divs = self.get_subsampling_divs(self.pixel_format)
    184236        for x,y in ((0, 0), (0, h), (w, h), (w, 0)):
    185237            for texture, index in ((GL_TEXTURE0, 0), (GL_TEXTURE1, 1), (GL_TEXTURE2, 2)):
    186238                div = divs[index]
  • xpra/window_backing.py

     
    326326        if not pixbuf:
    327327            log.error("failed %s pixbuf=%s data len=%s" % (coding, pixbuf, len(img_data)))
    328328            self.fire_paint_callbacks(callbacks, False)
    329         else:
    330             gc = self._backing.new_gc()
    331             self._backing.draw_pixbuf(gc, pixbuf, 0, 0, x, y, width, height)
    332             self.fire_paint_callbacks(callbacks, True)
     329            return  False
     330        self.do_paint_pixbuf(pixbuf, x, y, width, height, options, callbacks)
    333331        return  False
    334332
     333    def do_paint_pixbuf(self, pixbuf, x, y, width, height, options, callbacks):
     334        gc = self._backing.new_gc()
     335        self._backing.draw_pixbuf(gc, pixbuf, 0, 0, x, y, width, height)
     336        self.fire_paint_callbacks(callbacks, True)
     337
    335338    def paint_mmap(self, img_data, x, y, width, height, rowstride, options, callbacks):
    336339        """ must be called from UI thread """
    337340        #we could run just paint_rgb24 from the UI thread,
  • xpra/x264/x264lib.c

     
    130130int get_pixel_format(int csc)
    131131{
    132132        if (csc == PIX_FMT_YUV420P || csc < 0)
    133                 return 0;
     133                return 420;
    134134        else if (csc == PIX_FMT_YUV422P)
    135                 return 1;
     135                return 422;
    136136        else if (csc == PIX_FMT_YUV444P)
    137                 return 2;
     137                return 444;
    138138        else
    139139                return -1;
    140140}