static void gfx_ctx_vc_swap_buffers(void *data, void *data2) { #ifdef HAVE_EGL vc_ctx_data_t *vc = (vc_ctx_data_t*)data; video_frame_info_t *video_info = (video_frame_info_t*)data2; if (!vc) return; egl_swap_buffers(&vc->egl); /* Wait for vsync immediately if we don't * want egl_swap_buffers to triple-buffer */ if (video_info->max_swapchain_images <= 2) { /* We DON'T wait to wait without callback function ready! */ if (!vc->vsync_callback_set) { vc_dispmanx_vsync_callback(vc->dispman_display, dispmanx_vsync_callback, (void*)vc); vc->vsync_callback_set = true; } slock_lock(vc->vsync_condition_mutex); scond_wait(vc->vsync_condition, vc->vsync_condition_mutex); slock_unlock(vc->vsync_condition_mutex); } /* Stop generating vsync callbacks from now on */ else if (vc->vsync_callback_set) vc_dispmanx_vsync_callback(vc->dispman_display, NULL, NULL); #endif }
static void gfx_ctx_drm_swap_buffers(void *data) { gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; settings_t *settings = config_get_ptr(); switch (drm_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL egl_swap_buffers(&drm->egl); #endif break; default: break; } /* I guess we have to wait for flip to have taken * place before another flip can be queued up. * * If true, we are still waiting for a flip * (nonblocking mode, so just drop the frame). */ if (gfx_ctx_drm_wait_flip(drm->interval)) return; waiting_for_flip = gfx_ctx_drm_queue_flip(); /* Triple-buffered page flips */ if (settings->video.max_swapchain_images >= 3 && gbm_surface_has_free_buffers(g_gbm_surface)) return; gfx_ctx_drm_wait_flip(true); }
static void gfx_ctx_wl_swap_buffers(void *data, void *data2) { gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; switch (wl_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL egl_swap_buffers(&wl->egl); #endif break; case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN vulkan_present(&wl->vk, wl->vk.context.current_swapchain_index); vulkan_acquire_next_image(&wl->vk); flush_wayland_fd(&wl->input); #endif break; case GFX_CTX_NONE: default: break; } }
static void gfx_ctx_drm_swap_buffers(void *data) { gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; switch (drm_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL egl_swap_buffers(&drm->egl); #endif break; default: break; } /* I guess we have to wait for flip to have taken * place before another flip can be queued up. * * If true, we are still waiting for a flip * (nonblocking mode, so just drop the frame). */ if (gfx_ctx_drm_wait_flip(drm->interval)) return; waiting_for_flip = gfx_ctx_drm_queue_flip(); if (gbm_surface_has_free_buffers(g_gbm_surface)) return; /* We have to wait for this flip to finish. * This shouldn't happen as we have triple buffered page-flips. */ RARCH_WARN("[KMS]: Triple buffering is not working correctly ...\n"); gfx_ctx_drm_wait_flip(true); }
static void gfx_ctx_opendingux_swap_buffers(void *data, video_frame_info_t *video_info) { opendingux_ctx_data_t *viv = (opendingux_ctx_data_t*)data; #ifdef HAVE_EGL egl_swap_buffers(&viv->egl); #endif }
static void orbis_ctx_swap_buffers(void *data, void *data2) { orbis_ctx_data_t *ctx_orbis = (orbis_ctx_data_t *)data; #ifdef HAVE_EGL egl_swap_buffers(&ctx_orbis->egl); #endif }
static void gfx_ctx_mali_fbdev_swap_buffers(void *data, video_frame_info_t *video_info) { mali_ctx_data_t *mali = (mali_ctx_data_t*)data; #ifdef HAVE_EGL egl_swap_buffers(&mali->egl); #endif }
static void gfx_ctx_mali_fbdev_swap_buffers(void *data, void *data2) { mali_ctx_data_t *mali = (mali_ctx_data_t*)data; #ifdef HAVE_EGL egl_swap_buffers(&mali->egl); #endif }
static void gfx_ctx_vivante_swap_buffers(void *data) { vivante_ctx_data_t *viv = (vivante_ctx_data_t*)data; #ifdef HAVE_EGL egl_swap_buffers(&viv->egl); #endif }
static void gfx_ctx_vc_swap_buffers(void *data) { vc_ctx_data_t *vc = (vc_ctx_data_t*)data; #ifdef HAVE_EGL egl_swap_buffers(&vc->egl); #endif }
static void gfx_ctx_qnx_swap_buffers(void *data, void *data2) { qnx_ctx_data_t *qnx = (qnx_ctx_data_t*)data; #ifdef HAVE_EGL egl_swap_buffers(&qnx->egl); #endif }
static void gfx_ctx_emscripten_swap_buffers(void *data, void *data2) { emscripten_ctx_data_t *emscripten = (emscripten_ctx_data_t*)data; /* doesn't really do anything in WebGL, but it might if we use WebGL workers * in the future */ #ifdef HAVE_EGL egl_swap_buffers(&emscripten->egl); #endif }
static void gfx_ctx_xegl_swap_buffers(void *data) { xegl_ctx_data_t *xegl = (xegl_ctx_data_t*)data; switch (x_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_EGL egl_swap_buffers(&xegl->egl); #endif break; case GFX_CTX_NONE: default: break; } }
static void android_gfx_ctx_swap_buffers(void *data, void *data2) { android_ctx_data_t *and = (android_ctx_data_t*)data; switch (android_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL egl_swap_buffers(&and->egl); #endif break; case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN vulkan_present(&and->vk, and->vk.context.current_swapchain_index); vulkan_acquire_next_image(&and->vk); #endif break; case GFX_CTX_NONE: default: break; } }
static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) { const EGLint *attrib_ptr = NULL; static const EGLint egl_attribs_gl[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE, }; static const EGLint egl_attribs_gles[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE, }; #ifdef EGL_KHR_create_context static const EGLint egl_attribs_gles3[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_NONE, }; #endif #ifdef HAVE_VG static const EGLint egl_attribs_vg[] = { DRM_EGL_ATTRIBS_BASE, EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, EGL_NONE, }; #endif EGLint major; EGLint minor; EGLint n; EGLint egl_attribs[16]; EGLint *egl_attribs_ptr = NULL; EGLint *attr = NULL; switch (drm_api) { case GFX_CTX_OPENGL_API: #ifdef HAVE_OPENGL attrib_ptr = egl_attribs_gl; break; case GFX_CTX_OPENGL_ES_API: #ifdef EGL_KHR_create_context if (drm->egl.major >= 3) attrib_ptr = egl_attribs_gles3; else #endif attrib_ptr = egl_attribs_gles; #endif break; case GFX_CTX_OPENVG_API: #ifdef HAVE_VG attrib_ptr = egl_attribs_vg; #endif break; case GFX_CTX_NONE: default: break; } switch (drm_api) { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: #ifdef HAVE_EGL if (!egl_init_context(&drm->egl, (EGLNativeDisplayType)g_gbm_dev, &major, &minor, &n, attrib_ptr)) goto error; attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); egl_attribs_ptr = &egl_attribs[0]; if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) ? egl_attribs_ptr : NULL)) goto error; if (!egl_create_surface(&drm->egl, (EGLNativeWindowType)g_gbm_surface)) return false; #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) glClear(GL_COLOR_BUFFER_BIT); #endif #endif break; case GFX_CTX_NONE: default: break; } egl_swap_buffers(drm); return true; error: egl_report_error(); return false; }