コード例 #1
0
    def gl_swap_buffer(self):
        """ This function is used to swap the front/back buffers after rendering
        an output video frame.
        PROTOTYPE:
          m64p_error VidExt_GL_SwapBuffers(void)"""
        # Note: It can spam the message in the logs, it's best to never turn it on.
        #log.debug("Vidext: gl_swap_buffer()")
        if self.new_surface:
            log.info("VidExtFuncGLSwapBuf: New surface has been detected")
            self.egl_surface = egl.eglCreateWindowSurface(
                self.egl_display, self.egl_config[0], self.window_handle,
                self.window_attributes)

            try:
                egl.eglMakeCurrent(self.egl_display, self.egl_surface,
                                   self.egl_surface, self.egl_context)
                egl.eglSwapBuffers(self.egl_display, self.egl_surface)
            except:
                log.error(
                    f"eglMakeCurrent() returned error: {egl.eglGetError()}")

            self.new_surface = False
        else:
            if self.window.m64p_wrapper.running == True:
                egl.eglSwapBuffers(self.egl_display, self.egl_surface)

        return wrp_dt.m64p_error.M64ERR_SUCCESS.value
コード例 #2
0
 def initialize(self, width, height):
     gbm_format = egl.EGLint()
     if not egl.eglGetConfigAttrib(self.egl_dpy, self.egl_config,
                                   egl.EGL_NATIVE_VISUAL_ID,
                                   pointer(gbm_format)):
         return False
     self.gbm_surf = libgbm.gbm_surface_create(self.gbm_dev, width, height,
                                               gbm_format,
                                               libgbm.GBM_BO_USE_RENDERING)
     if not self.gbm_surf:
         self.gbm_surf = None
         return False
     self.egl_surface = egl.eglCreateWindowSurface(self.egl_dpy,
                                                   self.egl_config,
                                                   self.gbm_surf, None)
     if self.egl_surface == egl.EGL_NO_SURFACE:
         self.egl_surface = None
         self.release()
         return False
     return True
コード例 #3
0
ファイル: kms.py プロジェクト: marcan/blitzloop
    def __init__(self, width=640, height=480, fullscreen=False, aspect=None):
        self.gl = gl
        self.bo_next = self.bo_prev = None
        self.last_swap = time.time()
        self.frame_count = 0

        self.card = pykms.Card()
        print("DRM fd: %d" % self.card.fd)
        print("Has atomic: %r" % self.card.has_atomic)

        self.render_fd = -1

        render_name = libdrm.drmGetRenderDeviceNameFromFd(self.card.fd)
        print("Render device name: %r" % render_name)

        if render_name:
            try:
                self.render_fd = os.open(render_name, os.O_RDWR)
            except OSError:
                print("Render node not available")

        print("Render fd: %d" % self.render_fd)
        self.gbm_dev = libgbm.gbm_create_device(self.card.fd)
        if not self.gbm_dev:
            raise Exception("Failed to create GBM device")

        print("GBM dev: %x" % self.gbm_dev)

        self.res = pykms.ResourceManager(self.card)
        self.conn = self.res.reserve_connector()
        self.crtc = self.res.reserve_crtc(self.conn)
        self.root_plane = self.res.reserve_generic_plane(self.crtc)
        if not self.root_plane:
            raise Exception("Root plane not available")

        self.mode = mode = self.conn.get_default_mode()

        BaseDisplay.__init__(self, mode.hdisplay, mode.vdisplay, True, aspect)

        self.fps = 1000 * mode.clock / (mode.htotal * mode.vtotal)
        print("Creating GBM surface (%dx%d %f Hz)" % (mode.hdisplay, mode.vdisplay, self.fps))

        self.gbm_surface = libgbm.gbm_surface_create(
            c_void_p(self.gbm_dev), mode.hdisplay, mode.vdisplay,
            GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING)

        if not self.gbm_surface:
            raise Exception("Failed to create GBM surface")
        print("GBM surface: %x" % self.gbm_surface)

        self.disp = egl.eglGetDisplay(self.gbm_dev)
        if not self.disp:
            raise Exception("Failed to get egl display")

        attribList = arrays.GLintArray.asArray([
            egl.EGL_RENDERABLE_TYPE, egl.EGL_OPENGL_ES2_BIT,
            egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
            #egl.EGL_COLOR_BUFFER_TYPE, egl.EGL_RGB_BUFFER,
            egl.EGL_RED_SIZE, 8,
            egl.EGL_GREEN_SIZE, 8,
            egl.EGL_BLUE_SIZE, 8,
            egl.EGL_ALPHA_SIZE, 0,
            egl.EGL_NONE
        ])
        ctxAttrib = arrays.GLintArray.asArray([
            egl.EGL_CONTEXT_CLIENT_VERSION, 2,
            egl.EGL_NONE
        ])
        egl.eglInitialize(self.disp, None, None)
        config = egl.EGLConfig()
        num_configs = ctypes.c_long()
        egl.eglChooseConfig(self.disp, attribList, byref(config), 1, byref(num_configs))

        ret = ctypes.c_int()
        egl.eglBindAPI(egl.EGL_OPENGL_ES_API)

        self.surface = egl.eglCreateWindowSurface(self.disp, config, c_void_p(self.gbm_surface), None)
        self.context = egl.eglCreateContext(self.disp, config, egl.EGL_NO_CONTEXT, ctxAttrib)
        assert egl.eglMakeCurrent(self.disp, self.surface, self.surface, self.context)

        egl.eglSwapInterval(self.disp, 1)

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)

        gl.glClearColor(0, 0, 0, 1.0)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

        #fb = self.lock_next()
        #self.crtc.set_mode(self.conn, fb, mode)

        modeb = mode.to_blob(self.card)

        req = pykms.AtomicReq(self.card)
        req.add(self.conn, "CRTC_ID", self.crtc.id)
        req.add(self.crtc, {"ACTIVE": 1,
                            "MODE_ID": modeb.id})
        if req.test(allow_modeset = True):
            raise Exception("Atomic test failed")
        if req.commit_sync(allow_modeset = True):
            raise Exception("Atomic commit failed")

        self.win_width = self.width = mode.hdisplay
        self.win_height = self.height = mode.vdisplay

        gl.glViewport(0, 0, self.win_width, self.win_height)

        self.clear_color = self.BLACK

        self._initialize()
