void Platform_VSync ( void );
uint32_t Platform_GetTicks ( void );
+static void drm_do_swap(void);
+
/** @brief Release all EGL and system resources
*/
void EGL_Close( void )
}
peglSwapBuffers( eglDisplay, eglSurface );
+ drm_do_swap();
if (eglSettings[CFG_FPS] != 0) {
fpsCount++;
return 0;
}
+#if 0
+
/** @brief Obtain a reference to the system's native display
* @param window : pointer to save the display reference
* @return : 0 if the function passed, else 1
return 0;
}
+#else
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <gbm.h>
+#include <errno.h>
+
+static struct {
+ struct gbm_device *dev;
+ struct gbm_surface *surface;
+} gbm;
+
+static struct {
+ int fd;
+ uint32_t crtc_id;
+ uint32_t connector_id;
+ //struct gbm_bo *bo;
+} drm;
+
+int8_t GetNativeDisplay( void )
+{
+ drmModeRes *resources;
+ drmModeConnector *connector;
+ drmModeEncoder *encoder;
+ drmModeCrtc *crtc;
+ int i;
+
+ errno = 0;
+
+ /* init drm */
+ drm.fd = drmOpen("omapdrm", NULL);
+ if (drm.fd < 0) {
+ perror("DRM: drmOpen omapdrm");
+ exit(1);
+ }
+
+ resources = drmModeGetResources(drm.fd);
+ if (resources == NULL) {
+ perror("DRM: drmModeGetResources");
+ exit(1);
+ }
+
+ /* find a connected connector: */
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = drmModeGetConnector(drm.fd, resources->connectors[i]);
+ if (connector->connection == DRM_MODE_CONNECTED)
+ break;
+ drmModeFreeConnector(connector);
+ connector = NULL;
+ }
+
+ if (connector == NULL) {
+ fprintf(stderr, "DRM: no connected connector\n");
+ exit(1);
+ }
+
+ encoder = drmModeGetEncoder(drm.fd, connector->encoder_id);
+ if (encoder == NULL) {
+ fprintf(stderr, "DRM: drmModeGetEncoder failed\n");
+ exit(1);
+ }
+
+ crtc = drmModeGetCrtc(drm.fd, encoder->crtc_id);
+ if (crtc == NULL) {
+ fprintf(stderr, "DRM: drmModeGetCrtc failed\n");
+ exit(1);
+ }
+
+ drm.crtc_id = encoder->crtc_id;
+ drm.connector_id = connector->connector_id;
+
+ /* init gbm */
+ gbm.dev = gbm_create_device(drm.fd);
+ if (gbm.dev == NULL) {
+ fprintf(stderr, "DRM: gbm_create_device failed\n");
+ exit(1);
+ }
+
+ gbm.surface = gbm_surface_create(gbm.dev,
+ crtc->width, crtc->height,
+ GBM_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ if (!gbm.surface) {
+ fprintf(stderr, "DRM: failed to create gbm surface\n");
+ exit(1);
+ }
+
+ nativeDisplay = (EGLNativeDisplayType)gbm.dev;
+ nativeWindow = (NativeWindowType)gbm.surface;
+
+#if 0
+ drm.bo = gbm_surface_lock_front_buffer(gbm.surface);
+ if (drm.bo == NULL) {
+ fprintf(stderr, "DRM: no initial bo?\n");
+ exit(1);
+ }
+#endif
+
+ //ret = drmModeSetCrtc(drm.fd, drm.crtc_id, fb->fb_id, 0, 0,
+ // &drm.connector_id, 1, drm.mode);
+
+ return 0;
+}
+
+int8_t GetNativeWindow( uint16_t width, uint16_t height )
+{
+ /* already have nativeWindow, ignore width, height */
+ return 0;
+}
+
+static void
+drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
+{
+ uint32_t fb_id = (uint32_t)(long)data;
+
+ if (fb_id)
+ drmModeRmFB(drm.fd, fb_id);
+}
+
+static uint32_t drm_fb_get_from_bo(struct gbm_bo *bo)
+{
+ uint32_t fb_id = (uint32_t)(long)gbm_bo_get_user_data(bo);
+ uint32_t width, height, stride, handle;
+ int ret;
+
+ if (fb_id)
+ return fb_id;
+
+ width = gbm_bo_get_width(bo);
+ height = gbm_bo_get_height(bo);
+ stride = gbm_bo_get_stride(bo);
+ handle = gbm_bo_get_handle(bo).u32;
+
+ ret = drmModeAddFB(drm.fd, width, height, 24, 32, stride, handle, &fb_id);
+ if (ret) {
+ printf("failed to create fb: %s\n", strerror(errno));
+ return 0;
+ }
+
+ gbm_bo_set_user_data(bo, (void *)(long)fb_id, drm_fb_destroy_callback);
+
+ return fb_id;
+}
+
+static void page_flip_handler(int fd, unsigned int frame,
+ unsigned int sec, unsigned int usec, void *data)
+{
+ int *waiting_for_flip = (int *)data;
+ *waiting_for_flip = 0;
+}
+
+/* to be called after eglSwapBuffers */
+static void drm_do_swap(void)
+{
+ drmEventContext evctx = { 0, };
+ int waiting_for_flip = 1;
+ struct gbm_bo *bo;
+ uint32_t fb_id;
+ fd_set fds;
+ int ret;
+
+ bo = gbm_surface_lock_front_buffer(gbm.surface);
+ fb_id = drm_fb_get_from_bo(bo);
+
+ ret = drmModePageFlip(drm.fd, drm.crtc_id, fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip);
+ if (ret)
+ fprintf(stderr, "page flip error: %d %d\n", ret, errno);
+
+ FD_ZERO(&fds);
+ //FD_SET(0, &fds);
+ FD_SET(drm.fd, &fds);
+
+ evctx.version = DRM_EVENT_CONTEXT_VERSION;
+ evctx.page_flip_handler = page_flip_handler;
+
+ while (waiting_for_flip) {
+ ret = select(drm.fd + 1, &fds, NULL, NULL, NULL);
+ if (ret <= 0) {
+ perror("select");
+ return;
+#if 0
+ } else if (FD_ISSET(0, &fds)) {
+ printf("user interrupted!\n");
+ exit(1); // ?
+#endif
+ }
+ drmHandleEvent(drm.fd, &evctx);
+ }
+
+ gbm_surface_release_buffer(gbm.surface, bo);
+}
+
+#endif
+
/** @brief Release the system's native display
*/
void FreeNativeDisplay( void )
#endif
return ticks;
}
+
+// vim:ts=4:sw=4:expandtab