static void gfx_ctx_drm_egl_swap_buffers(void *data) { gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*) driver.video_context_data; (void)data; eglSwapBuffers(drm->g_egl_dpy, drm->g_egl_surf); /* I guess we have to wait for flip to have taken * place before another flip can be queued up. */ if (waiting_for_flip) { wait_flip(drm->g_interval); /* We are still waiting for a flip * (nonblocking mode, just drop the frame). */ if (waiting_for_flip) return; } queue_flip(); /* We have to wait for this flip to finish. * This shouldn't happen as we have triple buffered page-flips. */ if (!gbm_surface_has_free_buffers(drm->g_gbm_surface)) { RARCH_WARN("[KMS/EGL]: Triple buffering is not working correctly ...\n"); wait_flip(true); } }
static void gfx_ctx_drm_egl_destroy_resources(gfx_ctx_drm_egl_data_t *drm) { if (!drm) return; /* Make sure we acknowledge all page-flips. */ if (waiting_for_flip) wait_flip(true); if (drm->g_egl_dpy) { if (drm->g_egl_ctx) { eglMakeCurrent(drm->g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(drm->g_egl_dpy, drm->g_egl_ctx); } if (drm->g_egl_hw_ctx) eglDestroyContext(drm->g_egl_dpy, drm->g_egl_hw_ctx); if (drm->g_egl_surf) eglDestroySurface(drm->g_egl_dpy, drm->g_egl_surf); eglTerminate(drm->g_egl_dpy); } /* Be as careful as possible in deinit. * If we screw up, the KMS tty will not restore. */ drm->g_egl_ctx = NULL; drm->g_egl_hw_ctx = NULL; drm->g_egl_surf = NULL; drm->g_egl_dpy = NULL; drm->g_config = 0; /* Restore original CRTC. */ if (drm->g_orig_crtc) { drmModeSetCrtc(drm->g_drm_fd, drm->g_orig_crtc->crtc_id, drm->g_orig_crtc->buffer_id, drm->g_orig_crtc->x, drm->g_orig_crtc->y, &drm->g_connector_id, 1, &drm->g_orig_crtc->mode); } free_drm_resources(drm); drm->g_drm_mode = NULL; g_quit = 0; drm->g_crtc_id = 0; drm->g_connector_id = 0; drm->g_fb_width = 0; drm->g_fb_height = 0; drm->g_bo = NULL; drm->g_next_bo = NULL; }
static void gfx_ctx_drm_egl_destroy(void *data) { (void)data; // Make sure we acknowledge all page-flips. if (waiting_for_flip) wait_flip(true); if (g_egl_dpy) { if (g_egl_ctx) { eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(g_egl_dpy, g_egl_ctx); } if (g_egl_hw_ctx) eglDestroyContext(g_egl_dpy, g_egl_hw_ctx); if (g_egl_surf) eglDestroySurface(g_egl_dpy, g_egl_surf); eglTerminate(g_egl_dpy); } // Be as careful as possible in deinit. // If we screw up, the KMS tty will not restore. g_egl_ctx = NULL; g_egl_hw_ctx = NULL; g_egl_surf = NULL; g_egl_dpy = NULL; g_config = 0; // Restore original CRTC. if (g_orig_crtc) { drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id, g_orig_crtc->buffer_id, g_orig_crtc->x, g_orig_crtc->y, &g_connector_id, 1, &g_orig_crtc->mode); } free_drm_resources(); g_drm_mode = NULL; g_quit = 0; g_crtc_id = 0; g_connector_id = 0; g_fb_width = 0; g_fb_height = 0; g_bo = NULL; g_next_bo = NULL; g_inited = false; }
static int exynos_flip(struct hook_data *data, struct exynos_page *page) { /* We don't queue multiple page flips. */ if (data->pageflip_pending > 0) { wait_flip(data->fliphandler); } /* Issue a page flip at the next vblank interval. */ if (drmModePageFlip(data->drm_fd, data->drm->crtc_id, page->buf_id, DRM_MODE_PAGE_FLIP_EVENT, page)) { fprintf(stderr, "[exynos_flip] error: failed to issue page flip\n"); return -1; } else { data->pageflip_pending++; } /* On startup no frame is displayed. We therefore wait for the initial flip to finish. */ if (data->cur_page == NULL) wait_flip(data->fliphandler); return 0; }
static void gfx_ctx_swap_buffers(void) { eglSwapBuffers(g_egl_dpy, g_egl_surf); // I guess we have to wait for flip to have taken place before another flip can be queued up. if (waiting_for_flip) { wait_flip(g_interval); if (waiting_for_flip) // We are still waiting for a flip (nonblocking mode, just drop the frame). return; } queue_flip(); // We have to wait for this flip to finish. This shouldn't happen as we have triple buffered page-flips. if (!gbm_surface_has_free_buffers(g_gbm_surface)) { RARCH_WARN("[KMS/EGL]: Triple buffering is not working correctly ...\n"); wait_flip(true); } }
void gfx_ctx_destroy(void) { // Make sure we acknowledge all page-flips. if (waiting_for_flip) wait_flip(true); if (g_egl_dpy) { if (g_egl_ctx) { eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(g_egl_dpy, g_egl_ctx); } if (g_egl_surf) eglDestroySurface(g_egl_dpy, g_egl_surf); eglTerminate(g_egl_dpy); } // Be as careful as possible in deinit. // If we screw up, the KMS tty will not restore. g_egl_ctx = NULL; g_egl_surf = NULL; g_egl_dpy = NULL; g_config = 0; // Restore original CRTC. if (g_orig_crtc) { drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id, g_orig_crtc->buffer_id, g_orig_crtc->x, g_orig_crtc->y, &g_connector_id, 1, &g_orig_crtc->mode); drmModeFreeCrtc(g_orig_crtc); } if (g_gbm_surface) gbm_surface_destroy(g_gbm_surface); if (g_gbm_dev) gbm_device_destroy(g_gbm_dev); if (g_encoder) drmModeFreeEncoder(g_encoder); if (g_connector) drmModeFreeConnector(g_connector); if (g_resources) drmModeFreeResources(g_resources); g_gbm_surface = NULL; g_gbm_dev = NULL; g_encoder = NULL; g_connector = NULL; g_resources = NULL; g_orig_crtc = NULL; g_drm_mode = NULL; g_quit = 0; g_crtc_id = 0; g_connector_id = 0; g_fb_width = 0; g_fb_height = 0; g_bo = NULL; g_next_bo = NULL; if (g_drm_fd >= 0) close(g_drm_fd); g_drm_fd = -1; unsigned frames = last_page_flip - first_page_flip; if (frames) { uint64_t usec = last_usec - first_usec; RARCH_WARN("[KMS/EGL]: Estimated monitor FPS: %.5f Hz\n", 1000000.0 * frames / usec); } RARCH_WARN("[KMS/EGL]: Performance stats: Missed VBlanks: %u, Perfect VBlanks: %u\n", missed_vblanks, hit_vblanks); g_inited = false; }
void gfx_ctx_destroy(void) { // Make sure we acknowledge all page-flips. if (waiting_for_flip) wait_flip(true); if (g_egl_dpy) { if (g_egl_ctx) { eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(g_egl_dpy, g_egl_ctx); } if (g_egl_surf) eglDestroySurface(g_egl_dpy, g_egl_surf); eglTerminate(g_egl_dpy); } // Be as careful as possible in deinit. // If we screw up, the KMS tty will not restore. g_egl_ctx = NULL; g_egl_surf = NULL; g_egl_dpy = NULL; g_config = 0; // Restore original CRTC. if (g_orig_crtc) { drmModeSetCrtc(g_drm_fd, g_orig_crtc->crtc_id, g_orig_crtc->buffer_id, g_orig_crtc->x, g_orig_crtc->y, &g_connector_id, 1, &g_orig_crtc->mode); drmModeFreeCrtc(g_orig_crtc); } if (g_gbm_surface) gbm_surface_destroy(g_gbm_surface); if (g_gbm_dev) gbm_device_destroy(g_gbm_dev); if (g_encoder) drmModeFreeEncoder(g_encoder); if (g_connector) drmModeFreeConnector(g_connector); if (g_resources) drmModeFreeResources(g_resources); g_gbm_surface = NULL; g_gbm_dev = NULL; g_encoder = NULL; g_connector = NULL; g_resources = NULL; g_orig_crtc = NULL; g_drm_mode = NULL; g_quit = 0; g_crtc_id = 0; g_connector_id = 0; g_fb_width = 0; g_fb_height = 0; g_bo = NULL; g_next_bo = NULL; if (g_drm_fd >= 0) close(g_drm_fd); g_drm_fd = -1; g_inited = false; }