Hello,

I downloaded and modified the code here
(http://cgit.freedesktop.org/~krh/mesa-demos/tree/src/egl/opengl/eglkms.c?h=gbm-surface),
in order to continuous display in the loop.  But it doesn't work. The
output message is:

EGL_VERSION = 1.4 (DRI2)
1
handle=14, stride=7680
2
handle=17, stride=7680
3
handle=14, stride=7680
4
Segmentation fault

gdb's debug message is:
Program received signal SIGSEGV, Segmentation fault.
gbm_bo_get_handle (bo=0x0) at main/gbm.c:231
231        return bo->handle;

Please point out the errors in my code (attachment), I really don't
know how to use gbm_surface_lock_front_buffer(), drmModeSetCrtc(), and
drmModePageFlip().  I have googled it for many days,  but can not find
a suitable tutorial or examples about this. I really want to run egl
on drm, for it looks so cool !

Many thanks !

Bie Tiwei
/*
 * Copyright © 2011 Kristian Høgsberg
 * Copyright © 2011 Benjamin Franzke
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting documentation, and
 * that the name of the copyright holders not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  The copyright holders make no representations
 * about the suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THIS SOFTWARE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define EGL_EGLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES

#include <gbm.h>
//#include "gl_wrap.h"
#include <GL/gl.h>
#include <GL/glext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <drm.h>
#include <xf86drmMode.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

struct kms {
	drmModeConnector *connector;
	drmModeEncoder *encoder;
	drmModeModeInfo mode;
	uint32_t fb_id;
};

static EGLBoolean setup_kms(int fd, struct kms *kms)
{
	drmModeRes *resources;
	drmModeConnector *connector;
	drmModeEncoder *encoder;
	int i;

	resources = drmModeGetResources(fd);
	if (!resources) {
		fprintf(stderr, "drmModeGetResources failed\n");
		return EGL_FALSE;
	}

	for (i = 0; i < resources->count_connectors; i++) {
		connector = drmModeGetConnector(fd, resources->connectors[i]);
		if (connector == NULL)
			continue;

		if (connector->connection == DRM_MODE_CONNECTED &&
		    connector->count_modes > 0)
			break;

		drmModeFreeConnector(connector);
	}

	if (i == resources->count_connectors) {
		fprintf(stderr, "No currently active connector found.\n");
		return EGL_FALSE;
	}

	for (i = 0; i < resources->count_encoders; i++) {
		encoder = drmModeGetEncoder(fd, resources->encoders[i]);

		if (encoder == NULL)
			continue;

		if (encoder->encoder_id == connector->encoder_id)
			break;

		drmModeFreeEncoder(encoder);
	}

	kms->connector = connector;
	kms->encoder = encoder;
	kms->mode = connector->modes[0];

	return EGL_TRUE;
}

static void render_stuff(int width, int height)
{
	static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
	static const GLfloat verts[3][2] = {
		{-1, -1},
		{1, -1},
		{0, 1}
	};
	static const GLfloat colors[3][3] = {
		{1, 0, 0},
		{0, 1, 0},
		{0, 0, 1}
	};
	GLfloat ar = (GLfloat) width / (GLfloat) height;

	glViewport(0, 0, (GLint) width, (GLint) height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-ar, ar, -1, 1, 5.0, 60.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0, 0.0, -10.0);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.4, 0.4, 0.4, 0.0);

	glPushMatrix();
	glRotatef(view_rotx, 1, 0, 0);
	glRotatef(view_roty, 0, 1, 0);
	glRotatef(view_rotz, 0, 0, 1);
	view_rotz += 1.0;
	printf("%g\n", view_rotz);

	glVertexPointer(2, GL_FLOAT, 0, verts);
	glColorPointer(3, GL_FLOAT, 0, colors);
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);

	glDrawArrays(GL_TRIANGLES, 0, 3);

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);

	glPopMatrix();

	glFinish();
}

static const char device_name[] = "/dev/dri/card0";

static const EGLint attribs[] = {
	EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
	EGL_RED_SIZE, 1,
	EGL_GREEN_SIZE, 1,
	EGL_BLUE_SIZE, 1,
	EGL_ALPHA_SIZE, 0,
	EGL_DEPTH_SIZE, 1,
	EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
	EGL_NONE
};

int main(int argc, char *argv[])
{
	EGLDisplay dpy;
	EGLContext ctx;
	EGLSurface surface;
	EGLConfig config;
	EGLint major, minor, n;
	const char *ver;
	uint32_t handle, stride;
	struct kms kms;
	int ret, fd;
	struct gbm_device *gbm;
	struct gbm_bo *bo;
	struct gbm_surface *gs;

	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_RENDERING);
	surface = eglCreateWindowSurface(dpy, config, gs, NULL);

	if (!eglMakeCurrent(dpy, surface, surface, ctx)) {
		fprintf(stderr, "failed to make context current\n");
		ret = -1;
		goto destroy_context;
	}

	while (true) {
		render_stuff(kms.mode.hdisplay, kms.mode.vdisplay);

		eglSwapBuffers(dpy, surface);

		bo = gbm_surface_lock_front_buffer(gs);
		handle = gbm_bo_get_handle(bo).u32;
		stride = gbm_bo_get_pitch(bo);

		printf("handle=%d, stride=%d\n", handle, stride);

		ret = drmModeAddFB(fd,
				   kms.mode.hdisplay, kms.mode.vdisplay,
				   24, 32, stride, handle, &kms.fb_id);
		if (ret) {
			fprintf(stderr, "failed to create fb\n");
			goto rm_fb;
		}

		ret = drmModeSetCrtc(fd, kms.encoder->crtc_id, kms.fb_id, 0, 0,
				     &kms.connector->connector_id, 1, &kms.mode);
		if (ret) {
			fprintf(stderr, "failed to set mode: %m\n");
			goto rm_fb;
		}

		drmModeRmFB(fd, kms.fb_id);
		gbm_bo_destroy(bo);
	}

rm_fb:
	drmModeRmFB(fd, kms.fb_id);
	gbm_bo_destroy(bo);
	eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
destroy_context:
	eglDestroyContext(dpy, ctx);
egl_terminate:
	eglTerminate(dpy);
destroy_gbm_device:
	gbm_device_destroy(gbm);
close_fd:
	close(fd);

	return ret;
}
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to