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: gl-memoryview-nocopy.patch

File gl-memoryview-nocopy.patch, 3.5 KB (added by Antoine Martin, 7 years ago)

zerocopy patch for pyopengl texture upload

  • 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 and ENABLE_MEMORYVIEW is True)
     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        if memoryview_type is not None and len(plane_types)==1 and list(plane_types)[0]==memoryview_type:
     513            log("using memoryview directly on %s", img)
     514        else:
     515            #copy so the data will be usable (usually a str)
     516            img.clone_pixel_data()
    505517        gobject.idle_add(self.gl_paint_planar, img, x, y, enc_width, enc_height, width, height, callbacks)
    506518
    507519    def gl_paint_planar(self, img, x, y, enc_width, enc_height, width, height, callbacks):
    508520        #this function runs in the UI thread, no video_decoder lock held
     521        log("gl_paint_planar%s", (img, x, y, enc_width, enc_height, width, height, callbacks))
    509522        try:
    510523            pixel_format = img.get_pixel_format()
    511524            assert pixel_format in ("YUV420P", "YUV422P", "YUV444P", "GBRP"), "sorry the GL backing does not handle pixel format '%s' yet!" % (pixel_format)
     
    516529                return
    517530            try:
    518531                self.update_planar_textures(x, y, enc_width, enc_height, img, pixel_format, scaling=(enc_width!=width or enc_height!=height))
     532                img.free()
     533
    519534                # Update FBO texture
    520535                x_scale, y_scale = 1, 1
    521536                if width!=enc_width or height!=enc_height: