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;
}