コード例 #4
0
ファイル: rpi.py プロジェクト: marcan/blitzloop
    def __init__(self, width=640, height=480, fullscreen=False, aspect=None):
        self.gl = gl
        libbcm_host.bcm_host_init()
        display = libbcm_host.vc_dispmanx_display_open(0)

        mode = DISPMANX_MODEINFO_T()
        libbcm_host.vc_dispmanx_display_get_info(display, byref(mode))
        print("Display mode: %dx%d" % (mode.width, mode.height))

        self.disp = egl.eglGetDisplay(egl.EGL_DEFAULT_DISPLAY)
        attribList = arrays.GLintArray.asArray([
            egl.EGL_RENDERABLE_TYPE, egl.EGL_OPENGL_ES2_BIT,
            egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
            #egl.EGL_COLOR_BUFFER_TYPE, egl.EGL_RGB_BUFFER,
            egl.EGL_RED_SIZE, 8,
            egl.EGL_GREEN_SIZE, 8,
            egl.EGL_BLUE_SIZE, 8,
            egl.EGL_ALPHA_SIZE, 8,
            egl.EGL_NONE
        ])
        ctxAttrib = arrays.GLintArray.asArray([
            egl.EGL_CONTEXT_CLIENT_VERSION, 2,
            egl.EGL_NONE
        ])
        egl.eglInitialize(self.disp, None, None)
        config = egl.EGLConfig()
        num_configs = ctypes.c_long()
        egl.eglChooseConfig(self.disp, attribList, byref(config), 1, byref(num_configs))

        ret = ctypes.c_int()
        egl.eglBindAPI(egl.EGL_OPENGL_ES_API)

        update = libbcm_host.vc_dispmanx_update_start(0)
        rectDst = VC_RECT_T()
        rectDst.x = rectDst.y = 0
        rectDst.width = mode.width
        rectDst.height = mode.height

        rectSrc = VC_RECT_T()
        rectSrc.x = rectDst.y = 0
        rectSrc.width = mode.width << 16
        rectSrc.height = mode.height << 16

        alpha = VC_DISPMANX_ALPHA_T()
        alpha.flags = 1 << 16  # premultiplied alpha
        alpha.opacity = 255
        alpha.mask = 0

        self.nativeWindow = EGL_DISPMANX_WINDOW_T()
        self.nativeWindow.width = mode.width
        self.nativeWindow.height = mode.height

        layer = 0
        self.nativeWindow.element = libbcm_host.vc_dispmanx_element_add(
            update, display, layer, byref(rectDst), 0, byref(rectSrc),
            0, byref(alpha), 0, 0)

        libbcm_host.vc_dispmanx_update_submit_sync(update)
        libbcm_host.vc_dispmanx_display_close(display)

        self.surface = egl.eglCreateWindowSurface(self.disp, config, byref(self.nativeWindow), None)
        self.context = egl.eglCreateContext(self.disp, config, egl.EGL_NO_CONTEXT, ctxAttrib)
        assert egl.eglMakeCurrent(self.disp, self.surface, self.surface, self.context)

        egl.eglSwapInterval(self.disp, 1)

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)

        for i in range(5):
            gl.glClearColor(0, 0, 0, 1.0)
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            egl.eglSwapBuffers(self.disp, self.surface)

        self.win_width = self.width = mode.width
        self.win_height = self.height = mode.height

        gl.glViewport(0, 0, self.win_width, self.win_height)

        BaseDisplay.__init__(self, mode.width, mode.height, True, aspect)

        # Transparent layer
        self.clear_color = self.TRANSPARENT

        self._initialize()
