SDL_bool KMSDRM_GLES_SetupCrtc(_THIS, SDL_Window * window) { SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata); SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata); KMSDRM_FBInfo *fb_info; if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed on CRTC setup"); return SDL_FALSE; } wdata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); if (wdata->next_bo == NULL) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer on CRTC setup"); return SDL_FALSE; } fb_info = KMSDRM_FBFromBO(_this, wdata->next_bo); if (fb_info == NULL) { return SDL_FALSE; } if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode) != 0) { SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC to a GBM buffer"); return SDL_FALSE; } wdata->crtc_ready = SDL_TRUE; return SDL_TRUE; }
void KMSDRM_VideoQuit(_THIS) { SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata); SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()"); if (_this->gl_config.driver_loaded) { SDL_GL_UnloadLibrary(); } if(vdata->saved_crtc != NULL) { if(vdata->drm_fd > 0 && vdata->saved_conn_id > 0) { /* Restore saved CRTC settings */ drmModeCrtc *crtc = vdata->saved_crtc; if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, &vdata->saved_conn_id, 1, &crtc->mode) != 0) { SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode"); } } KMSDRM_drmModeFreeCrtc(vdata->saved_crtc); vdata->saved_crtc = NULL; } if (vdata->gbm != NULL) { KMSDRM_gbm_device_destroy(vdata->gbm); vdata->gbm = NULL; } if (vdata->drm_fd >= 0) { close(vdata->drm_fd); SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", vdata->drm_fd); vdata->drm_fd = -1; } #ifdef SDL_INPUT_LINUXEV SDL_EVDEV_Quit(); #endif }
int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) { SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata); SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata); KMSDRM_FBInfo *fb_info; int ret; /* Do we still need to wait for a flip? */ int timeout = 0; if (_this->egl_data->egl_swapinterval == 1) { timeout = -1; } if (!KMSDRM_WaitPageFlip(_this, wdata, timeout)) { return 0; } /* Release previously displayed buffer (which is now the backbuffer) and lock a new one */ if (wdata->next_bo != NULL) { KMSDRM_gbm_surface_release_buffer(wdata->gs, wdata->current_bo); /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)wdata->next_bo); */ wdata->current_bo = wdata->next_bo; wdata->next_bo = NULL; } if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed."); return 0; } if (wdata->current_bo == NULL) { wdata->current_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); if (wdata->current_bo == NULL) { return 0; } } wdata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); if (wdata->next_bo == NULL) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer"); return 0; /* } else { SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)wdata->next_bo); */ } fb_info = KMSDRM_FBFromBO(_this, wdata->next_bo); if (fb_info == NULL) { return 0; } if (_this->egl_data->egl_swapinterval == 0) { /* Swap buffers instantly, possible tearing */ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModeSetCrtc(%d, %u, %u, 0, 0, &%u, 1, &%ux%u@%u)", vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, vdata->saved_conn_id, displaydata->cur_mode.hdisplay, displaydata->cur_mode.vdisplay, displaydata->cur_mode.vrefresh); */ ret = KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode); if(ret != 0) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not pageflip with drmModeSetCrtc: %d", ret); } } else { /* Queue page flip at vsync */ /* Have we already setup the CRTC to one of the GBM buffers? Do so if we have not, or FlipPage won't work in some cases. */ if (!wdata->crtc_ready) { if(!KMSDRM_GLES_SetupCrtc(_this, window)) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC for doing vsync-ed pageflips"); return 0; } } /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip)", vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */ ret = KMSDRM_drmModePageFlip(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip); if (ret == 0) { wdata->waiting_for_flip = SDL_TRUE; } else { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret); } } return 0; }