summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2008-11-25 00:09:33 -0500
committerKristian Høgsberg <krh@redhat.com>2008-11-25 00:12:56 -0500
commitafd39ddf0bd41c80e997cee46e6239bbe044ee2a (patch)
treee122997c73e9370068c827967b61a5c191037838
parentbf75ddbcc58a18068717572c5ffcbb117901cae5 (diff)
Always require user to pass in GEM handle for front.
This pushes the responsibility for figuring out the GEM handle for the front buffer to the client and avoids making the full screen surface a special case.
-rw-r--r--eagle-internal.h3
-rw-r--r--eagle.c22
-rw-r--r--eagle.h2
-rw-r--r--intel.c202
-rw-r--r--test.c75
-rw-r--r--x11-dri2.c10
6 files changed, 159 insertions, 155 deletions
diff --git a/eagle-internal.h b/eagle-internal.h
index e9e29dd..c16af96 100644
--- a/eagle-internal.h
+++ b/eagle-internal.h
@@ -73,6 +73,7 @@ struct EagleBackend {
};
int eglInitDisplay(EGLDisplay display, const char *device, const char *driver);
-void eglInitSurface(EGLSurface surface, EGLDisplay display, EGLConfig fbconfig);
+void eglInitSurface(EGLSurface surface, EGLDisplay display, EGLConfig fbconfig,
+ int width, int height);
#endif
diff --git a/eagle.c b/eagle.c
index 4630caa..ea4b841 100644
--- a/eagle.c
+++ b/eagle.c
@@ -185,6 +185,12 @@ eglInitDisplay(EGLDisplay display, const char *device, const char *driver)
return -1;
}
+int
+eglGetDisplayFD(EGLDisplay display)
+{
+ return display->fd;
+}
+
EGLBoolean
eglInitialize(EGLDisplay display, EGLint *major, EGLint *minor)
{
@@ -332,9 +338,12 @@ eglGetConfigAttrib(EGLDisplay display, EGLConfig config,
*value = EGL_LUMINANCE_BUFFER;
break;
case EGL_CONFIG_CAVEAT:
- *value = EGL_NONE;
- *value = EGL_SLOW_CONFIG;
- *value = EGL_NON_CONFORMANT_CONFIG;
+ if (dri_value & __DRI_ATTRIB_SLOW_BIT)
+ *value = EGL_SLOW_CONFIG;
+ else if (dri_value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
+ *value = EGL_NON_CONFORMANT_CONFIG;
+ else
+ *value = EGL_NONE;
break;
case EGL_TRANSPARENT_TYPE:
*value = EGL_NONE;
@@ -350,12 +359,13 @@ eglGetConfigAttrib(EGLDisplay display, EGLConfig config,
void
eglInitSurface(EGLSurface surface,
- EGLDisplay display, EGLConfig fbconfig)
+ EGLDisplay display, EGLConfig fbconfig, int width, int height)
{
surface->display = display;
surface->id = display->next_surface_id++;
- surface->width = 0;
- surface->height = 0;
+ surface->width = width;
+ surface->height = height;
+ surface->count = 0;
surface->driDrawable =
display->dri2->createNewDrawable(display->driScreen,
diff --git a/eagle.h b/eagle.h
index bd2f2a9..d65c26b 100644
--- a/eagle.h
+++ b/eagle.h
@@ -174,6 +174,8 @@ extern EGLSurface eglCreateSurfaceNative(EGLDisplay display,
EGLConfig config,
int x, int y, int width, int height);
+extern int eglGetDisplayFD(EGLDisplay display);
+
#ifdef _XLIB_H_ /* Hm, this is hack-ish, I guess we need eagle-x11.h */
extern EGLDisplay eglCreateDisplayX11(Display *display, Window root);
diff --git a/intel.c b/intel.c
index 709a16f..f9adb83 100644
--- a/intel.c
+++ b/intel.c
@@ -7,9 +7,6 @@
#include <fcntl.h>
#include <unistd.h>
#include <i915_drm.h>
-#include <drm_mode.h>
-#include <xf86drmMode.h>
-#include <linux/fb.h>
#include <GL/gl.h> /* dri_interface.h uses some GL integer types... */
#include "eagle-internal.h"
@@ -20,22 +17,17 @@ struct EGLDisplayNative {
struct EGLDisplay base;
#ifdef __DRI_COPY_BUFFER
- __DRIbuffer front;
__DRIcopyBufferExtension *copyBuffer;
#endif
-
- unsigned int stride;
- unsigned int width;
- unsigned int height;
- void *fb;
};
typedef struct EGLSurfaceNative *EGLSurfaceNative;
struct EGLSurfaceNative {
struct EGLSurface base;
uint32_t handles[10];
- int x, y, width, height;
- uint32_t name, stride;
+ EGLBoolean backBuffer;
+ __DRIbuffer front;
+ uint32_t frontHandle;
};
static inline uint32_t
@@ -55,9 +47,7 @@ nativeGetBuffers(EGLSurface surface, unsigned int *attachments, int count)
uint32_t size;
int fd, i, ret;
- if (nativeSurface->width == surface->width &&
- nativeSurface->height == surface->height &&
- count == surface->count)
+ if (count == surface->count)
return;
for (i = 0; i < count; i++) {
@@ -66,14 +56,15 @@ nativeGetBuffers(EGLSurface surface, unsigned int *attachments, int count)
buffer = &surface->buffers[i];
buffer->attachment = attachments[i];
- buffer->pitch = align_to(nativeSurface->width * 4,
+ buffer->pitch = align_to(surface->width * 4,
INTEL_STRIDE_ALIGNMENT);
buffer->cpp = 4;
if (buffer->attachment == __DRI_BUFFER_FRONT_LEFT &&
- nativeSurface->name != ~0) {
- buffer->name = nativeSurface->name;
- buffer->pitch = nativeSurface->stride;
+ nativeSurface->front.name != ~0 &&
+ !nativeSurface->backBuffer) {
+ buffer->name = nativeSurface->front.name;
+ buffer->pitch = nativeSurface->front.pitch;
open_arg.name = buffer->name;
ret = ioctl(surface->display->fd,
DRM_IOCTL_GEM_OPEN, &open_arg);
@@ -88,7 +79,7 @@ nativeGetBuffers(EGLSurface surface, unsigned int *attachments, int count)
continue;
}
- size = buffer->pitch * nativeSurface->height;
+ size = buffer->pitch * surface->height;
fd = surface->display->fd;
create.size = size;
if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) {
@@ -106,8 +97,6 @@ nativeGetBuffers(EGLSurface surface, unsigned int *attachments, int count)
buffer->name = flink.name;
}
- surface->width = nativeSurface->width;
- surface->height = nativeSurface->height;
surface->count = count;
}
@@ -125,17 +114,21 @@ static EGLBoolean
nativeDRISwapBuffers(EGLDisplay display, EGLSurface surface)
{
EGLDisplayNative nativeDisplay = (EGLDisplayNative) display;
+ EGLSurfaceNative nativeSurface = (EGLSurfaceNative) surface;
EGLContext context;
- __DRIbuffer *buffer;
+ __DRIbuffer *back;
+
+ if (!nativeSurface->backBuffer)
+ return EGL_TRUE;
context = eglGetCurrentContext();
- buffer = &surface->buffers[0];
+ back = &surface->buffers[0];
nativeDisplay->copyBuffer->copyBuffer(context->driContext,
- &nativeDisplay->front,
+ &nativeSurface->front,
0, 0,
- buffer,
+ back,
0, 0,
surface->width,
surface->height);
@@ -156,10 +149,6 @@ nativeInitDRICopyBuffer(EGLDisplay display)
{
EGLDisplayNative nativeDisplay = (EGLDisplayNative) display;
const __DRIextension **extensions;
- drmModeResPtr mode_res;
- drmModeCrtcPtr crtc;
- drmModeFBPtr fb;
- struct drm_gem_flink flink;
int i;
extensions = display->core->getExtensions(display->driScreen);
@@ -177,38 +166,6 @@ nativeInitDRICopyBuffer(EGLDisplay display)
if (nativeDisplay->copyBuffer == NULL)
return;
- mode_res = drmModeGetResources(display->fd);
- if (mode_res == NULL) {
- fprintf(stderr, "drmModeGetResources returns NULL\n");
- return;
- }
-
- crtc = drmModeGetCrtc(display->fd, mode_res->crtcs[1]);
- if (crtc == NULL) {
- fprintf(stderr, "drmModeGetCrtc returns NULL\n");
- return;
- }
-
- fb = drmModeGetFB(display->fd, crtc->buffer_id);
- if (fb == NULL) {
- fprintf(stderr, "drmModeGetFB returns NULL\n");
- return;
- }
-
- flink.handle = fb->handle;
- if (ioctl(display->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
- fprintf(stderr, "failed to create buffer\n");
- return;
- }
-
- nativeDisplay->front.attachment = __DRI_BUFFER_FRONT_LEFT;
- nativeDisplay->front.name = flink.name;
- nativeDisplay->front.cpp = fb->bpp / 8;
- nativeDisplay->front.pitch = fb->pitch;
- nativeDisplay->front.flags = 0;
-
- display->width = fb->width;
- display->height = fb->height;
display->backend = &nativeDRIBackend;
printf("Using DRI CopyBuffer swapbuffer\n");
@@ -219,18 +176,21 @@ nativeInitDRICopyBuffer(EGLDisplay display)
static EGLBoolean
nativeMemcpySwapBuffers(EGLDisplay display, EGLSurface surface)
{
- EGLDisplayNative nativeDisplay = (EGLDisplayNative) display;
EGLSurfaceNative nativeSurface = (EGLSurfaceNative) surface;
struct drm_i915_gem_pread pread;
- char *data, *dst;
- int i, stride, x, y;
+ struct drm_i915_gem_pwrite pwrite;
+ char *data;
+ int stride, i;
+
+ if (!nativeSurface->backBuffer)
+ return EGL_TRUE;
stride = surface->buffers[0].pitch;
pread.handle = nativeSurface->handles[0];
pread.pad = 0;
pread.offset = 0;
- pread.size = stride * nativeSurface->height;
+ pread.size = stride * surface->height;
data = malloc(pread.size);
if (data == NULL) {
@@ -245,12 +205,29 @@ nativeMemcpySwapBuffers(EGLDisplay display, EGLSurface surface)
return EGL_FALSE;
}
- x = nativeSurface->x;
- y = nativeSurface->y;
- dst = nativeDisplay->fb + nativeDisplay->stride * y + x * 4;
- for (i = 0; i < nativeSurface->height; i++)
- memcpy(dst + nativeDisplay->stride * i,
- data + stride * i, nativeSurface->width * 4);
+ if (nativeSurface->frontHandle == 0) {
+ struct drm_gem_open open_arg;
+
+ open_arg.name = nativeSurface->front.name;
+ if (ioctl(display->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
+ fprintf(stderr, "failed to gem_open back buffer\n");
+ return EGL_FALSE;
+ }
+
+ nativeSurface->frontHandle = open_arg.handle;
+ }
+
+
+ for (i = 0; i < surface->height; i++) {
+ pwrite.handle = nativeSurface->frontHandle;
+ pwrite.offset = nativeSurface->front.pitch * i;
+ pwrite.size = surface->width * 4;
+ pwrite.data_ptr = (intptr_t) data + i * stride;
+ if (ioctl(display->fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite)) {
+ fprintf(stderr, "gem pread failed\n");
+ return EGL_FALSE;
+ }
+ }
free(data);
@@ -268,43 +245,7 @@ static const char fb_device[] = "/dev/fb";
static void
nativeInitMemcpy(EGLDisplay display)
{
- EGLDisplayNative nativeDisplay = (EGLDisplayNative) display;
- struct fb_fix_screeninfo fix;
- struct fb_var_screeninfo var;
- int fd;
-
- fd = open(fb_device, O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "failed to open %s\n", fb_device);
- return;
- }
-
- if (ioctl(fd, FBIOGET_FSCREENINFO, &fix) < 0) {
- fprintf(stderr, "fb get fixed failed\n");
- return;
- }
-
- if (ioctl(fd, FBIOGET_VSCREENINFO, &var) < 0) {
- fprintf(stderr, "fb get fixed failed\n");
- return;
- }
-
- nativeDisplay->stride = fix.line_length;
- nativeDisplay->width = var.xres;
- nativeDisplay->height = var.yres;
- nativeDisplay->fb = mmap(NULL, nativeDisplay->stride * nativeDisplay->height,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-
- close(fd);
-
- if (nativeDisplay->fb == MAP_FAILED) {
- fprintf(stderr, "fb map failed\n");
- return;
- }
-
display->backend = &intelMemcpyBackend;
- display->width = nativeDisplay->width;
- display->height = nativeDisplay->height;
printf("Using memcpy swapbuffer\n");
}
@@ -334,46 +275,33 @@ eglCreateDisplayNative(const char *device, const char *driver)
}
EGLSurface
-eglCreateSurfaceNative(EGLDisplay display, EGLConfig config,
- int x, int y, int width, int height)
-{
- EGLSurfaceNative nativeSurface;
-
- nativeSurface = malloc(sizeof *nativeSurface);
- if (nativeSurface == NULL)
- return NULL;
-
- nativeSurface->x = x;
- nativeSurface->y = y;
- nativeSurface->width = width;
- nativeSurface->height = height;
- nativeSurface->name = ~0;
- nativeSurface->stride = 0;
-
- eglInitSurface(&nativeSurface->base, display, config);
-
- return &nativeSurface->base;
-}
-
-EGLSurface
eglCreateSurfaceForName(EGLDisplay display, EGLConfig config,
uint32_t name, uint32_t width,
uint32_t height, uint32_t stride, const EGLint *attribList)
{
EGLSurfaceNative nativeSurface;
+ int i;
nativeSurface = malloc(sizeof *nativeSurface);
if (nativeSurface == NULL)
return NULL;
- nativeSurface->x = 0;
- nativeSurface->y = 0;
- nativeSurface->width = width;
- nativeSurface->height = height;
- nativeSurface->name = name;
- nativeSurface->stride = stride;
+ nativeSurface->backBuffer = EGL_FALSE;
- eglInitSurface(&nativeSurface->base, display, config);
+ nativeSurface->front.attachment = __DRI_BUFFER_FRONT_LEFT;
+ nativeSurface->front.name = name;
+ nativeSurface->front.pitch = stride;
+ nativeSurface->front.cpp = 4;
+ nativeSurface->front.flags = 0;
+ nativeSurface->frontHandle = 0;
+
+ eglInitSurface(&nativeSurface->base, display, config, width, height);
+
+ for (i = 0; attribList && attribList[i] != EGL_NONE; i += 2) {
+ if (attribList[i] == EGL_RENDER_BUFFER &&
+ attribList[i + 1] == EGL_BACK_BUFFER)
+ nativeSurface->backBuffer = EGL_TRUE;
+ }
return &nativeSurface->base;
}
@@ -427,7 +355,7 @@ eglReadBuffer(EGLDisplay display,
pread.handle = nativeSurface->handles[0];
pread.pad = 0;
pread.offset = 0;
- pread.size = *stride * nativeSurface->height;
+ pread.size = *stride * surface->height;
data = malloc(pread.size);
if (data == NULL) {
diff --git a/test.c b/test.c
index 46ac8d8..5b6fef6 100644
--- a/test.c
+++ b/test.c
@@ -7,6 +7,11 @@
#include <GL/gl.h>
#include "eagle.h"
#include "gears.h"
+#include <sys/time.h>
+#include <drm_mode.h>
+#include <xf86drmMode.h>
+#include <sys/ioctl.h>
+#include <i915_drm.h>
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a)[0])
@@ -23,6 +28,8 @@ static void run(EGLDisplay display, EGLSurface surface, EGLConfig config,
struct pollfd p[1];
GLfloat angle = 0.0;
struct gears *gears;
+ struct timeval before, now;
+ int count, elapsed, slice = 300;
context = eglCreateContext(display, config, NULL, NULL);
if (context == NULL)
@@ -34,10 +41,23 @@ static void run(EGLDisplay display, EGLSurface surface, EGLConfig config,
gears = gears_create(width, height);
p[0].fd = STDIN_FILENO;
p[0].events = POLLIN;
- while (poll(p, 1, 20) == 0) {
+ count = 0;
+ gettimeofday(&before, NULL);
+ while (1) {
+ glClear(GL_COLOR_BUFFER_BIT);
gears_draw(gears, angle);
eglSwapBuffers(display, surface);
- angle += 1;
+ angle += 0.4;
+ count += 1;
+ if (count == slice) {
+ gettimeofday(&now, NULL);
+ elapsed = (now.tv_sec - before.tv_sec) * 1000 +
+ (now.tv_usec - before.tv_usec) / 1000;
+ before = now;
+ printf("%d frames in %d seconds: %f fps\n",
+ slice, elapsed, (float) 1000 * slice / elapsed);
+ count = 0;
+ }
}
eglTerminate(display);
@@ -101,12 +121,58 @@ static void run_dri2(int x, int y, int width, int height)
run(display, surface, configs[24], width, height);
}
+static int
+get_fb_name(EGLDisplay display, int *width, int *height, int *stride)
+{
+ drmModeResPtr mode_res;
+ drmModeCrtcPtr crtc;
+ drmModeFBPtr fb;
+ struct drm_gem_flink flink;
+ int fd;
+
+ fd = eglGetDisplayFD(display);
+
+ mode_res = drmModeGetResources(fd);
+ if (mode_res == NULL) {
+ fprintf(stderr, "drmModeGetResources returns NULL\n");
+ return 0;
+ }
+
+ crtc = drmModeGetCrtc(fd, mode_res->crtcs[1]);
+ if (crtc == NULL) {
+ fprintf(stderr, "drmModeGetCrtc returns NULL\n");
+ return 0;
+ }
+
+ fb = drmModeGetFB(fd, crtc->buffer_id);
+ if (fb == NULL) {
+ fprintf(stderr, "drmModeGetFB returns NULL\n");
+ return 0;
+ }
+
+ flink.handle = fb->handle;
+ if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
+ fprintf(stderr, "failed to create buffer\n");
+ return 0;
+ }
+
+ *width = fb->width;
+ *height = fb->height;
+ *stride = fb->pitch;
+
+ return flink.name;
+}
+
static void run_native(int x, int y, int width, int height)
{
EGLDisplay display;
EGLSurface surface;
EGLConfig configs[64];
EGLint major, minor, count;
+ uint32_t name;
+ int fb_width, fb_height, fb_stride;
+ const static EGLint attribs[] =
+ { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };
display = eglCreateDisplayNative("/dev/dri/card0", "i965");
if (display == NULL)
@@ -118,8 +184,9 @@ static void run_native(int x, int y, int width, int height)
if (!eglGetConfigs(display, configs, ARRAY_SIZE(configs), &count))
die("failed to get configs\n");
- surface = eglCreateSurfaceNative(display, configs[24],
- x, y, width, height);
+ name = get_fb_name(display, &fb_width, &fb_height, &fb_stride);
+ surface = eglCreateSurfaceForName(display, configs[24],
+ name, width, height, fb_stride, attribs);
if (surface == NULL)
die("failed to create surface\n");
diff --git a/x11-dri2.c b/x11-dri2.c
index 953f63c..9b6dcb9 100644
--- a/x11-dri2.c
+++ b/x11-dri2.c
@@ -19,8 +19,6 @@ typedef struct EGLSurfaceX11 *EGLSurfaceX11;
struct EGLSurfaceX11 {
struct EGLSurface base;
Drawable drawable;
- int width;
- int height;
};
static void
@@ -33,8 +31,8 @@ x11GetBuffers(EGLSurface surface, uint32_t *attachments, int count)
buffers = DRI2GetBuffers(x11Display->display,
x11Surface->drawable,
- &x11Surface->width,
- &x11Surface->height,
+ &surface->width,
+ &surface->height,
attachments, count, &outCount);
for (i = 0; i < outCount; i++) {
@@ -140,10 +138,8 @@ eglCreateSurfaceX11(EGLDisplay display, EGLConfig config,
return NULL;
x11Surface->drawable = window;
- x11Surface->width = width;
- x11Surface->height = height;
- eglInitSurface(&x11Surface->base, display, config);
+ eglInitSurface(&x11Surface->base, display, config, width, height);
return &x11Surface->base;
}