diff options
author | Rob Clark <robdclark@gmail.com> | 2017-02-21 17:01:16 -0500 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2017-02-22 10:31:02 -0500 |
commit | 1f1158fe1279e845420d3cb838eff3bbf2e5701a (patch) | |
tree | 95fe331b322f1a4d67ed1f1c77b36c0cb8ece71c /drm-legacy.c | |
parent | 3e78eabeeeeb8476583cf2d37f1bd561307694db (diff) | |
download | kmscube-1f1158fe1279e845420d3cb838eff3bbf2e5701a.tar.gz |
split out legacy (pageflip) kms
Preping to add new atomic alternative path.
Diffstat (limited to 'drm-legacy.c')
-rw-r--r-- | drm-legacy.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/drm-legacy.c b/drm-legacy.c new file mode 100644 index 0000000..29d5f3c --- /dev/null +++ b/drm-legacy.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2017 Rob Clark <rclark@redhat.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include "common.h" +#include "drm.h" + +static struct drm drm; + +static void page_flip_handler(int fd, unsigned int frame, + unsigned int sec, unsigned int usec, void *data) +{ + int *waiting_for_flip = data; + *waiting_for_flip = 0; +} + +static int legacy_run(const struct gbm *gbm, const struct egl *egl) +{ + fd_set fds; + drmEventContext evctx = { + .version = DRM_EVENT_CONTEXT_VERSION, + .page_flip_handler = page_flip_handler, + }; + struct gbm_bo *bo; + struct drm_fb *fb; + uint32_t i = 0; + int ret; + + FD_ZERO(&fds); + FD_SET(0, &fds); + FD_SET(drm.fd, &fds); + + eglSwapBuffers(egl->display, egl->surface); + bo = gbm_surface_lock_front_buffer(gbm->surface); + fb = drm_fb_get_from_bo(bo); + + /* set mode: */ + ret = drmModeSetCrtc(drm.fd, drm.crtc_id, fb->fb_id, 0, 0, + &drm.connector_id, 1, drm.mode); + if (ret) { + printf("failed to set mode: %s\n", strerror(errno)); + return ret; + } + + while (1) { + struct gbm_bo *next_bo; + int waiting_for_flip = 1; + + egl->draw(i++); + + eglSwapBuffers(egl->display, egl->surface); + next_bo = gbm_surface_lock_front_buffer(gbm->surface); + fb = drm_fb_get_from_bo(next_bo); + + /* + * Here you could also update drm plane layers if you want + * hw composition + */ + + ret = drmModePageFlip(drm.fd, drm.crtc_id, fb->fb_id, + DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip); + if (ret) { + printf("failed to queue page flip: %s\n", strerror(errno)); + return -1; + } + + while (waiting_for_flip) { + ret = select(drm.fd + 1, &fds, NULL, NULL, NULL); + if (ret < 0) { + printf("select err: %s\n", strerror(errno)); + return ret; + } else if (ret == 0) { + printf("select timeout!\n"); + return -1; + } else if (FD_ISSET(0, &fds)) { + printf("user interrupted!\n"); + break; + } + drmHandleEvent(drm.fd, &evctx); + } + + /* release last buffer to render on again: */ + gbm_surface_release_buffer(gbm->surface, bo); + bo = next_bo; + } + + return 0; +} + +const struct drm * init_drm_legacy(const char *device) +{ + int ret; + + ret = init_drm(&drm, device); + if (ret) + return NULL; + + drm.run = legacy_run; + + return &drm; +} |