diff options
author | Kristian Høgsberg <krh@redhat.com> | 2008-11-25 00:09:33 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2008-11-25 00:12:56 -0500 |
commit | afd39ddf0bd41c80e997cee46e6239bbe044ee2a (patch) | |
tree | e122997c73e9370068c827967b61a5c191037838 | |
parent | bf75ddbcc58a18068717572c5ffcbb117901cae5 (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.h | 3 | ||||
-rw-r--r-- | eagle.c | 22 | ||||
-rw-r--r-- | eagle.h | 2 | ||||
-rw-r--r-- | intel.c | 202 | ||||
-rw-r--r-- | test.c | 75 | ||||
-rw-r--r-- | x11-dri2.c | 10 |
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 @@ -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, @@ -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); @@ -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) { @@ -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"); @@ -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; } |