diff options
Diffstat (limited to 'lib/mesa/src/egl/drivers')
-rw-r--r-- | lib/mesa/src/egl/drivers/dri2/egl_dri2.h | 33 | ||||
-rw-r--r-- | lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h | 5 | ||||
-rw-r--r-- | lib/mesa/src/egl/drivers/dri2/platform_android.c | 499 | ||||
-rw-r--r-- | lib/mesa/src/egl/drivers/dri2/platform_drm.c | 47 | ||||
-rw-r--r-- | lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c | 11 | ||||
-rw-r--r-- | lib/mesa/src/egl/drivers/dri2/platform_wayland.c | 341 | ||||
-rw-r--r-- | lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c | 34 |
7 files changed, 588 insertions, 382 deletions
diff --git a/lib/mesa/src/egl/drivers/dri2/egl_dri2.h b/lib/mesa/src/egl/drivers/dri2/egl_dri2.h index 0020a5b98..bd77247d2 100644 --- a/lib/mesa/src/egl/drivers/dri2/egl_dri2.h +++ b/lib/mesa/src/egl/drivers/dri2/egl_dri2.h @@ -56,14 +56,7 @@ #ifdef HAVE_ANDROID_PLATFORM #define LOG_TAG "EGL-DRI2" -#if ANDROID_VERSION >= 0x0400 -# include <system/window.h> -#else -# define android_native_buffer_t ANativeWindowBuffer -# include <ui/egl/android_natives.h> -# include <ui/android_native_buffer.h> -#endif - +#include <system/window.h> #include <hardware/gralloc.h> #include <gralloc_drm_handle.h> #include <cutils/log.h> @@ -199,7 +192,7 @@ struct dri2_egl_display #ifdef HAVE_X11_PLATFORM xcb_connection_t *conn; - int screen; + xcb_screen_t *screen; int swap_available; #ifdef HAVE_DRI3 struct loader_dri3_extensions loader_dri3_ext; @@ -208,6 +201,7 @@ struct dri2_egl_display #ifdef HAVE_WAYLAND_PLATFORM struct wl_display *wl_dpy; + struct wl_display *wl_dpy_wrapper; struct wl_registry *wl_registry; struct wl_drm *wl_server_drm; struct wl_drm *wl_drm; @@ -219,6 +213,10 @@ struct dri2_egl_display char *device_name; #endif +#ifdef HAVE_ANDROID_PLATFORM + const gralloc_module_t *gralloc; +#endif + int is_render_node; int is_different_gpu; }; @@ -259,6 +257,10 @@ struct dri2_egl_surface struct wl_egl_window *wl_win; int dx; int dy; + struct wl_event_queue *wl_queue; + struct wl_surface *wl_surface_wrapper; + struct wl_display *wl_dpy_wrapper; + struct wl_drm *wl_drm_wrapper; struct wl_callback *throttle_callback; int format; #endif @@ -290,10 +292,20 @@ struct dri2_egl_surface #ifdef HAVE_ANDROID_PLATFORM struct ANativeWindow *window; struct ANativeWindowBuffer *buffer; - __DRIimage *dri_image; + __DRIimage *dri_image_back; + __DRIimage *dri_image_front; /* EGL-owned buffers */ __DRIbuffer *local_buffers[__DRI_BUFFER_COUNT]; + + /* Used to record all the buffers created by ANativeWindow and their ages. + * Usually Android uses at most triple buffers in ANativeWindow + * so hardcode the number of color_buffers to 3. + */ + struct { + struct ANativeWindowBuffer *buffer; + int age; + } color_buffers[3], *back; #endif #if defined(HAVE_SURFACELESS_PLATFORM) @@ -336,6 +348,7 @@ _EGL_DRIVER_TYPECAST(dri2_egl_sync, _EGLSync, obj) extern const __DRIimageLookupExtension image_lookup_extension; extern const __DRIuseInvalidateExtension use_invalidate; +extern const __DRIbackgroundCallableExtension background_callable_extension; EGLBoolean dri2_load_driver(_EGLDisplay *disp); diff --git a/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h b/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h index 8dad27116..67a9c5034 100644 --- a/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h +++ b/lib/mesa/src/egl/drivers/dri2/egl_dri2_fallbacks.h @@ -22,7 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ -#pragma once +#ifndef EGL_DRI2_FALLBACKS_INCLUDED +#define EGL_DRI2_FALLBACKS_INCLUDED #include "egltypedefs.h" @@ -116,3 +117,5 @@ dri2_fallback_get_sync_values(_EGLDisplay *dpy, _EGLSurface *surf, { return EGL_FALSE; } + +#endif /* EGL_DRI2_FALLBACKS_INCLUDED */ diff --git a/lib/mesa/src/egl/drivers/dri2/platform_android.c b/lib/mesa/src/egl/drivers/dri2/platform_android.c index cf60f1d6b..d675cdcfc 100644 --- a/lib/mesa/src/egl/drivers/dri2/platform_android.c +++ b/lib/mesa/src/egl/drivers/dri2/platform_android.c @@ -31,10 +31,8 @@ #include <dlfcn.h> #include <fcntl.h> #include <xf86drm.h> - -#if ANDROID_VERSION >= 0x402 +#include <stdbool.h> #include <sync/sync.h> -#endif #include "loader.h" #include "egl_dri2.h" @@ -43,6 +41,52 @@ #define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) +struct droid_yuv_format { + /* Lookup keys */ + int native; /* HAL_PIXEL_FORMAT_ */ + int is_ycrcb; /* 0 if chroma order is {Cb, Cr}, 1 if {Cr, Cb} */ + int chroma_step; /* Distance in bytes between subsequent chroma pixels. */ + + /* Result */ + int fourcc; /* __DRI_IMAGE_FOURCC_ */ +}; + +/* The following table is used to look up a DRI image FourCC based + * on native format and information contained in android_ycbcr struct. */ +static const struct droid_yuv_format droid_yuv_formats[] = { + /* Native format, YCrCb, Chroma step, DRI image FourCC */ + { HAL_PIXEL_FORMAT_YCbCr_420_888, 0, 2, __DRI_IMAGE_FOURCC_NV12 }, + { HAL_PIXEL_FORMAT_YCbCr_420_888, 0, 1, __DRI_IMAGE_FOURCC_YUV420 }, + { HAL_PIXEL_FORMAT_YCbCr_420_888, 1, 1, __DRI_IMAGE_FOURCC_YVU420 }, + { HAL_PIXEL_FORMAT_YV12, 1, 1, __DRI_IMAGE_FOURCC_YVU420 }, +}; + +static int +get_fourcc_yuv(int native, int is_ycrcb, int chroma_step) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i) + if (droid_yuv_formats[i].native == native && + droid_yuv_formats[i].is_ycrcb == is_ycrcb && + droid_yuv_formats[i].chroma_step == chroma_step) + return droid_yuv_formats[i].fourcc; + + return -1; +} + +static bool +is_yuv(int native) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(droid_yuv_formats); ++i) + if (droid_yuv_formats[i].native == native) + return true; + + return false; +} + static int get_format_bpp(int native) { @@ -54,15 +98,9 @@ get_format_bpp(int native) case HAL_PIXEL_FORMAT_BGRA_8888: bpp = 4; break; - case HAL_PIXEL_FORMAT_RGB_888: - bpp = 3; - break; case HAL_PIXEL_FORMAT_RGB_565: bpp = 2; break; - case HAL_PIXEL_FORMAT_YV12: - bpp = 1; - break; default: bpp = 0; break; @@ -79,7 +117,6 @@ static int get_fourcc(int native) case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FOURCC_ARGB8888; case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FOURCC_ABGR8888; case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FOURCC_XBGR8888; - case HAL_PIXEL_FORMAT_YV12: return __DRI_IMAGE_FOURCC_YVU420; default: _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", native); } @@ -93,8 +130,6 @@ static int get_format(int format) case HAL_PIXEL_FORMAT_RGB_565: return __DRI_IMAGE_FORMAT_RGB565; case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FORMAT_ABGR8888; case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FORMAT_XBGR8888; - case HAL_PIXEL_FORMAT_RGB_888: - /* unsupported */ default: _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", format); } @@ -122,7 +157,6 @@ get_native_buffer_name(struct ANativeWindowBuffer *buf) static EGLBoolean droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) { -#if ANDROID_VERSION >= 0x0402 int fence_fd; if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer, @@ -157,13 +191,33 @@ droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) } dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common); -#else - if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer)) - return EGL_FALSE; - dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common); - dri2_surf->window->lockBuffer(dri2_surf->window, dri2_surf->buffer); -#endif + /* Record all the buffers created by ANativeWindow and update back buffer + * for updating buffer's age in swap_buffers. + */ + EGLBoolean updated = EGL_FALSE; + for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (!dri2_surf->color_buffers[i].buffer) { + dri2_surf->color_buffers[i].buffer = dri2_surf->buffer; + } + if (dri2_surf->color_buffers[i].buffer == dri2_surf->buffer) { + dri2_surf->back = &dri2_surf->color_buffers[i]; + updated = EGL_TRUE; + break; + } + } + + if (!updated) { + /* In case of all the buffers were recreated by ANativeWindow, reset + * the color_buffers + */ + for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + dri2_surf->color_buffers[i].buffer = NULL; + dri2_surf->color_buffers[i].age = 0; + } + dri2_surf->color_buffers[0].buffer = dri2_surf->buffer; + dri2_surf->back = &dri2_surf->color_buffers[0]; + } return EGL_TRUE; } @@ -179,7 +233,6 @@ droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_sur */ mtx_unlock(&disp->Mutex); -#if ANDROID_VERSION >= 0x0402 /* Queue the buffer without a sync fence. This informs the ANativeWindow * that it may access the buffer immediately. * @@ -195,28 +248,31 @@ droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_sur int fence_fd = -1; dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer, fence_fd); -#else - dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer); -#endif dri2_surf->buffer->common.decRef(&dri2_surf->buffer->common); dri2_surf->buffer = NULL; + dri2_surf->back = NULL; mtx_lock(&disp->Mutex); - if (dri2_surf->dri_image) { - dri2_dpy->image->destroyImage(dri2_surf->dri_image); - dri2_surf->dri_image = NULL; + if (dri2_surf->dri_image_back) { + dri2_dpy->image->destroyImage(dri2_surf->dri_image_back); + dri2_surf->dri_image_back = NULL; } return EGL_TRUE; } static void -droid_window_cancel_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf) +droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) { - /* no cancel buffer? */ - droid_window_enqueue_buffer(disp, dri2_surf); + int ret; + + ret = dri2_surf->window->cancelBuffer(dri2_surf->window, dri2_surf->buffer, -1); + if (ret < 0) { + _eglLog(_EGL_WARNING, "ANativeWindow::cancelBuffer failed"); + dri2_surf->base.Lost = EGL_TRUE; + } } static __DRIbuffer * @@ -295,14 +351,14 @@ droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height); } - config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT, + config = dri2_get_dri_config(dri2_conf, type, dri2_surf->base.GLColorspace); if (!config) goto cleanup_surface; dri2_surf->dri_drawable = - (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, - dri2_surf); + dri2_dpy->dri2->createNewDrawable(dri2_dpy->dri_screen, config, + dri2_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_surface; @@ -348,12 +404,24 @@ droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->buffer) - droid_window_cancel_buffer(disp, dri2_surf); + droid_window_cancel_buffer(dri2_surf); dri2_surf->window->common.decRef(&dri2_surf->window->common); } - (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); + if (dri2_surf->dri_image_back) { + _eglLog(_EGL_DEBUG, "%s : %d : destroy dri_image_back", __func__, __LINE__); + dri2_dpy->image->destroyImage(dri2_surf->dri_image_back); + dri2_surf->dri_image_back = NULL; + } + + if (dri2_surf->dri_image_front) { + _eglLog(_EGL_DEBUG, "%s : %d : destroy dri_image_front", __func__, __LINE__); + dri2_dpy->image->destroyImage(dri2_surf->dri_image_front); + dri2_surf->dri_image_front = NULL; + } + + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); free(dri2_surf); @@ -363,12 +431,16 @@ droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) static int update_buffers(struct dri2_egl_surface *dri2_surf) { + if (dri2_surf->base.Lost) + return -1; + if (dri2_surf->base.Type != EGL_WINDOW_BIT) return 0; /* try to dequeue the next back buffer */ if (!dri2_surf->buffer && !droid_window_dequeue_buffer(dri2_surf)) { _eglLog(_EGL_WARNING, "Could not dequeue buffer from native window"); + dri2_surf->base.Lost = EGL_TRUE; return -1; } @@ -384,52 +456,111 @@ update_buffers(struct dri2_egl_surface *dri2_surf) } static int -get_back_bo(struct dri2_egl_surface *dri2_surf) +get_front_bo(struct dri2_egl_surface *dri2_surf, unsigned int format) +{ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + + if (dri2_surf->dri_image_front) + return 0; + + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { + /* According current EGL spec, front buffer rendering + * for window surface is not supported now. + * and mesa doesn't have the implementation of this case. + * Add warning message, but not treat it as error. + */ + _eglLog(_EGL_DEBUG, "DRI driver requested unsupported front buffer for window surface"); + } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) { + dri2_surf->dri_image_front = + dri2_dpy->image->createImage(dri2_dpy->dri_screen, + dri2_surf->base.Width, + dri2_surf->base.Height, + format, + 0, + dri2_surf); + if (!dri2_surf->dri_image_front) { + _eglLog(_EGL_WARNING, "dri2_image_front allocation failed"); + return -1; + } + } + + return 0; +} + +static int +get_back_bo(struct dri2_egl_surface *dri2_surf, unsigned int format) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); int fourcc, pitch; int offset = 0, fd; - if (dri2_surf->dri_image) - return 0; + if (dri2_surf->dri_image_back) + return 0; - if (!dri2_surf->buffer) - return -1; + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { + if (!dri2_surf->buffer) { + _eglLog(_EGL_WARNING, "Could not get native buffer"); + return -1; + } - fd = get_native_buffer_fd(dri2_surf->buffer); - if (fd < 0) { - _eglLog(_EGL_WARNING, "Could not get native buffer FD"); - return -1; - } + fd = get_native_buffer_fd(dri2_surf->buffer); + if (fd < 0) { + _eglLog(_EGL_WARNING, "Could not get native buffer FD"); + return -1; + } - fourcc = get_fourcc(dri2_surf->buffer->format); + fourcc = get_fourcc(dri2_surf->buffer->format); - pitch = dri2_surf->buffer->stride * - get_format_bpp(dri2_surf->buffer->format); + pitch = dri2_surf->buffer->stride * + get_format_bpp(dri2_surf->buffer->format); - if (fourcc == -1 || pitch == 0) { - _eglLog(_EGL_WARNING, "Invalid buffer fourcc(%x) or pitch(%d)", - fourcc, pitch); - return -1; - } + if (fourcc == -1 || pitch == 0) { + _eglLog(_EGL_WARNING, "Invalid buffer fourcc(%x) or pitch(%d)", + fourcc, pitch); + return -1; + } - dri2_surf->dri_image = - dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, - dri2_surf->base.Width, - dri2_surf->base.Height, - fourcc, - &fd, - 1, - &pitch, - &offset, - dri2_surf); - if (!dri2_surf->dri_image) - return -1; + dri2_surf->dri_image_back = + dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, + dri2_surf->base.Width, + dri2_surf->base.Height, + fourcc, + &fd, + 1, + &pitch, + &offset, + dri2_surf); + if (!dri2_surf->dri_image_back) { + _eglLog(_EGL_WARNING, "failed to create DRI image from FD"); + return -1; + } + } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) { + /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically, + * the spec states that they have a back buffer but no front buffer, in + * contrast to pixmaps, which have a front buffer but no back buffer. + * + * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate + * from the spec, following the precedent of Mesa's EGL X11 platform. The + * X11 platform correctly assigns pbuffers to single-buffered configs, but + * assigns the pbuffer a front buffer instead of a back buffer. + * + * Pbuffers in the X11 platform mostly work today, so let's just copy its + * behavior instead of trying to fix (and hence potentially breaking) the + * world. + */ + _eglLog(_EGL_DEBUG, "DRI driver requested unsupported back buffer for pbuffer surface"); + } return 0; } +/* Some drivers will pass multiple bits in buffer_mask. + * For such case, will go through all the bits, and + * will not return error when unsupported buffer is requested, only + * return error when the allocation for supported buffer failed. + */ static int droid_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format, @@ -441,29 +572,49 @@ droid_image_get_buffers(__DRIdrawable *driDrawable, struct dri2_egl_surface *dri2_surf = loaderPrivate; images->image_mask = 0; + images->front = NULL; + images->back = NULL; if (update_buffers(dri2_surf) < 0) return 0; if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) { - /* - * We don't support front buffers and GLES doesn't require them for - * window surfaces, but some DRI drivers will request them anyway. - * We just ignore such request as other platforms backends do. - */ + if (get_front_bo(dri2_surf, format) < 0) + return 0; + + if (dri2_surf->dri_image_front) { + images->front = dri2_surf->dri_image_front; + images->image_mask |= __DRI_IMAGE_BUFFER_FRONT; + } } if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) { - if (get_back_bo(dri2_surf) < 0) + if (get_back_bo(dri2_surf, format) < 0) return 0; - images->back = dri2_surf->dri_image; - images->image_mask |= __DRI_IMAGE_BUFFER_BACK; + if (dri2_surf->dri_image_back) { + images->back = dri2_surf->dri_image_back; + images->image_mask |= __DRI_IMAGE_BUFFER_BACK; + } } return 1; } +static EGLint +droid_query_buffer_age(_EGLDriver *drv, + _EGLDisplay *disp, _EGLSurface *surface) +{ + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); + + if (update_buffers(dri2_surf) < 0) { + _eglError(EGL_BAD_ALLOC, "droid_query_buffer_age"); + return -1; + } + + return dri2_surf->back ? dri2_surf->back->age : 0; +} + static EGLBoolean droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { @@ -473,46 +624,108 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) if (dri2_surf->base.Type != EGL_WINDOW_BIT) return EGL_TRUE; + for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (dri2_surf->color_buffers[i].age > 0) + dri2_surf->color_buffers[i].age++; + } + + /* "XXX: we don't use get_back_bo() since it causes regressions in + * several dEQP tests. + */ + if (dri2_surf->back) + dri2_surf->back->age = 1; + dri2_flush_drawable_for_swapbuffers(disp, draw); + /* dri2_surf->buffer can be null even when no error has occured. For + * example, if the user has called no GL rendering commands since the + * previous eglSwapBuffers, then the driver may have not triggered + * a callback to ANativeWindow::dequeueBuffer, in which case + * dri2_surf->buffer remains null. + */ if (dri2_surf->buffer) droid_window_enqueue_buffer(disp, dri2_surf); - (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); return EGL_TRUE; } static _EGLImage * -droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx, - struct ANativeWindowBuffer *buf, int fd) +droid_create_image_from_prime_fd_yuv(_EGLDisplay *disp, _EGLContext *ctx, + struct ANativeWindowBuffer *buf, int fd) { - unsigned int offsets[3] = { 0, 0, 0 }; - unsigned int pitches[3] = { 0, 0, 0 }; + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct android_ycbcr ycbcr; + size_t offsets[3]; + size_t pitches[3]; + int is_ycrcb; + int fourcc; + int ret; + + if (!dri2_dpy->gralloc->lock_ycbcr) { + _eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr"); + return NULL; + } - const int fourcc = get_fourcc(buf->format); - if (fourcc == -1) { - _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); + memset(&ycbcr, 0, sizeof(ycbcr)); + ret = dri2_dpy->gralloc->lock_ycbcr(dri2_dpy->gralloc, buf->handle, + 0, 0, 0, 0, 0, &ycbcr); + if (ret) { + _eglLog(_EGL_WARNING, "gralloc->lock_ycbcr failed: %d", ret); return NULL; } + dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, buf->handle); + + /* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags + * it will return the .y/.cb/.cr pointers based on a NULL pointer, + * so they can be interpreted as offsets. */ + offsets[0] = (size_t)ycbcr.y; + /* We assume here that all the planes are located in one DMA-buf. */ + is_ycrcb = (size_t)ycbcr.cr < (size_t)ycbcr.cb; + if (is_ycrcb) { + offsets[1] = (size_t)ycbcr.cr; + offsets[2] = (size_t)ycbcr.cb; + } else { + offsets[1] = (size_t)ycbcr.cb; + offsets[2] = (size_t)ycbcr.cr; + } - pitches[0] = buf->stride * get_format_bpp(buf->format); - if (pitches[0] == 0) { - _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); + /* .ystride is the line length (in bytes) of the Y plane, + * .cstride is the line length (in bytes) of any of the remaining + * Cb/Cr/CbCr planes, assumed to be the same for Cb and Cr for fully + * planar formats. */ + pitches[0] = ycbcr.ystride; + pitches[1] = pitches[2] = ycbcr.cstride; + + /* .chroma_step is the byte distance between the same chroma channel + * values of subsequent pixels, assumed to be the same for Cb and Cr. */ + fourcc = get_fourcc_yuv(buf->format, is_ycrcb, ycbcr.chroma_step); + if (fourcc == -1) { + _eglLog(_EGL_WARNING, "unsupported YUV format, native = %x, is_ycrcb = %d, chroma_step = %d", + buf->format, is_ycrcb, ycbcr.chroma_step); return NULL; } - switch (buf->format) { - case HAL_PIXEL_FORMAT_YV12: - /* Y plane is assumed to be at offset 0. */ - /* Cr plane is located after Y plane */ - offsets[1] = offsets[0] + pitches[0] * buf->height; - pitches[1] = ALIGN(pitches[0] / 2, 16); - /* Cb plane is located after Cr plane */ - offsets[2] = offsets[1] + pitches[1] * buf->height / 2; - pitches[2] = pitches[1]; + if (ycbcr.chroma_step == 2) { + /* Semi-planar Y + CbCr or Y + CbCr format. */ + const EGLint attr_list_2plane[] = { + EGL_WIDTH, buf->width, + EGL_HEIGHT, buf->height, + EGL_LINUX_DRM_FOURCC_EXT, fourcc, + EGL_DMA_BUF_PLANE0_FD_EXT, fd, + EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0], + EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0], + EGL_DMA_BUF_PLANE1_FD_EXT, fd, + EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1], + EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1], + EGL_NONE, 0 + }; - const EGLint attr_list_yv12[] = { + return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_2plane); + } else { + /* Fully planar Y + Cb + Cr or Y + Cr + Cb format. */ + const EGLint attr_list_3plane[] = { EGL_WIDTH, buf->width, EGL_HEIGHT, buf->height, EGL_LINUX_DRM_FOURCC_EXT, fourcc, @@ -528,7 +741,29 @@ droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx, EGL_NONE, 0 }; - return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_yv12); + return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_3plane); + } +} + +static _EGLImage * +droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx, + struct ANativeWindowBuffer *buf, int fd) +{ + unsigned int pitch; + + if (is_yuv(buf->format)) + return droid_create_image_from_prime_fd_yuv(disp, ctx, buf, fd); + + const int fourcc = get_fourcc(buf->format); + if (fourcc == -1) { + _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); + return NULL; + } + + pitch = buf->stride * get_format_bpp(buf->format); + if (pitch == 0) { + _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); + return NULL; } const EGLint attr_list[] = { @@ -536,7 +771,7 @@ droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx, EGL_HEIGHT, buf->height, EGL_LINUX_DRM_FOURCC_EXT, fourcc, EGL_DMA_BUF_PLANE0_FD_EXT, fd, - EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0], + EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_NONE, 0 }; @@ -757,7 +992,6 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy) } visuals[] = { { HAL_PIXEL_FORMAT_RGBA_8888, { 0xff, 0xff00, 0xff0000, 0xff000000 } }, { HAL_PIXEL_FORMAT_RGBX_8888, { 0xff, 0xff00, 0xff0000, 0x0 } }, - { HAL_PIXEL_FORMAT_RGB_888, { 0xff, 0xff00, 0xff0000, 0x0 } }, { HAL_PIXEL_FORMAT_RGB_565, { 0xf800, 0x7e0, 0x1f, 0x0 } }, { HAL_PIXEL_FORMAT_BGRA_8888, { 0xff0000, 0xff00, 0xff, 0xff000000 } }, }; @@ -771,28 +1005,39 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy) unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 }; int count, i, j; + /* The nesting of loops is significant here. Also significant is the order + * of the HAL pixel formats. Many Android apps (such as Google's official + * NDK GLES2 example app), and even portions the core framework code (such + * as SystemServiceManager in Nougat), incorrectly choose their EGLConfig. + * They neglect to match the EGLConfig's EGL_NATIVE_VISUAL_ID against the + * window's native format, and instead choose the first EGLConfig whose + * channel sizes match those of the native window format while ignoring the + * channel *ordering*. + * + * We can detect such buggy clients in logcat when they call + * eglCreateSurface, by detecting the mismatch between the EGLConfig's + * format and the window's format. + * + * As a workaround, we generate EGLConfigs such that all EGLConfigs for HAL + * pixel format i precede those for HAL pixel format i+1. In my + * (chadversary) testing on Android Nougat, this was good enough to pacify + * the buggy clients. + */ count = 0; - for (i = 0; dri2_dpy->driver_configs[i]; i++) { + for (i = 0; i < ARRAY_SIZE(visuals); i++) { const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; struct dri2_egl_config *dri2_conf; - unsigned int double_buffered = 0; - - dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i], - __DRI_ATTRIB_DOUBLE_BUFFER, &double_buffered); - /* support only double buffered configs */ - if (!double_buffered) - continue; + for (j = 0; dri2_dpy->driver_configs[j]; j++) { + config_attrs[1] = visuals[i].format; + config_attrs[3] = visuals[i].format; - for (j = 0; j < ARRAY_SIZE(visuals); j++) { - config_attrs[1] = visuals[j].format; - config_attrs[3] = visuals[j].format; - - dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[i], - count + 1, surface_type, config_attrs, visuals[j].rgba_masks); + dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j], + count + 1, surface_type, config_attrs, visuals[i].rgba_masks); if (dri2_conf) { - count++; - format_count[j]++; + if (dri2_conf->base.ConfigID == count + 1) + count++; + format_count[i]++; } } } @@ -808,19 +1053,14 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy) } static int -droid_open_device(void) +droid_open_device(struct dri2_egl_display *dri2_dpy) { - const hw_module_t *mod; - int fd = -1, err; - - err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod); - if (!err) { - const gralloc_module_t *gr = (gralloc_module_t *) mod; + int fd = -1, err = -EINVAL; - err = -EINVAL; - if (gr->perform) - err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd); - } + if (dri2_dpy->gralloc->perform) + err = dri2_dpy->gralloc->perform(dri2_dpy->gralloc, + GRALLOC_MODULE_PERFORM_GET_DRM_FD, + &fd); if (err || fd < 0) { _eglLog(_EGL_WARNING, "fail to get drm fd"); fd = -1; @@ -874,7 +1114,7 @@ static struct dri2_egl_display_vtbl droid_display_vtbl = { .swap_buffers_region = dri2_fallback_swap_buffers_region, .post_sub_buffer = dri2_fallback_post_sub_buffer, .copy_buffers = dri2_fallback_copy_buffers, - .query_buffer_age = dri2_fallback_query_buffer_age, + .query_buffer_age = droid_query_buffer_age, .query_surface = droid_query_surface, .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image, .get_sync_values = dri2_fallback_get_sync_values, @@ -915,6 +1155,7 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy) { struct dri2_egl_display *dri2_dpy; const char *err; + int ret; _eglSetLogProc(droid_log); @@ -924,9 +1165,16 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy) if (!dri2_dpy) return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, + (const hw_module_t **)&dri2_dpy->gralloc); + if (ret) { + err = "DRI2: failed to get gralloc module"; + goto cleanup_display; + } + dpy->DriverData = (void *) dri2_dpy; - dri2_dpy->fd = droid_open_device(); + dri2_dpy->fd = droid_open_device(dri2_dpy); if (dri2_dpy->fd < 0) { err = "DRI2: failed to open device"; goto cleanup_display; @@ -965,6 +1213,7 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy) dpy->Extensions.ANDROID_framebuffer_target = EGL_TRUE; dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE; dpy->Extensions.ANDROID_recordable = EGL_TRUE; + dpy->Extensions.EXT_buffer_age = EGL_TRUE; /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. diff --git a/lib/mesa/src/egl/drivers/dri2/platform_drm.c b/lib/mesa/src/egl/drivers/dri2/platform_drm.c index ea1a7f126..b178eaa18 100644 --- a/lib/mesa/src/egl/drivers/dri2/platform_drm.c +++ b/lib/mesa/src/egl/drivers/dri2/platform_drm.c @@ -136,15 +136,15 @@ dri2_drm_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, if (dri2_dpy->dri2) { dri2_surf->dri_drawable = - (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, - dri2_surf->gbm_surf); + dri2_dpy->dri2->createNewDrawable(dri2_dpy->dri_screen, config, + dri2_surf->gbm_surf); } else { assert(dri2_dpy->swrast != NULL); dri2_surf->dri_drawable = - (*dri2_dpy->swrast->createNewDrawable)(dri2_dpy->dri_screen, config, - dri2_surf->gbm_surf); + dri2_dpy->swrast->createNewDrawable(dri2_dpy->dri_screen, config, + dri2_surf->gbm_surf); } if (dri2_surf->dri_drawable == NULL) { @@ -191,7 +191,7 @@ dri2_drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); unsigned i; - (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { if (dri2_surf->color_buffers[i].bo) @@ -215,23 +215,36 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); struct gbm_dri_surface *surf = dri2_surf->gbm_surf; + int age = 0; unsigned i; if (dri2_surf->back == NULL) { for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { - if (!dri2_surf->color_buffers[i].locked) { + if (!dri2_surf->color_buffers[i].locked && + dri2_surf->color_buffers[i].age >= age) { dri2_surf->back = &dri2_surf->color_buffers[i]; - break; + age = dri2_surf->color_buffers[i].age; } } } if (dri2_surf->back == NULL) return -1; - if (dri2_surf->back->bo == NULL) - dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base, - surf->base.width, surf->base.height, - surf->base.format, surf->base.flags); + if (dri2_surf->back->bo == NULL) { + if (surf->base.modifiers) + dri2_surf->back->bo = gbm_bo_create_with_modifiers(&dri2_dpy->gbm_dri->base.base, + surf->base.width, surf->base.height, + surf->base.format, + surf->base.modifiers, + surf->base.count); + else + dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base, + surf->base.width, + surf->base.height, + surf->base.format, + surf->base.flags); + + } if (dri2_surf->back->bo == NULL) return -1; @@ -414,7 +427,7 @@ dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) unsigned i; if (dri2_dpy->swrast) { - (*dri2_dpy->core->swapBuffers)(dri2_surf->dri_drawable); + dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); } else { if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->current) @@ -436,7 +449,7 @@ dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) } dri2_flush_drawable_for_swapbuffers(disp, draw); - (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); } return EGL_TRUE; @@ -450,7 +463,7 @@ dri2_drm_query_buffer_age(_EGLDriver *drv, if (get_back_bo(dri2_surf) < 0) { _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age"); - return 0; + return -1; } return dri2_surf->back->age; @@ -617,7 +630,8 @@ drm_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp) dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i], count + 1, EGL_WINDOW_BIT, attr_list, NULL); if (dri2_conf) { - count++; + if (dri2_conf->base.ConfigID == count + 1) + count++; format_count[j]++; } } @@ -676,12 +690,12 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) fd = loader_open_device(buf); if (fd < 0) fd = loader_open_device("/dev/dri/card0"); - dri2_dpy->own_device = 1; gbm = gbm_create_device(fd); if (gbm == NULL) { err = "DRI2: failed to create gbm device"; goto cleanup; } + dri2_dpy->own_device = 1; } else { fd = fcntl(gbm_device_get_fd(gbm), F_DUPFD_CLOEXEC, 3); if (fd < 0) { @@ -712,6 +726,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) dri2_dpy->flush = dri2_dpy->gbm_dri->flush; dri2_dpy->swrast = dri2_dpy->gbm_dri->swrast; dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs; + dri2_dpy->interop = dri2_dpy->gbm_dri->interop; dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image; dri2_dpy->gbm_dri->lookup_user_data = disp; diff --git a/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c b/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c index 025aaa255..3e1916956 100644 --- a/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c +++ b/lib/mesa/src/egl/drivers/dri2/platform_surfaceless.c @@ -134,8 +134,8 @@ dri2_surfaceless_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, goto cleanup_surface; dri2_surf->dri_drawable = - (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, - dri2_surf); + dri2_dpy->dri2->createNewDrawable(dri2_dpy->dri_screen, config, + dri2_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_surface; @@ -163,7 +163,7 @@ surfaceless_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *sur surfaceless_free_images(dri2_surf); - (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); free(dri2_surf); return EGL_TRUE; @@ -212,7 +212,8 @@ surfaceless_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy) count + 1, EGL_PBUFFER_BIT, NULL, visuals[j].rgba_masks); if (dri2_conf) { - count++; + if (dri2_conf->base.ConfigID == count + 1) + count++; format_count[j]++; } } @@ -322,8 +323,6 @@ dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp) goto cleanup_screen; } - disp->Extensions.KHR_image_base = EGL_TRUE; - /* Fill vtbl last to prevent accidentally calling virtual function during * initialization. */ diff --git a/lib/mesa/src/egl/drivers/dri2/platform_wayland.c b/lib/mesa/src/egl/drivers/dri2/platform_wayland.c index 27baec348..b8af6ef25 100644 --- a/lib/mesa/src/egl/drivers/dri2/platform_wayland.c +++ b/lib/mesa/src/egl/drivers/dri2/platform_wayland.c @@ -55,35 +55,10 @@ static EGLBoolean dri2_wl_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint interval); -static void -sync_callback(void *data, struct wl_callback *callback, uint32_t serial) -{ - int *done = data; - - *done = 1; - wl_callback_destroy(callback); -} - -static const struct wl_callback_listener sync_listener = { - .done = sync_callback -}; - static int roundtrip(struct dri2_egl_display *dri2_dpy) { - struct wl_callback *callback; - int done = 0, ret = 0; - - callback = wl_display_sync(dri2_dpy->wl_dpy); - wl_callback_add_listener(callback, &sync_listener, &done); - wl_proxy_set_queue((struct wl_proxy *) callback, dri2_dpy->wl_queue); - while (ret != -1 && !done) - ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue); - - if (!done) - wl_callback_destroy(callback); - - return ret; + return wl_display_roundtrip_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue); } static void @@ -115,7 +90,7 @@ resize_callback(struct wl_egl_window *wl_win, void *data) struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); - (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); } static void @@ -129,18 +104,17 @@ destroy_window_callback(void *data) * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * -dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, - _EGLConfig *conf, void *native_window, - const EGLint *attrib_list) +dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, void *native_window, + const EGLint *attrib_list) { + __DRIcreateNewDrawableFunc createNewDrawable; struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct wl_egl_window *window = native_window; struct dri2_egl_surface *dri2_surf; const __DRIconfig *config; - (void) drv; - dri2_surf = calloc(1, sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); @@ -150,12 +124,22 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list)) goto cleanup_surf; - if (conf->RedSize == 5) - dri2_surf->format = WL_DRM_FORMAT_RGB565; - else if (conf->AlphaSize == 0) - dri2_surf->format = WL_DRM_FORMAT_XRGB8888; - else - dri2_surf->format = WL_DRM_FORMAT_ARGB8888; + if (dri2_dpy->wl_drm) { + if (conf->RedSize == 5) + dri2_surf->format = WL_DRM_FORMAT_RGB565; + else if (conf->AlphaSize == 0) + dri2_surf->format = WL_DRM_FORMAT_XRGB8888; + else + dri2_surf->format = WL_DRM_FORMAT_ARGB8888; + } else { + assert(dri2_dpy->wl_shm); + if (conf->RedSize == 5) + dri2_surf->format = WL_SHM_FORMAT_RGB565; + else if (conf->AlphaSize == 0) + dri2_surf->format = WL_SHM_FORMAT_XRGB8888; + else + dri2_surf->format = WL_SHM_FORMAT_ARGB8888; + } if (!window) { _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_create_surface"); @@ -163,9 +147,39 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, } dri2_surf->wl_win = window; + dri2_surf->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy); + if (!dri2_surf->wl_queue) { + _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); + goto cleanup_surf; + } + + if (dri2_dpy->wl_drm) { + dri2_surf->wl_drm_wrapper = wl_proxy_create_wrapper(dri2_dpy->wl_drm); + if (!dri2_surf->wl_drm_wrapper) { + _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); + goto cleanup_queue; + } + wl_proxy_set_queue((struct wl_proxy *)dri2_surf->wl_drm_wrapper, + dri2_surf->wl_queue); + } + + dri2_surf->wl_dpy_wrapper = wl_proxy_create_wrapper(dri2_dpy->wl_dpy); + if (!dri2_surf->wl_dpy_wrapper) { + _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); + goto cleanup_drm; + } + wl_proxy_set_queue((struct wl_proxy *)dri2_surf->wl_dpy_wrapper, + dri2_surf->wl_queue); + + dri2_surf->wl_surface_wrapper = wl_proxy_create_wrapper(window->surface); + if (!dri2_surf->wl_surface_wrapper) { + _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); + goto cleanup_drm; + } + wl_proxy_set_queue((struct wl_proxy *)dri2_surf->wl_surface_wrapper, + dri2_surf->wl_queue); dri2_surf->wl_win->private = dri2_surf; - dri2_surf->wl_win->resize_callback = resize_callback; dri2_surf->wl_win->destroy_window_callback = destroy_window_callback; dri2_surf->base.Width = -1; @@ -174,41 +188,37 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT, dri2_surf->base.GLColorspace); - dri2_surf->dri_drawable = - (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, - dri2_surf); - if (dri2_surf->dri_drawable == NULL) { - _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); - goto cleanup_surf; + if (dri2_dpy->dri2) { + dri2_surf->wl_win->resize_callback = resize_callback; + + createNewDrawable = dri2_dpy->dri2->createNewDrawable; + } else { + createNewDrawable = dri2_dpy->swrast->createNewDrawable; } + dri2_surf->dri_drawable = (*createNewDrawable)(dri2_dpy->dri_screen, config, + dri2_surf); + if (dri2_surf->dri_drawable == NULL) { + _eglError(EGL_BAD_ALLOC, "createNewDrawable"); + goto cleanup_surf; + } + + dri2_wl_swap_interval(drv, disp, &dri2_surf->base, + dri2_dpy->default_swap_interval); + return &dri2_surf->base; + cleanup_drm: + if (dri2_surf->wl_drm_wrapper) + wl_proxy_wrapper_destroy(dri2_surf->wl_drm_wrapper); + cleanup_queue: + wl_event_queue_destroy(dri2_surf->wl_queue); cleanup_surf: free(dri2_surf); return NULL; } -/** - * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). - */ -static _EGLSurface * -dri2_wl_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, - _EGLConfig *conf, void *native_window, - const EGLint *attrib_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - _EGLSurface *surf; - - surf = dri2_wl_create_surface(drv, disp, conf, native_window, attrib_list); - - if (surf != NULL) - dri2_wl_swap_interval(drv, disp, surf, dri2_dpy->default_swap_interval); - - return surf; -} - static _EGLSurface * dri2_wl_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, void *native_window, @@ -237,7 +247,7 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) (void) drv; - (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { if (dri2_surf->color_buffers[i].wl_buffer) @@ -268,6 +278,12 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) dri2_surf->wl_win->destroy_window_callback = NULL; } + if (dri2_surf->wl_drm_wrapper) + wl_proxy_wrapper_destroy(dri2_surf->wl_drm_wrapper); + wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper); + wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper); + wl_event_queue_destroy(dri2_surf->wl_queue); + free(surf); return EGL_TRUE; @@ -335,16 +351,10 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) return -1; } - /* We always want to throttle to some event (either a frame callback or - * a sync request) after the commit so that we can be sure the - * compositor has had a chance to handle it and send us a release event - * before we look for a free buffer */ - while (dri2_surf->throttle_callback != NULL) - if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, - dri2_dpy->wl_queue) == -1) - return -1; + /* There might be a buffer release already queued that wasn't processed */ + wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_surf->wl_queue); - if (dri2_surf->back == NULL) { + while (dri2_surf->back == NULL) { for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { /* Get an unlocked buffer, preferrably one with a dri_buffer * already allocated. */ @@ -355,6 +365,14 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) else if (dri2_surf->back->dri_image == NULL) dri2_surf->back = &dri2_surf->color_buffers[i]; } + + if (dri2_surf->back) + break; + + /* If we don't have a buffer, then block on the server to release one for + * us, and try again. */ + if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_surf->wl_queue) < 0) + return -1; } if (dri2_surf->back == NULL) @@ -643,7 +661,7 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf) dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); dri2_surf->current->wl_buffer = - wl_drm_create_prime_buffer(dri2_dpy->wl_drm, + wl_drm_create_prime_buffer(dri2_surf->wl_drm_wrapper, fd, dri2_surf->base.Width, dri2_surf->base.Height, @@ -657,7 +675,7 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf) dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); dri2_surf->current->wl_buffer = - wl_drm_create_buffer(dri2_dpy->wl_drm, + wl_drm_create_buffer(dri2_surf->wl_drm_wrapper, name, dri2_surf->base.Width, dri2_surf->base.Height, @@ -665,8 +683,6 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf) dri2_surf->format); } - wl_proxy_set_queue((struct wl_proxy *) dri2_surf->current->wl_buffer, - dri2_dpy->wl_queue); wl_buffer_add_listener(dri2_surf->current->wl_buffer, &wl_buffer_listener, dri2_surf); } @@ -676,31 +692,21 @@ try_damage_buffer(struct dri2_egl_surface *dri2_surf, const EGLint *rects, EGLint n_rects) { -/* The WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION macro and - * wl_proxy_get_version() were both introduced in wayland 1.10. - * Instead of bumping our wayland dependency we just make this - * function conditional on the required 1.10 features, falling - * back to old (correct but suboptimal) behaviour for older - * wayland. - */ -#ifdef WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION int i; - if (wl_proxy_get_version((struct wl_proxy *) dri2_surf->wl_win->surface) + if (wl_proxy_get_version((struct wl_proxy *) dri2_surf->wl_surface_wrapper) < WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) return EGL_FALSE; for (i = 0; i < n_rects; i++) { const int *rect = &rects[i * 4]; - wl_surface_damage_buffer(dri2_surf->wl_win->surface, + wl_surface_damage_buffer(dri2_surf->wl_surface_wrapper, rect[0], dri2_surf->base.Height - rect[1] - rect[3], rect[2], rect[3]); } return EGL_TRUE; -#endif - return EGL_FALSE; } /** * Called via eglSwapBuffers(), drv->API.SwapBuffers(). @@ -716,6 +722,11 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv, struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); int i; + while (dri2_surf->throttle_callback != NULL) + if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, + dri2_surf->wl_queue) == -1) + return -1; + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) if (dri2_surf->color_buffers[i].age > 0) dri2_surf->color_buffers[i].age++; @@ -729,11 +740,9 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv, if (draw->SwapInterval > 0) { dri2_surf->throttle_callback = - wl_surface_frame(dri2_surf->wl_win->surface); + wl_surface_frame(dri2_surf->wl_surface_wrapper); wl_callback_add_listener(dri2_surf->throttle_callback, &throttle_listener, dri2_surf); - wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback, - dri2_dpy->wl_queue); } dri2_surf->back->age = 1; @@ -742,7 +751,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv, create_wl_buffer(dri2_surf); - wl_surface_attach(dri2_surf->wl_win->surface, + wl_surface_attach(dri2_surf->wl_surface_wrapper, dri2_surf->current->wl_buffer, dri2_surf->dx, dri2_surf->dy); @@ -756,7 +765,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv, * ignore the damage region and post maximum damage, due to * https://bugs.freedesktop.org/78190 */ if (!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects)) - wl_surface_damage(dri2_surf->wl_win->surface, + wl_surface_damage(dri2_surf->wl_surface_wrapper, 0, 0, INT32_MAX, INT32_MAX); if (dri2_dpy->is_different_gpu) { @@ -772,20 +781,18 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv, } dri2_flush_drawable_for_swapbuffers(disp, draw); - (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); - wl_surface_commit(dri2_surf->wl_win->surface); + wl_surface_commit(dri2_surf->wl_surface_wrapper); /* If we're not waiting for a frame callback then we'll at least throttle * to a sync callback so that we always give a chance for the compositor to * handle the commit and send a release event before checking for a free * buffer */ if (dri2_surf->throttle_callback == NULL) { - dri2_surf->throttle_callback = wl_display_sync(dri2_dpy->wl_dpy); + dri2_surf->throttle_callback = wl_display_sync(dri2_surf->wl_dpy_wrapper); wl_callback_add_listener(dri2_surf->throttle_callback, &throttle_listener, dri2_surf); - wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback, - dri2_dpy->wl_queue); } wl_display_flush(dri2_dpy->wl_dpy); @@ -801,7 +808,7 @@ dri2_wl_query_buffer_age(_EGLDriver *drv, if (get_back_bo(dri2_surf) < 0) { _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age"); - return 0; + return -1; } return dri2_surf->back->age; @@ -1121,7 +1128,8 @@ dri2_wl_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp) dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i], count + 1, EGL_WINDOW_BIT, NULL, visuals[j].rgba_masks); if (dri2_conf) { - count++; + if (dri2_conf->base.ConfigID == count + 1) + count++; format_count[j]++; } } @@ -1160,12 +1168,17 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp) dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy); + dri2_dpy->wl_dpy_wrapper = wl_proxy_create_wrapper(dri2_dpy->wl_dpy); + if (dri2_dpy->wl_dpy_wrapper == NULL) + goto cleanup_dpy_wrapper; + + wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_dpy_wrapper, + dri2_dpy->wl_queue); + if (dri2_dpy->own_device) wl_display_dispatch_pending(dri2_dpy->wl_dpy); - dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy); - wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry, - dri2_dpy->wl_queue); + dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy_wrapper); wl_registry_add_listener(dri2_dpy->wl_registry, ®istry_listener_drm, dri2_dpy); if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL) @@ -1283,6 +1296,8 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp) wl_drm_destroy(dri2_dpy->wl_drm); cleanup_registry: wl_registry_destroy(dri2_dpy->wl_registry); + wl_proxy_wrapper_destroy(dri2_dpy->wl_dpy_wrapper); + cleanup_dpy_wrapper: wl_event_queue_destroy(dri2_dpy->wl_queue); if (disp->PlatformDisplay == NULL) wl_display_disconnect(dri2_dpy->wl_dpy); @@ -1419,11 +1434,13 @@ os_create_anonymous_file(off_t size) static EGLBoolean -dri2_wl_swrast_allocate_buffer(struct dri2_egl_display *dri2_dpy, +dri2_wl_swrast_allocate_buffer(struct dri2_egl_surface *dri2_surf, int format, int w, int h, void **data, int *size, struct wl_buffer **buffer) { + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); struct wl_shm_pool *pool; int fd, stride, size_map; void *data_map; @@ -1444,6 +1461,7 @@ dri2_wl_swrast_allocate_buffer(struct dri2_egl_display *dri2_dpy, /* Share it in a wl_buffer */ pool = wl_shm_create_pool(dri2_dpy->wl_shm, fd, size_map); + wl_proxy_set_queue((struct wl_proxy *)pool, dri2_surf->wl_queue); *buffer = wl_shm_pool_create_buffer(pool, 0, w, h, stride, format); wl_shm_pool_destroy(pool); close(fd); @@ -1478,14 +1496,8 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf) /* find back buffer */ - /* We always want to throttle to some event (either a frame callback or - * a sync request) after the commit so that we can be sure the - * compositor has had a chance to handle it and send us a release event - * before we look for a free buffer */ - while (dri2_surf->throttle_callback != NULL) - if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, - dri2_dpy->wl_queue) == -1) - return -1; + /* There might be a buffer release already queued that wasn't processed */ + wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_surf->wl_queue); /* try get free buffer already created */ for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { @@ -1501,7 +1513,7 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf) for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { if (!dri2_surf->color_buffers[i].locked) { dri2_surf->back = &dri2_surf->color_buffers[i]; - if (!dri2_wl_swrast_allocate_buffer(dri2_dpy, + if (!dri2_wl_swrast_allocate_buffer(dri2_surf, dri2_surf->format, dri2_surf->base.Width, dri2_surf->base.Height, @@ -1511,8 +1523,6 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf) _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer"); return -1; } - wl_proxy_set_queue((struct wl_proxy *) dri2_surf->back->wl_buffer, - dri2_dpy->wl_queue); wl_buffer_add_listener(dri2_surf->back->wl_buffer, &wl_buffer_listener, dri2_surf); break; @@ -1566,19 +1576,22 @@ dri2_wl_swrast_commit_backbuffer(struct dri2_egl_surface *dri2_surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); + while (dri2_surf->throttle_callback != NULL) + if (wl_display_dispatch_queue(dri2_dpy->wl_dpy, + dri2_surf->wl_queue) == -1) + return; + if (dri2_surf->base.SwapInterval > 0) { dri2_surf->throttle_callback = - wl_surface_frame(dri2_surf->wl_win->surface); + wl_surface_frame(dri2_surf->wl_surface_wrapper); wl_callback_add_listener(dri2_surf->throttle_callback, &throttle_listener, dri2_surf); - wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback, - dri2_dpy->wl_queue); } dri2_surf->current = dri2_surf->back; dri2_surf->back = NULL; - wl_surface_attach(dri2_surf->wl_win->surface, + wl_surface_attach(dri2_surf->wl_surface_wrapper, dri2_surf->current->wl_buffer, dri2_surf->dx, dri2_surf->dy); @@ -1588,20 +1601,18 @@ dri2_wl_swrast_commit_backbuffer(struct dri2_egl_surface *dri2_surf) dri2_surf->dx = 0; dri2_surf->dy = 0; - wl_surface_damage(dri2_surf->wl_win->surface, + wl_surface_damage(dri2_surf->wl_surface_wrapper, 0, 0, INT32_MAX, INT32_MAX); - wl_surface_commit(dri2_surf->wl_win->surface); + wl_surface_commit(dri2_surf->wl_surface_wrapper); /* If we're not waiting for a frame callback then we'll at least throttle * to a sync callback so that we always give a chance for the compositor to * handle the commit and send a release event before checking for a free * buffer */ if (dri2_surf->throttle_callback == NULL) { - dri2_surf->throttle_callback = wl_display_sync(dri2_dpy->wl_dpy); + dri2_surf->throttle_callback = wl_display_sync(dri2_dpy->wl_dpy_wrapper); wl_callback_add_listener(dri2_surf->throttle_callback, &throttle_listener, dri2_surf); - wl_proxy_set_queue((struct wl_proxy *) dri2_surf->throttle_callback, - dri2_dpy->wl_queue); } wl_display_flush(dri2_dpy->wl_dpy); @@ -1712,69 +1723,6 @@ dri2_wl_swrast_put_image(__DRIdrawable * draw, int op, stride, data, loaderPrivate); } -/** - * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). - */ -static _EGLSurface * -dri2_wl_swrast_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, - _EGLConfig *conf, void *native_window, - const EGLint *attrib_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); - struct wl_egl_window *window = native_window; - struct dri2_egl_surface *dri2_surf; - const __DRIconfig *config; - - (void) drv; - - dri2_surf = calloc(1, sizeof *dri2_surf); - if (!dri2_surf) { - _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); - return NULL; - } - - if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list)) - goto cleanup_surf; - - if (conf->RedSize == 5) - dri2_surf->format = WL_SHM_FORMAT_RGB565; - else if (conf->AlphaSize == 0) - dri2_surf->format = WL_SHM_FORMAT_XRGB8888; - else - dri2_surf->format = WL_SHM_FORMAT_ARGB8888; - - dri2_surf->wl_win = window; - dri2_surf->wl_win->private = dri2_surf; - dri2_surf->wl_win->destroy_window_callback = destroy_window_callback; - - dri2_surf->base.Width = -1; - dri2_surf->base.Height = -1; - - config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT, - dri2_surf->base.GLColorspace); - - dri2_surf->dri_drawable = - (*dri2_dpy->swrast->createNewDrawable)(dri2_dpy->dri_screen, - config, dri2_surf); - if (dri2_surf->dri_drawable == NULL) { - _eglError(EGL_BAD_ALLOC, "swrast->createNewDrawable"); - goto cleanup_dri_drawable; - } - - dri2_wl_swap_interval(drv, disp, &dri2_surf->base, - dri2_dpy->default_swap_interval); - - return &dri2_surf->base; - - cleanup_dri_drawable: - dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); - cleanup_surf: - free(dri2_surf); - - return NULL; -} - static EGLBoolean dri2_wl_swrast_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { @@ -1827,7 +1775,7 @@ static const struct wl_registry_listener registry_listener_swrast = { static struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = { .authenticate = NULL, - .create_window_surface = dri2_wl_swrast_create_window_surface, + .create_window_surface = dri2_wl_create_window_surface, .create_pixmap_surface = dri2_wl_create_pixmap_surface, .create_pbuffer_surface = dri2_fallback_create_pbuffer_surface, .destroy_surface = dri2_wl_destroy_surface, @@ -1881,12 +1829,17 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp) dri2_dpy->wl_queue = wl_display_create_queue(dri2_dpy->wl_dpy); + dri2_dpy->wl_dpy_wrapper = wl_proxy_create_wrapper(dri2_dpy->wl_dpy); + if (dri2_dpy->wl_dpy_wrapper == NULL) + goto cleanup_dpy_wrapper; + + wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_dpy_wrapper, + dri2_dpy->wl_queue); + if (dri2_dpy->own_device) wl_display_dispatch_pending(dri2_dpy->wl_dpy); - dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy); - wl_proxy_set_queue((struct wl_proxy *) dri2_dpy->wl_registry, - dri2_dpy->wl_queue); + dri2_dpy->wl_registry = wl_display_get_registry(dri2_dpy->wl_dpy_wrapper); wl_registry_add_listener(dri2_dpy->wl_registry, ®istry_listener_swrast, dri2_dpy); @@ -1928,6 +1881,8 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp) wl_shm_destroy(dri2_dpy->wl_shm); cleanup_registry: wl_registry_destroy(dri2_dpy->wl_registry); + wl_proxy_wrapper_destroy(dri2_dpy->wl_dpy_wrapper); + cleanup_dpy_wrapper: wl_event_queue_destroy(dri2_dpy->wl_queue); if (disp->PlatformDisplay == NULL) wl_display_disconnect(dri2_dpy->wl_dpy); diff --git a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c index 1648ef08d..c4a54431c 100644 --- a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c @@ -160,16 +160,6 @@ dri3_set_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, return EGL_TRUE; } -static xcb_screen_t * -get_xcb_screen(xcb_screen_iterator_t iter, int screen) -{ - for (; iter.rem; --screen, xcb_screen_next(&iter)) - if (screen == 0) - return iter.data; - - return NULL; -} - static _EGLSurface * dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, void *native_surface, @@ -180,8 +170,6 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, struct dri3_egl_surface *dri3_surf; const __DRIconfig *dri_config; xcb_drawable_t drawable; - xcb_screen_iterator_t s; - xcb_screen_t *screen; STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_surface)); drawable = (uintptr_t) native_surface; @@ -198,16 +186,9 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, goto cleanup_surf; if (type == EGL_PBUFFER_BIT) { - s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); - screen = get_xcb_screen(s, dri2_dpy->screen); - if (!screen) { - _eglError(EGL_BAD_NATIVE_WINDOW, "dri3_create_surface"); - goto cleanup_surf; - } - drawable = xcb_generate_id(dri2_dpy->conn); xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, - drawable, screen->root, + drawable, dri2_dpy->screen->root, dri3_surf->base.Width, dri3_surf->base.Height); } @@ -407,7 +388,7 @@ dri3_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) /* No-op for a pixmap or pbuffer surface */ if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) - return 0; + return EGL_FALSE; return loader_dri3_swap_buffers_msc(&dri3_surf->loader_drawable, 0, 0, 0, 0, @@ -493,8 +474,6 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy) xcb_present_query_version_reply_t *present_query; xcb_present_query_version_cookie_t present_query_cookie; xcb_generic_error_t *error; - xcb_screen_iterator_t s; - xcb_screen_t *screen; const xcb_query_extension_reply_t *extension; xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id); @@ -537,14 +516,7 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy) } free(present_query); - s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); - screen = get_xcb_screen(s, dri2_dpy->screen); - if (!screen) { - _eglError(EGL_BAD_NATIVE_WINDOW, "dri3_x11_connect"); - return EGL_FALSE; - } - - dri2_dpy->fd = loader_dri3_open(dri2_dpy->conn, screen->root, 0); + dri2_dpy->fd = loader_dri3_open(dri2_dpy->conn, dri2_dpy->screen->root, 0); if (dri2_dpy->fd < 0) { int conn_error = xcb_connection_has_error(dri2_dpy->conn); _eglLog(_EGL_WARNING, "DRI3: Screen seems not DRI3 capable"); |