xpra icon
Bug tracker and wiki

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


Ticket #465: newbuffer-pyopengl-leaks.patch

File newbuffer-pyopengl-leaks.patch, 4.0 KB (added by Antoine Martin, 7 years ago)

enables memoryview direct memory copy with pyopengl for memoryviews, str and buffers (indirectly) - all leak

  • xpra/client/gl/gl_window_backing.py

     
    55# later version. See the file COPYING for details.
    66
    77#only works with gtk2:
     8import sys
    89import os
    910from gtk import gdk
    1011assert gdk
     
    1617log = Logger("opengl", "paint")
    1718OPENGL_DEBUG = os.environ.get("XPRA_OPENGL_DEBUG", "0")=="1"
    1819
    19 
    2020from xpra.codecs.codec_constants import get_subsampling_divs
    2121from xpra.client.gl.gl_check import get_DISPLAY_MODE
    2222from xpra.client.gl.gl_colorspace_conversions import YUV2RGB_shader, RGBP2RGB_shader
    2323from xpra.client.gtk2.window_backing import GTK2WindowBacking, fire_paint_callbacks
    24 from OpenGL.GL import GL_PROJECTION, GL_MODELVIEW, \
     24from OpenGL import version as OpenGL_version
     25from OpenGL.GL import \
     26    GL_PROJECTION, GL_MODELVIEW, \
    2527    GL_UNPACK_ROW_LENGTH, GL_UNPACK_ALIGNMENT, \
    2628    GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, GL_NEAREST, \
    2729    GL_UNSIGNED_BYTE, GL_LUMINANCE, GL_LINEAR, \
     
    9799from ctypes import c_char_p
    98100
    99101
     102#support for memory views requires Python 2.7 and PyOpenGL 3.1
     103memoryview_type = None
     104if sys.version_info[:2]>=(2,7) and OpenGL_version.__version__.split('.')[:2]>=['3','1']:
     105    memoryview_type = memoryview
     106
     107
    100108# Texture number assignment
    101109#  1 = Y plane
    102110#  2 = U plane
     
    496504        return True
    497505
    498506    def do_video_paint(self, img, x, y, enc_width, enc_height, width, height, options, callbacks):
    499         #note: we clone here unconditionally because this gives us the pixels
    500         #as a string object which PyOpenGL can use for upload, whereas the buffer objects
    501         #we get from the avcodec and vpx decoders cannot be used.
    502         #PyOpenGL version 3.1 has some support for the memory view interface
    503         #but this requires memoryview support which requires python>=2.7
    504         img.clone_pixel_data()
     507        #figure out if we can use the pixels directly
     508        #(only if stored as a memoryview)
     509        pixels = img.get_pixels()
     510        assert len(pixels)==3, "invalid number of planes: %s" % len(pixels)
     511        plane_types = set([type(plane) for plane in img.get_pixels()])
     512        log.info("memoryview_type=%s, plane_types=%s", memoryview_type, plane_types)
     513        if memoryview_type is not None and len(plane_types)==1 and list(plane_types)[0]==str:
     514            log.info("using memoryview wrapper for str %s", img)
     515            wrapped = [memoryview_type(plane) for plane in pixels]
     516            img.set_pixels(wrapped)
     517        elif memoryview_type is not None and len(plane_types)==1 and list(plane_types)[0]==buffer:
     518            log.info("using memoryview wrapper for str %s", img)
     519            wrapped = [memoryview_type(str(plane)) for plane in pixels]
     520            img.set_pixels(wrapped)
     521        elif memoryview_type is not None and len(plane_types)==1 and list(plane_types)[0]==memoryview_type:
     522            log.info("using memoryview directly on %s", img)
     523        else:
     524            img.clone_pixel_data()
    505525        gobject.idle_add(self.gl_paint_planar, img, x, y, enc_width, enc_height, width, height, callbacks)
    506526
    507527    def gl_paint_planar(self, img, x, y, enc_width, enc_height, width, height, callbacks):
    508528        #this function runs in the UI thread, no video_decoder lock held
     529        log("gl_paint_planar%s", (img, x, y, enc_width, enc_height, width, height, callbacks))
    509530        try:
    510531            pixel_format = img.get_pixel_format()
    511532            assert pixel_format in ("YUV420P", "YUV422P", "YUV444P", "GBRP"), "sorry the GL backing does not handle pixel format '%s' yet!" % (pixel_format)
     
    516537                return
    517538            try:
    518539                self.update_planar_textures(x, y, enc_width, enc_height, img, pixel_format, scaling=(enc_width!=width or enc_height!=height))
     540                img.free()
     541
    519542                # Update FBO texture
    520543                x_scale, y_scale = 1, 1
    521544                if width!=enc_width or height!=enc_height: