How to use gbm_surface_lock_front_buffer() ?

Bie Tiwei <[email protected]>
Newsgroups gmane.comp.video.mesa3d.user
Message-ID <CAFCyVfnSOEtSbcFuPnYaG4dJdtb2gKg36VY3gN2vZ3TWu+JCUA@mail.gmail.com>
I 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 correct the errors in my code, I really don't know how to use
gbm_surface_lock_front_buffer(), drmModeSetCrtc(), and
drmModePageFlip().  I have googled it for many days, and still can not
figure it out.

Many thanks !

_______________________________________________
mesa-users mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-users
gbm.try.c (text/x-csrc, 6.6 KB)
/*
 * 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;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.