コード例 #5
0
ファイル: rpi.py プロジェクト: Ppjet6/blitzloop
    def __init__(self, width=640, height=480, fullscreen=False, aspect=None):
        self.gl = gl
        libbcm_host.bcm_host_init()
        display = libbcm_host.vc_dispmanx_display_open(0)

        mode = DISPMANX_MODEINFO_T()
        libbcm_host.vc_dispmanx_display_get_info(display, byref(mode))
        print("Display mode: %dx%d" % (mode.width, mode.height))

        self.disp = egl.eglGetDisplay(egl.EGL_DEFAULT_DISPLAY)
        attribList = arrays.GLintArray.asArray([
            egl.EGL_RENDERABLE_TYPE, egl.EGL_OPENGL_ES2_BIT,
            egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
            #egl.EGL_COLOR_BUFFER_TYPE, egl.EGL_RGB_BUFFER,
            egl.EGL_RED_SIZE, 8,
            egl.EGL_GREEN_SIZE, 8,
            egl.EGL_BLUE_SIZE, 8,
            egl.EGL_ALPHA_SIZE, 8,
            egl.EGL_NONE
        ])
        ctxAttrib = arrays.GLintArray.asArray([
            egl.EGL_CONTEXT_CLIENT_VERSION, 2,
            egl.EGL_NONE
        ])
        egl.eglInitialize(self.disp, None, None)
        config = egl.EGLConfig()
        num_configs = ctypes.c_long()
        egl.eglChooseConfig(self.disp, attribList, byref(config), 1, byref(num_configs))

        ret = ctypes.c_int()
        egl.eglBindAPI(egl.EGL_OPENGL_ES_API)

        update = libbcm_host.vc_dispmanx_update_start(0)
        rectDst = VC_RECT_T()
        rectDst.x = rectDst.y = 0
        rectDst.width = mode.width
        rectDst.height = mode.height

        rectSrc = VC_RECT_T()
        rectSrc.x = rectDst.y = 0
        rectSrc.width = mode.width << 16
        rectSrc.height = mode.height << 16

        alpha = VC_DISPMANX_ALPHA_T()
        alpha.flags = 1 << 16  # premultiplied alpha
        alpha.opacity = 255
        alpha.mask = 0

        self.nativeWindow = EGL_DISPMANX_WINDOW_T()
        self.nativeWindow.width = mode.width
        self.nativeWindow.height = mode.height

        layer = 0
        self.nativeWindow.element = libbcm_host.vc_dispmanx_element_add(
            update, display, layer, byref(rectDst), 0, byref(rectSrc),
            0, byref(alpha), 0, 0)

        libbcm_host.vc_dispmanx_update_submit_sync(update)
        libbcm_host.vc_dispmanx_display_close(display)

        self.surface = egl.eglCreateWindowSurface(self.disp, config, byref(self.nativeWindow), None)
        self.context = egl.eglCreateContext(self.disp, config, egl.EGL_NO_CONTEXT, ctxAttrib)
        assert egl.eglMakeCurrent(self.disp, self.surface, self.surface, self.context)

        egl.eglSwapInterval(self.disp, 1)

        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)

        for i in range(5):
            gl.glClearColor(0, 0, 0, 1.0)
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            egl.eglSwapBuffers(self.disp, self.surface)

        self.win_width = self.width = mode.width
        self.win_height = self.height = mode.height

        gl.glViewport(0, 0, self.win_width, self.win_height)

        BaseDisplay.__init__(self, mode.width, mode.height, True, aspect)

        # Transparent layer
        self.clear_color = self.TRANSPARENT

        self._initialize()
コード例 #6
0
    def video_set_mode(self,
                       width,
                       height,
                       bits,
                       screenmode,
                       flags,
                       refreshrate=None):
        """This function creates a rendering window or switches into a
        fullscreen video mode. Any desired OpenGL attributes should be set
        before calling this function.
        PROTOTYPE:
         m64p_error VidExt_SetVideoMode(int Width, int Height, int BitsPerPixel,
                          m64p_video_mode ScreenMode, m64p_video_flags Flags)"""
        log.debug(
            f"Vidext: video_set_mode(width: {str(width)}, height: {str(height)}, bits: {str(bits)}, screenmode: {wrp_dt.m64p_video_mode(screenmode).name}, flags:{wrp_dt.m64p_video_flags(flags).name}"
        )

        self.width = width
        self.height = height

        self.former_size = self.window.get_size()
        # Needed for get_preferred_size() to work
        self.window.set_resizable(False)
        # It doesn't just get the preferred size, it DOES resize the window too
        self.window.canvas.get_preferred_size()
        # Necessary so that we tell the GUI to not shrink the window further than the size of the widget set by mupen64plus
        self.window.canvas.set_size_request(width, height)
        # XXX: Workaround because GTK is too slow.
        time.sleep(0.1)

        # The window is resizable if gfx plugin allows it
        if flags == wrp_dt.m64p_video_flags.M64VIDEOFLAG_SUPPORT_RESIZING.value:
            self.window.set_resizable(True)

        log.debug(f'Double buffer: {self.double_buffer}')
        log.debug(f'Buffer size: {self.buffer_size}')
        log.debug(f'Depth size: {self.depth_size}')
        log.debug(f'Red size: {self.red_size}')
        log.debug(f'Green size: {self.green_size}')
        log.debug(f'Blue size: {self.blue_size}')
        log.debug(f'Alpha size: {self.alpha_size}')
        log.debug(f'Swap control: {self.swap_control}')
        log.debug(f'Multisample buffer: {self.multisample_buffer}')
        log.debug(f'Multisample samples: {self.multisample_samples}')
        log.debug(f'OpenGL: {self.context_major}.{self.context_minor}')
        log.debug(f'Context profile: {self.profile_bit}')

        self.egl_attributes = gl.arrays.GLintArray.asArray([
            egl.EGL_BUFFER_SIZE, self.buffer_size, egl.EGL_DEPTH_SIZE,
            self.depth_size, egl.EGL_RED_SIZE, self.red_size,
            egl.EGL_GREEN_SIZE, self.green_size, egl.EGL_BLUE_SIZE,
            self.blue_size, egl.EGL_ALPHA_SIZE, self.alpha_size,
            egl.EGL_SAMPLE_BUFFERS, self.multisample_buffer, egl.EGL_SAMPLES,
            self.multisample_samples, egl.EGL_RENDERABLE_TYPE, self.api_bit,
            egl.EGL_NONE
        ])

        self.window_attributes = gl.arrays.GLintArray.asArray(
            [egl.EGL_RENDER_BUFFER, self.double_buffer, egl.EGL_NONE])

        self.opengl_version = gl.arrays.GLintArray.asArray([
            egl.EGL_CONTEXT_MAJOR_VERSION, self.context_major,
            egl.EGL_CONTEXT_MINOR_VERSION, self.context_minor,
            egl.EGL_CONTEXT_OPENGL_PROFILE_MASK, self.profile_bit, egl.EGL_NONE
        ])

        # Return a list of EGL frame buffer configurations that match specified attributes
        num_configs = c.c_long()
        self.egl_config = (egl.EGLConfig * 2)()
        config_chosen = egl.eglChooseConfig(self.egl_display,
                                            self.egl_attributes,
                                            self.egl_config, 2, num_configs)
        if config_chosen == None:
            log.error(f"eglChooseConfig() returned error: {egl.eglGetError()}")
            return wrp_dt.m64p_error.M64ERR_INVALID_STATE.value

        if self.new_surface:
            log.info("VidExtFuncSetMode: Initializing surface")
            self.egl_surface = egl.eglCreateWindowSurface(
                self.egl_display, self.egl_config[0], self.window_handle,
                self.window_attributes)

            self.egl_context = egl.eglCreateContext(self.egl_display,
                                                    self.egl_config[0],
                                                    egl.EGL_NO_CONTEXT,
                                                    self.opengl_version)
            if self.egl_context == egl.EGL_NO_CONTEXT:
                raise RuntimeError('Unable to create context')
            try:
                egl.eglMakeCurrent(self.egl_display, self.egl_surface,
                                   self.egl_surface, self.egl_context)
                egl.eglSwapInterval(self.egl_display, self.swap_control)
                egl.eglSwapBuffers(self.egl_display, self.egl_surface)
                retval = True

            except:
                log.error(
                    f"eglMakeCurrent() returned error: {egl.eglGetError()}")

            self.new_surface = False

        else:
            log.error("VidExtFuncSetMode called before surface has been set")
            return wrp_dt.m64p_error.M64ERR_INVALID_STATE.value

        if retval == True:
            log.debug(f"Vidext: video_set_mode() has reported M64ERR_SUCCESS")
            return wrp_dt.m64p_error.M64ERR_SUCCESS.value
        else:
            log.error(
                f"Vidext: video_set_mode() has reported M64ERR_SYSTEM_FAIL")
            return wrp_dt.m64p_error.M64ERR_SYSTEM_FAIL.value