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_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_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); }
void CDRMLegacy::FlipPage(CGLContextEGL *pGLContext) { if(WaitingForFlip()) { return; } flip_happening = QueueFlip(); if(g_Windowing.NoOfBuffers() >= 3 && gbm_surface_has_free_buffers(m_gbm->surface)) { return; } WaitingForFlip(); }
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); } }
int main(int argc, char *argv[]) { EGLDisplay dpy; EGLContext ctx; EGLConfig config; EGLSurface surface; EGLint major, minor, n; const char *ver; uint32_t handle, stride; int ret, fd, frames = 0; struct gbm_device *gbm; drmModeCrtcPtr saved_crtc; time_t start, end; char *data; char j; int i; int once; once = 0; signal (SIGINT, quit_handler); fd = open(device_name, O_RDWR); if (fd < 0) { /* Probably permissions error */ fprintf(stderr, "couldn't open %s, skipping\n", device_name); return -1; } gbm = gbm_create_device(fd); if (gbm == NULL) { fprintf(stderr, "couldn't create gbm device\n"); ret = -1; goto close_fd; } dpy = eglGetDisplay(gbm); if (dpy == EGL_NO_DISPLAY) { fprintf(stderr, "eglGetDisplay() failed\n"); ret = -1; goto destroy_gbm_device; } if (!eglInitialize(dpy, &major, &minor)) { printf("eglInitialize() failed\n"); ret = -1; goto egl_terminate; } ver = eglQueryString(dpy, EGL_VERSION); printf("EGL_VERSION = %s\n", ver); if (!setup_kms(fd, &kms)) { ret = -1; goto egl_terminate; } eglBindAPI(EGL_OPENGL_API); if (!eglChooseConfig(dpy, attribs, &config, 1, &n) || n != 1) { fprintf(stderr, "failed to choose argb config\n"); goto egl_terminate; } ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL); if (ctx == NULL) { fprintf(stderr, "failed to create context\n"); ret = -1; goto egl_terminate; } gs = gbm_surface_create(gbm, kms.mode.hdisplay, kms.mode.vdisplay, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (gs == NULL) { fprintf(stderr, "unable to create gbm surface\n"); ret = -1; goto egl_terminate; } surface = eglCreateWindowSurface(dpy, config, gs, NULL); if (surface == EGL_NO_SURFACE) { fprintf(stderr, "failed to create surface\n"); ret = -1; goto destroy_gbm_surface; } if (!eglMakeCurrent(dpy, surface, surface, ctx)) { fprintf(stderr, "failed to make context current\n"); ret = -1; goto destroy_surface; } saved_crtc = drmModeGetCrtc(fd, kms.crtc_id); if (saved_crtc == NULL) { fprintf(stderr, "no valid graphic configuration active (VT ?)\n"); } time(&start); do { drmEventContext evctx; fd_set rfds; render_stuff(kms.mode.hdisplay, kms.mode.vdisplay); eglSwapBuffers(dpy, surface); if (!gbm_surface_has_free_buffers(gs)) fprintf(stderr, "out of free buffers\n"); next_bo = gbm_surface_lock_front_buffer(gs); if (!next_bo) fprintf(stderr, "failed to lock front buffer: %m\n"); handle = gbm_bo_get_handle(next_bo).u32; stride = gbm_bo_get_stride(next_bo); ret = drmModeAddFB(fd, kms.mode.hdisplay, kms.mode.vdisplay, 24, 32, stride, handle, &next_fb_id); if (ret) { fprintf(stderr, "failed to create fb\n"); goto out; } /* make sure to setup crtc once (fix for broken drivers) */ if(once == 0){ once = 1; drmModeSetCrtc(fd, kms.crtc_id, next_fb_id, 0, 0, &kms.connector->connector_id, 1, &kms.mode); } ret = drmModePageFlip(fd, kms.crtc_id, next_fb_id, DRM_MODE_PAGE_FLIP_EVENT, 0); if (ret) { fprintf(stderr, "failed to page flip: %m\n"); goto out; } FD_ZERO(&rfds); FD_SET(fd, &rfds); while (select(fd + 1, &rfds, NULL, NULL, NULL) == -1) NULL; memset(&evctx, 0, sizeof evctx); evctx.version = DRM_EVENT_CONTEXT_VERSION; evctx.page_flip_handler = page_flip_handler; drmHandleEvent(fd, &evctx); frames++; } while (!quit); time(&end); printf("Frames per second: %.2lf\n", frames / difftime(end, start)); out: if(saved_crtc){ drmModeSetCrtc(fd, saved_crtc->crtc_id, saved_crtc->buffer_id, saved_crtc->x, saved_crtc->y, &kms.connector->connector_id, 1, &saved_crtc->mode); } drmModeFreeCrtc(saved_crtc); if (current_fb_id) drmModeRmFB(fd, current_fb_id); if (next_fb_id) drmModeRmFB(fd, next_fb_id); eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); destroy_context: eglDestroyContext(dpy, ctx); destroy_surface: eglDestroySurface(dpy, surface); destroy_gbm_surface: gbm_surface_destroy(gs); egl_terminate: eglTerminate(dpy); destroy_gbm_device: gbm_device_destroy(gbm); close_fd: close(fd); return ret; }