gbm-sdl2-example

changeset 0:665119a0580e tip

example program that uses gbm buffers
author Eleni Maria Stea <eleni@mutantstargoat.com>
date Wed, 04 Jul 2018 22:16:23 +0300
parents
children
files Makefile src/drmtest.cc src/drmtest.h src/test.cc
diffstat 4 files changed, 307 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Makefile	Wed Jul 04 22:16:23 2018 +0300
     1.3 @@ -0,0 +1,21 @@
     1.4 +src = $(wildcard src/*.cc)
     1.5 +obj = $(src:.cc=.o)
     1.6 +dep = $(obj:.o=.d)
     1.7 +bin = test
     1.8 +
     1.9 +dbg = -g
    1.10 +opt = -O0
    1.11 +inc = -Isrc -I/usr/lib/i386-linux-gnu
    1.12 +
    1.13 +CXX = g++
    1.14 +CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc) `sdl2-config --cflags` `pkg-config --cflags libdrm`
    1.15 +LDFLAGS = `sdl2-config --libs` -lGLESv2 -lgbm -lEGL -ldrm -ludev
    1.16 +
    1.17 +$(bin): $(obj)
    1.18 +		  $(CXX) -o $@ $(obj) $(LDFLAGS)
    1.19 +
    1.20 +-include $(dep)
    1.21 +
    1.22 +.PHONY: clean
    1.23 +clean:
    1.24 +	rm -f $(obj) $(bin)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/drmtest.cc	Wed Jul 04 22:16:23 2018 +0300
     2.3 @@ -0,0 +1,131 @@
     2.4 +/*
     2.5 + * Copyright © 2007 Intel Corporation
     2.6 + *
     2.7 + * Permission is hereby granted, free of charge, to any person obtaining a
     2.8 + * copy of this software and associated documentation files (the "Software"),
     2.9 + * to deal in the Software without restriction, including without limitation
    2.10 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    2.11 + * and/or sell copies of the Software, and to permit persons to whom the
    2.12 + * Software is furnished to do so, subject to the following conditions:
    2.13 + *
    2.14 + * The above copyright notice and this permission notice (including the next
    2.15 + * paragraph) shall be included in all copies or substantial portions of the
    2.16 + * Software.
    2.17 + *
    2.18 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    2.19 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    2.20 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    2.21 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    2.22 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    2.23 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    2.24 + * IN THE SOFTWARE.
    2.25 + *
    2.26 + * Authors:
    2.27 + *    Eric Anholt <eric@anholt.net>
    2.28 + *
    2.29 + */
    2.30 +
    2.31 +#include <string.h>
    2.32 +
    2.33 +#include <fcntl.h>
    2.34 +#include <fnmatch.h>
    2.35 +#include <sys/stat.h>
    2.36 +#include <sys/ioctl.h>
    2.37 +#include "drmtest.h"
    2.38 +
    2.39 +#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
    2.40 +#include <libudev.h>
    2.41 +
    2.42 +static int is_master(int fd)
    2.43 +{
    2.44 +	drm_client_t client;
    2.45 +	int ret;
    2.46 +
    2.47 +	/* Check that we're the only opener and authed. */
    2.48 +	client.idx = 0;
    2.49 +	ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
    2.50 +	assert (ret == 0);
    2.51 +	if (!client.auth)
    2.52 +		return 0;
    2.53 +	client.idx = 1;
    2.54 +	ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
    2.55 +	if (ret != -1 || errno != EINVAL)
    2.56 +		return 0;
    2.57 +
    2.58 +	return 1;
    2.59 +}
    2.60 +
    2.61 +/** Open the first DRM device matching the criteria */
    2.62 +int drm_open_matching(const char *pci_glob, int flags)
    2.63 +{
    2.64 +	struct udev *udev;
    2.65 +	struct udev_enumerate *e;
    2.66 +	struct udev_device *device, *parent;
    2.67 +        struct udev_list_entry *entry;
    2.68 +	const char *pci_id, *path;
    2.69 +	int fd;
    2.70 +
    2.71 +	udev = udev_new();
    2.72 +	if (udev == NULL) {
    2.73 +		fprintf(stderr, "failed to initialize udev context\n");
    2.74 +		abort();
    2.75 +	}
    2.76 +
    2.77 +	fd = -1;
    2.78 +	e = udev_enumerate_new(udev);
    2.79 +	udev_enumerate_add_match_subsystem(e, "drm");
    2.80 +        udev_enumerate_scan_devices(e);
    2.81 +        udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
    2.82 +		path = udev_list_entry_get_name(entry);
    2.83 +		device = udev_device_new_from_syspath(udev, path);
    2.84 +		parent = udev_device_get_parent(device);
    2.85 +		/* Filter out KMS output devices. */
    2.86 +		if (strcmp(udev_device_get_subsystem(parent), "pci") != 0)
    2.87 +			continue;
    2.88 +		pci_id = udev_device_get_property_value(parent, "PCI_ID");
    2.89 +		if (fnmatch(pci_glob, pci_id, 0) != 0)
    2.90 +			continue;
    2.91 +		fd = open(udev_device_get_devnode(device), O_RDWR);
    2.92 +		if (fd < 0)
    2.93 +			continue;
    2.94 +		if ((flags & DRM_TEST_MASTER) && !is_master(fd)) {
    2.95 +			close(fd);
    2.96 +			fd = -1;
    2.97 +			continue;
    2.98 +		}
    2.99 +
   2.100 +		break;
   2.101 +	}
   2.102 +        udev_enumerate_unref(e);
   2.103 +	udev_unref(udev);
   2.104 +
   2.105 +	return fd;
   2.106 +}
   2.107 +
   2.108 +int drm_open_any(void)
   2.109 +{
   2.110 +	int fd = drm_open_matching("*:*", 0);
   2.111 +
   2.112 +	if (fd < 0) {
   2.113 +		fprintf(stderr, "failed to open any drm device\n");
   2.114 +		abort();
   2.115 +	}
   2.116 +
   2.117 +	return fd;
   2.118 +}
   2.119 +
   2.120 +/**
   2.121 + * Open the first DRM device we can find where we end up being the master.
   2.122 + */
   2.123 +int drm_open_any_master(void)
   2.124 +{
   2.125 +	int fd = drm_open_matching("*:*", DRM_TEST_MASTER);
   2.126 +
   2.127 +	if (fd < 0) {
   2.128 +		fprintf(stderr, "failed to open any drm device\n");
   2.129 +		abort();
   2.130 +	}
   2.131 +
   2.132 +	return fd;
   2.133 +
   2.134 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/drmtest.h	Wed Jul 04 22:16:23 2018 +0300
     3.3 @@ -0,0 +1,40 @@
     3.4 +/*
     3.5 + * Copyright © 2007 Intel Corporation
     3.6 + *
     3.7 + * Permission is hereby granted, free of charge, to any person obtaining a
     3.8 + * copy of this software and associated documentation files (the "Software"),
     3.9 + * to deal in the Software without restriction, including without limitation
    3.10 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    3.11 + * and/or sell copies of the Software, and to permit persons to whom the
    3.12 + * Software is furnished to do so, subject to the following conditions:
    3.13 + *
    3.14 + * The above copyright notice and this permission notice (including the next
    3.15 + * paragraph) shall be included in all copies or substantial portions of the
    3.16 + * Software.
    3.17 + *
    3.18 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    3.19 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    3.20 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    3.21 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    3.22 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    3.23 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    3.24 + * IN THE SOFTWARE.
    3.25 + *
    3.26 + * Authors:
    3.27 + *    Eric Anholt <eric@anholt.net>
    3.28 + *
    3.29 + */
    3.30 +
    3.31 +#include <stdio.h>
    3.32 +#include <stdlib.h>
    3.33 +#include <unistd.h>
    3.34 +#include <assert.h>
    3.35 +#include <errno.h>
    3.36 +
    3.37 +#include <xf86drm.h>
    3.38 +
    3.39 +#define DRM_TEST_MASTER 0x01
    3.40 +
    3.41 +int drm_open_any(void);
    3.42 +int drm_open_any_master(void);
    3.43 +int drm_open_matching(const char *pci_glob, int flags);
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/test.cc	Wed Jul 04 22:16:23 2018 +0300
     4.3 @@ -0,0 +1,115 @@
     4.4 +#include <errno.h>
     4.5 +#include <stdio.h>
     4.6 +#include <stdlib.h>
     4.7 +#include <string.h>
     4.8 +
     4.9 +#include <SDL2/SDL.h>
    4.10 +#include <GLES2/gl2.h>
    4.11 +#include <EGL/egl.h>
    4.12 +#include <EGL/eglext.h>
    4.13 +#include <EGL/eglplatform.h>
    4.14 +#include <KHR/khrplatform.h>
    4.15 +#include <gbm.h>
    4.16 +
    4.17 +#include <fcntl.h>
    4.18 +#include <fnmatch.h>
    4.19 +#include <sys/stat.h>
    4.20 +#include <stdio.h>
    4.21 +#include <stdlib.h>
    4.22 +#include <unistd.h>
    4.23 +#include <assert.h>
    4.24 +#include <errno.h>
    4.25 +#include <libudev.h>
    4.26 +
    4.27 +#include "drmtest.h"
    4.28 +
    4.29 +int fd = -1;
    4.30 +static struct gbm_device *gbm_dev;
    4.31 +struct gbm_bo *bo;
    4.32 +struct gbm_surface *gbm_surf;
    4.33 +
    4.34 +int main(int argc, char **argv)
    4.35 +{
    4.36 +//	if((fd = open("/dev/dri/card0", O_RDWR) == -1)) {
    4.37 +//		fprintf(stderr, "can't open device: %s\n", strerror(errno));
    4.38 +//		exit(1);
    4.39 +//	}
    4.40 +	if((fd = drm_open_any()) == - 1) {
    4.41 +		fprintf(stderr, "can't open device: %s\n", strerror(errno));
    4.42 +		exit(1);
    4.43 +	}
    4.44 +
    4.45 +	printf("fd: %d\n", fd);
    4.46 +
    4.47 +	if(!(gbm_dev = gbm_create_device(fd))) {
    4.48 +		fprintf(stderr, "can't create gbm device: %s\n", strerror(errno));
    4.49 +		exit(1);
    4.50 +	}
    4.51 +
    4.52 +	if(!(gbm_surf = gbm_surface_create(gbm_dev, 640, 480,  GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING))) {
    4.53 +		fprintf(stderr, "can't create gbm surface: %s\n", strerror(errno));
    4.54 +		exit(1);
    4.55 +	}
    4.56 +
    4.57 +	EGLDisplay dpy;
    4.58 +	dpy = eglGetDisplay((_XDisplay*)gbm_dev);
    4.59 +	EGLint major, minor;
    4.60 +
    4.61 +	//const char *ver;
    4.62 +	const char *extensions;
    4.63 +	eglInitialize(dpy, &major, &minor);
    4.64 +	//ver = eglQueryString(dpy, EGL_VERSION);
    4.65 +	extensions = eglQueryString(dpy, EGL_EXTENSIONS);
    4.66 +
    4.67 +	if (!strstr(extensions, "EGL_KHR_surfaceless_context")) {
    4.68 +		fprintf(stderr, "no surfaceless support, cannot initialize\n");
    4.69 +		exit(1);
    4.70 +	}
    4.71 +
    4.72 +	SDL_Window *win;
    4.73 +	SDL_GLContext ctx;
    4.74 +
    4.75 +	if(SDL_Init(SDL_INIT_VIDEO) == -1) {
    4.76 +		fprintf(stderr, "failed to initialize sdl\n");
    4.77 +		return 1;
    4.78 +	}
    4.79 +
    4.80 +	SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 1);
    4.81 +	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    4.82 +	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
    4.83 +	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    4.84 +	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    4.85 +	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    4.86 +	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    4.87 +	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    4.88 +	//SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
    4.89 +
    4.90 +	if(!(bo = gbm_bo_create(gbm_dev, 640, 480, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING))) {
    4.91 +		fprintf(stderr, "Unable to create gbm buffer object!\n");
    4.92 +	}
    4.93 +
    4.94 +	win = SDL_CreateWindow("foo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480,
    4.95 +			SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    4.96 +
    4.97 +	if(!win) {
    4.98 +		fprintf(stderr, "failed to create window: %s\n", SDL_GetError());
    4.99 +		return 1;
   4.100 +	}
   4.101 +
   4.102 +	if(!(ctx = SDL_GL_CreateContext(win))) {
   4.103 +		fprintf(stderr, "failed to create OpenGL context: %s\n", SDL_GetError());
   4.104 +		return 1;
   4.105 +	}
   4.106 +
   4.107 +	glClearColor(1.0, 0.0, 0.0, 1.0);
   4.108 +	glClear(GL_COLOR_BUFFER_BIT);
   4.109 +
   4.110 +	SDL_GL_SwapWindow(win);
   4.111 +	SDL_Delay(5000);
   4.112 +
   4.113 +	gbm_device_destroy(gbm_dev);
   4.114 +	SDL_GL_DeleteContext(win);
   4.115 +	SDL_DestroyWindow(win);
   4.116 +	SDL_Quit();
   4.117 +	return 0;
   4.118 +}