1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2011 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19bf215546Sopenharmony_ci * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20bf215546Sopenharmony_ci * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci * Authors: 25bf215546Sopenharmony_ci * Kristian Høgsberg <krh@bitplanet.net> 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <stdbool.h> 29bf215546Sopenharmony_ci#include <stdint.h> 30bf215546Sopenharmony_ci#include <stdlib.h> 31bf215546Sopenharmony_ci#include <string.h> 32bf215546Sopenharmony_ci#include <stdio.h> 33bf215546Sopenharmony_ci#include <limits.h> 34bf215546Sopenharmony_ci#include <dlfcn.h> 35bf215546Sopenharmony_ci#include <fcntl.h> 36bf215546Sopenharmony_ci#include <errno.h> 37bf215546Sopenharmony_ci#include <unistd.h> 38bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 39bf215546Sopenharmony_ci#include <xf86drm.h> 40bf215546Sopenharmony_ci#endif 41bf215546Sopenharmony_ci#include <sys/types.h> 42bf215546Sopenharmony_ci#include <sys/stat.h> 43bf215546Sopenharmony_ci#include "util/debug.h" 44bf215546Sopenharmony_ci#include "util/macros.h" 45bf215546Sopenharmony_ci#include "util/bitscan.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci#include "egl_dri2.h" 48bf215546Sopenharmony_ci#include "loader.h" 49bf215546Sopenharmony_ci#include "kopper_interface.h" 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci#ifdef HAVE_DRI3 52bf215546Sopenharmony_ci#include "platform_x11_dri3.h" 53bf215546Sopenharmony_ci#endif 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_cistatic EGLBoolean 56bf215546Sopenharmony_cidri2_x11_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval); 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ciuint32_t 59bf215546Sopenharmony_cidri2_format_for_depth(struct dri2_egl_display *dri2_dpy, uint32_t depth); 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cistatic void 62bf215546Sopenharmony_ciswrastCreateDrawable(struct dri2_egl_display * dri2_dpy, 63bf215546Sopenharmony_ci struct dri2_egl_surface * dri2_surf) 64bf215546Sopenharmony_ci{ 65bf215546Sopenharmony_ci uint32_t mask; 66bf215546Sopenharmony_ci const uint32_t function = GXcopy; 67bf215546Sopenharmony_ci uint32_t valgc[2]; 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci /* create GC's */ 70bf215546Sopenharmony_ci dri2_surf->gc = xcb_generate_id(dri2_dpy->conn); 71bf215546Sopenharmony_ci mask = XCB_GC_FUNCTION; 72bf215546Sopenharmony_ci xcb_create_gc(dri2_dpy->conn, dri2_surf->gc, dri2_surf->drawable, mask, &function); 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci dri2_surf->swapgc = xcb_generate_id(dri2_dpy->conn); 75bf215546Sopenharmony_ci mask = XCB_GC_FUNCTION | XCB_GC_GRAPHICS_EXPOSURES; 76bf215546Sopenharmony_ci valgc[0] = function; 77bf215546Sopenharmony_ci valgc[1] = False; 78bf215546Sopenharmony_ci xcb_create_gc(dri2_dpy->conn, dri2_surf->swapgc, dri2_surf->drawable, mask, valgc); 79bf215546Sopenharmony_ci switch (dri2_surf->depth) { 80bf215546Sopenharmony_ci case 32: 81bf215546Sopenharmony_ci case 30: 82bf215546Sopenharmony_ci case 24: 83bf215546Sopenharmony_ci dri2_surf->bytes_per_pixel = 4; 84bf215546Sopenharmony_ci break; 85bf215546Sopenharmony_ci case 16: 86bf215546Sopenharmony_ci dri2_surf->bytes_per_pixel = 2; 87bf215546Sopenharmony_ci break; 88bf215546Sopenharmony_ci case 8: 89bf215546Sopenharmony_ci dri2_surf->bytes_per_pixel = 1; 90bf215546Sopenharmony_ci break; 91bf215546Sopenharmony_ci case 0: 92bf215546Sopenharmony_ci dri2_surf->bytes_per_pixel = 0; 93bf215546Sopenharmony_ci break; 94bf215546Sopenharmony_ci default: 95bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "unsupported depth %d", dri2_surf->depth); 96bf215546Sopenharmony_ci } 97bf215546Sopenharmony_ci} 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_cistatic void 100bf215546Sopenharmony_ciswrastDestroyDrawable(struct dri2_egl_display * dri2_dpy, 101bf215546Sopenharmony_ci struct dri2_egl_surface * dri2_surf) 102bf215546Sopenharmony_ci{ 103bf215546Sopenharmony_ci xcb_free_gc(dri2_dpy->conn, dri2_surf->gc); 104bf215546Sopenharmony_ci xcb_free_gc(dri2_dpy->conn, dri2_surf->swapgc); 105bf215546Sopenharmony_ci} 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_cistatic bool 108bf215546Sopenharmony_cix11_get_drawable_info(__DRIdrawable * draw, 109bf215546Sopenharmony_ci int *x, int *y, int *w, int *h, 110bf215546Sopenharmony_ci void *loaderPrivate) 111bf215546Sopenharmony_ci{ 112bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 113bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci xcb_get_geometry_cookie_t cookie; 116bf215546Sopenharmony_ci xcb_get_geometry_reply_t *reply; 117bf215546Sopenharmony_ci xcb_generic_error_t *error; 118bf215546Sopenharmony_ci bool ret; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); 121bf215546Sopenharmony_ci reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); 122bf215546Sopenharmony_ci if (reply == NULL) 123bf215546Sopenharmony_ci return false; 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci if (error != NULL) { 126bf215546Sopenharmony_ci ret = false; 127bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "error in xcb_get_geometry"); 128bf215546Sopenharmony_ci free(error); 129bf215546Sopenharmony_ci } else { 130bf215546Sopenharmony_ci *x = reply->x; 131bf215546Sopenharmony_ci *y = reply->y; 132bf215546Sopenharmony_ci *w = reply->width; 133bf215546Sopenharmony_ci *h = reply->height; 134bf215546Sopenharmony_ci ret = true; 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci free(reply); 137bf215546Sopenharmony_ci return ret; 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_cistatic void 141bf215546Sopenharmony_ciswrastGetDrawableInfo(__DRIdrawable * draw, 142bf215546Sopenharmony_ci int *x, int *y, int *w, int *h, 143bf215546Sopenharmony_ci void *loaderPrivate) 144bf215546Sopenharmony_ci{ 145bf215546Sopenharmony_ci *x = *y = *w = *h = 0; 146bf215546Sopenharmony_ci x11_get_drawable_info(draw, x, y, w, h, loaderPrivate); 147bf215546Sopenharmony_ci} 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_cistatic void 150bf215546Sopenharmony_ciswrastPutImage(__DRIdrawable * draw, int op, 151bf215546Sopenharmony_ci int x, int y, int w, int h, 152bf215546Sopenharmony_ci char *data, void *loaderPrivate) 153bf215546Sopenharmony_ci{ 154bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 155bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); 156bf215546Sopenharmony_ci size_t hdr_len = sizeof(xcb_put_image_request_t); 157bf215546Sopenharmony_ci int stride_b = dri2_surf->bytes_per_pixel * w; 158bf215546Sopenharmony_ci size_t size = (hdr_len + stride_b * h) >> 2; 159bf215546Sopenharmony_ci uint64_t max_req_len = xcb_get_maximum_request_length(dri2_dpy->conn); 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci xcb_gcontext_t gc; 162bf215546Sopenharmony_ci xcb_void_cookie_t cookie; 163bf215546Sopenharmony_ci switch (op) { 164bf215546Sopenharmony_ci case __DRI_SWRAST_IMAGE_OP_DRAW: 165bf215546Sopenharmony_ci gc = dri2_surf->gc; 166bf215546Sopenharmony_ci break; 167bf215546Sopenharmony_ci case __DRI_SWRAST_IMAGE_OP_SWAP: 168bf215546Sopenharmony_ci gc = dri2_surf->swapgc; 169bf215546Sopenharmony_ci break; 170bf215546Sopenharmony_ci default: 171bf215546Sopenharmony_ci return; 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (size < max_req_len) { 175bf215546Sopenharmony_ci cookie = xcb_put_image(dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, dri2_surf->drawable, 176bf215546Sopenharmony_ci gc, w, h, x, y, 0, dri2_surf->depth, 177bf215546Sopenharmony_ci h * stride_b, (const uint8_t *)data); 178bf215546Sopenharmony_ci xcb_discard_reply(dri2_dpy->conn, cookie.sequence); 179bf215546Sopenharmony_ci } else { 180bf215546Sopenharmony_ci int num_lines = ((max_req_len << 2) - hdr_len) / stride_b; 181bf215546Sopenharmony_ci int y_start = 0; 182bf215546Sopenharmony_ci int y_todo = h; 183bf215546Sopenharmony_ci while (y_todo) { 184bf215546Sopenharmony_ci int this_lines = MIN2(num_lines, y_todo); 185bf215546Sopenharmony_ci cookie = xcb_put_image(dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, dri2_surf->drawable, 186bf215546Sopenharmony_ci gc, w, this_lines, x, y_start, 0, dri2_surf->depth, 187bf215546Sopenharmony_ci this_lines * stride_b, ((const uint8_t *)data + y_start * stride_b)); 188bf215546Sopenharmony_ci xcb_discard_reply(dri2_dpy->conn, cookie.sequence); 189bf215546Sopenharmony_ci y_start += this_lines; 190bf215546Sopenharmony_ci y_todo -= this_lines; 191bf215546Sopenharmony_ci } 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_cistatic void 196bf215546Sopenharmony_ciswrastGetImage(__DRIdrawable * read, 197bf215546Sopenharmony_ci int x, int y, int w, int h, 198bf215546Sopenharmony_ci char *data, void *loaderPrivate) 199bf215546Sopenharmony_ci{ 200bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 201bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci xcb_get_image_cookie_t cookie; 204bf215546Sopenharmony_ci xcb_get_image_reply_t *reply; 205bf215546Sopenharmony_ci xcb_generic_error_t *error; 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci cookie = xcb_get_image (dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, 208bf215546Sopenharmony_ci dri2_surf->drawable, x, y, w, h, ~0); 209bf215546Sopenharmony_ci reply = xcb_get_image_reply (dri2_dpy->conn, cookie, &error); 210bf215546Sopenharmony_ci if (reply == NULL) 211bf215546Sopenharmony_ci return; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci if (error != NULL) { 214bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "error in xcb_get_image"); 215bf215546Sopenharmony_ci free(error); 216bf215546Sopenharmony_ci } else { 217bf215546Sopenharmony_ci uint32_t bytes = xcb_get_image_data_length(reply); 218bf215546Sopenharmony_ci uint8_t *idata = xcb_get_image_data(reply); 219bf215546Sopenharmony_ci memcpy(data, idata, bytes); 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci free(reply); 222bf215546Sopenharmony_ci} 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_cistatic xcb_screen_t * 226bf215546Sopenharmony_ciget_xcb_screen(xcb_screen_iterator_t iter, int screen) 227bf215546Sopenharmony_ci{ 228bf215546Sopenharmony_ci for (; iter.rem; --screen, xcb_screen_next(&iter)) 229bf215546Sopenharmony_ci if (screen == 0) 230bf215546Sopenharmony_ci return iter.data; 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci return NULL; 233bf215546Sopenharmony_ci} 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_cistatic xcb_visualtype_t * 236bf215546Sopenharmony_ciget_xcb_visualtype_for_depth(struct dri2_egl_display *dri2_dpy, int depth) 237bf215546Sopenharmony_ci{ 238bf215546Sopenharmony_ci xcb_visualtype_iterator_t visual_iter; 239bf215546Sopenharmony_ci xcb_screen_t *screen = dri2_dpy->screen; 240bf215546Sopenharmony_ci xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen); 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci for (; depth_iter.rem; xcb_depth_next(&depth_iter)) { 243bf215546Sopenharmony_ci if (depth_iter.data->depth != depth) 244bf215546Sopenharmony_ci continue; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci visual_iter = xcb_depth_visuals_iterator(depth_iter.data); 247bf215546Sopenharmony_ci if (visual_iter.rem) 248bf215546Sopenharmony_ci return visual_iter.data; 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci return NULL; 252bf215546Sopenharmony_ci} 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci/* Get red channel mask for given depth. */ 255bf215546Sopenharmony_ciunsigned int 256bf215546Sopenharmony_cidri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth) 257bf215546Sopenharmony_ci{ 258bf215546Sopenharmony_ci xcb_visualtype_t *visual = get_xcb_visualtype_for_depth(dri2_dpy, depth); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci if (visual) 261bf215546Sopenharmony_ci return visual->red_mask; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci return 0; 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci/** 267bf215546Sopenharmony_ci * Called via eglCreateWindowSurface(), drv->CreateWindowSurface(). 268bf215546Sopenharmony_ci */ 269bf215546Sopenharmony_cistatic _EGLSurface * 270bf215546Sopenharmony_cidri2_x11_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, 271bf215546Sopenharmony_ci void *native_surface, const EGLint *attrib_list) 272bf215546Sopenharmony_ci{ 273bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 274bf215546Sopenharmony_ci struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); 275bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf; 276bf215546Sopenharmony_ci xcb_get_geometry_cookie_t cookie; 277bf215546Sopenharmony_ci xcb_get_geometry_reply_t *reply; 278bf215546Sopenharmony_ci xcb_generic_error_t *error; 279bf215546Sopenharmony_ci const __DRIconfig *config; 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci dri2_surf = calloc(1, sizeof *dri2_surf); 282bf215546Sopenharmony_ci if (!dri2_surf) { 283bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); 284bf215546Sopenharmony_ci return NULL; 285bf215546Sopenharmony_ci } 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci if (!dri2_init_surface(&dri2_surf->base, disp, type, conf, attrib_list, 288bf215546Sopenharmony_ci false, native_surface)) 289bf215546Sopenharmony_ci goto cleanup_surf; 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci dri2_surf->region = XCB_NONE; 292bf215546Sopenharmony_ci if (type == EGL_PBUFFER_BIT) { 293bf215546Sopenharmony_ci dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn); 294bf215546Sopenharmony_ci xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, 295bf215546Sopenharmony_ci dri2_surf->drawable, dri2_dpy->screen->root, 296bf215546Sopenharmony_ci dri2_surf->base.Width, dri2_surf->base.Height); 297bf215546Sopenharmony_ci } else { 298bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_surface)); 299bf215546Sopenharmony_ci dri2_surf->drawable = (uintptr_t) native_surface; 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci config = dri2_get_dri_config(dri2_conf, type, 303bf215546Sopenharmony_ci dri2_surf->base.GLColorspace); 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci if (!config) { 306bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration"); 307bf215546Sopenharmony_ci goto cleanup_pixmap; 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci if (type != EGL_PBUFFER_BIT) { 311bf215546Sopenharmony_ci cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); 312bf215546Sopenharmony_ci reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); 313bf215546Sopenharmony_ci if (error != NULL) { 314bf215546Sopenharmony_ci if (error->error_code == BadAlloc) 315bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); 316bf215546Sopenharmony_ci else if (type == EGL_WINDOW_BIT) 317bf215546Sopenharmony_ci _eglError(EGL_BAD_NATIVE_WINDOW, "xcb_get_geometry"); 318bf215546Sopenharmony_ci else 319bf215546Sopenharmony_ci _eglError(EGL_BAD_NATIVE_PIXMAP, "xcb_get_geometry"); 320bf215546Sopenharmony_ci free(error); 321bf215546Sopenharmony_ci free(reply); 322bf215546Sopenharmony_ci goto cleanup_dri_drawable; 323bf215546Sopenharmony_ci } else if (reply == NULL) { 324bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); 325bf215546Sopenharmony_ci goto cleanup_dri_drawable; 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci dri2_surf->base.Width = reply->width; 329bf215546Sopenharmony_ci dri2_surf->base.Height = reply->height; 330bf215546Sopenharmony_ci dri2_surf->depth = reply->depth; 331bf215546Sopenharmony_ci free(reply); 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf)) 335bf215546Sopenharmony_ci goto cleanup_pixmap; 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci if (dri2_dpy->dri2) { 338bf215546Sopenharmony_ci xcb_void_cookie_t cookie; 339bf215546Sopenharmony_ci int conn_error; 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci cookie = xcb_dri2_create_drawable_checked(dri2_dpy->conn, 342bf215546Sopenharmony_ci dri2_surf->drawable); 343bf215546Sopenharmony_ci error = xcb_request_check(dri2_dpy->conn, cookie); 344bf215546Sopenharmony_ci conn_error = xcb_connection_has_error(dri2_dpy->conn); 345bf215546Sopenharmony_ci if (conn_error || error != NULL) { 346bf215546Sopenharmony_ci if (type == EGL_PBUFFER_BIT || conn_error || error->error_code == BadAlloc) 347bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "xcb_dri2_create_drawable_checked"); 348bf215546Sopenharmony_ci else if (type == EGL_WINDOW_BIT) 349bf215546Sopenharmony_ci _eglError(EGL_BAD_NATIVE_WINDOW, 350bf215546Sopenharmony_ci "xcb_dri2_create_drawable_checked"); 351bf215546Sopenharmony_ci else 352bf215546Sopenharmony_ci _eglError(EGL_BAD_NATIVE_PIXMAP, 353bf215546Sopenharmony_ci "xcb_dri2_create_drawable_checked"); 354bf215546Sopenharmony_ci free(error); 355bf215546Sopenharmony_ci goto cleanup_dri_drawable; 356bf215546Sopenharmony_ci } 357bf215546Sopenharmony_ci } else { 358bf215546Sopenharmony_ci if (type == EGL_PBUFFER_BIT) { 359bf215546Sopenharmony_ci dri2_surf->depth = conf->BufferSize; 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci swrastCreateDrawable(dri2_dpy, dri2_surf); 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci /* we always copy the back buffer to front */ 365bf215546Sopenharmony_ci dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE; 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci return &dri2_surf->base; 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci cleanup_dri_drawable: 370bf215546Sopenharmony_ci dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); 371bf215546Sopenharmony_ci cleanup_pixmap: 372bf215546Sopenharmony_ci if (type == EGL_PBUFFER_BIT) 373bf215546Sopenharmony_ci xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable); 374bf215546Sopenharmony_ci cleanup_surf: 375bf215546Sopenharmony_ci free(dri2_surf); 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci return NULL; 378bf215546Sopenharmony_ci} 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci/** 381bf215546Sopenharmony_ci * Called via eglCreateWindowSurface(), drv->CreateWindowSurface(). 382bf215546Sopenharmony_ci */ 383bf215546Sopenharmony_cistatic _EGLSurface * 384bf215546Sopenharmony_cidri2_x11_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, 385bf215546Sopenharmony_ci void *native_window, const EGLint *attrib_list) 386bf215546Sopenharmony_ci{ 387bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 388bf215546Sopenharmony_ci _EGLSurface *surf; 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci surf = dri2_x11_create_surface(disp, EGL_WINDOW_BIT, conf, 391bf215546Sopenharmony_ci native_window, attrib_list); 392bf215546Sopenharmony_ci if (surf != NULL) { 393bf215546Sopenharmony_ci /* When we first create the DRI2 drawable, its swap interval on the 394bf215546Sopenharmony_ci * server side is 1. 395bf215546Sopenharmony_ci */ 396bf215546Sopenharmony_ci surf->SwapInterval = 1; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci /* Override that with a driconf-set value. */ 399bf215546Sopenharmony_ci dri2_x11_swap_interval(disp, surf, dri2_dpy->default_swap_interval); 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci return surf; 403bf215546Sopenharmony_ci} 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_cistatic _EGLSurface * 406bf215546Sopenharmony_cidri2_x11_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf, 407bf215546Sopenharmony_ci void *native_pixmap, const EGLint *attrib_list) 408bf215546Sopenharmony_ci{ 409bf215546Sopenharmony_ci return dri2_x11_create_surface(disp, EGL_PIXMAP_BIT, conf, 410bf215546Sopenharmony_ci native_pixmap, attrib_list); 411bf215546Sopenharmony_ci} 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_cistatic _EGLSurface * 414bf215546Sopenharmony_cidri2_x11_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf, 415bf215546Sopenharmony_ci const EGLint *attrib_list) 416bf215546Sopenharmony_ci{ 417bf215546Sopenharmony_ci return dri2_x11_create_surface(disp, EGL_PBUFFER_BIT, conf, 418bf215546Sopenharmony_ci NULL, attrib_list); 419bf215546Sopenharmony_ci} 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_cistatic EGLBoolean 422bf215546Sopenharmony_cidri2_x11_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 425bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci if (dri2_dpy->dri2) { 430bf215546Sopenharmony_ci xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable); 431bf215546Sopenharmony_ci } else { 432bf215546Sopenharmony_ci assert(dri2_dpy->swrast); 433bf215546Sopenharmony_ci swrastDestroyDrawable(dri2_dpy, dri2_surf); 434bf215546Sopenharmony_ci } 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci if (surf->Type == EGL_PBUFFER_BIT) 437bf215546Sopenharmony_ci xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable); 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci dri2_fini_surface(surf); 440bf215546Sopenharmony_ci free(surf); 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci return EGL_TRUE; 443bf215546Sopenharmony_ci} 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci/** 446bf215546Sopenharmony_ci * Function utilizes swrastGetDrawableInfo to get surface 447bf215546Sopenharmony_ci * geometry from x server and calls default query surface 448bf215546Sopenharmony_ci * implementation that returns the updated values. 449bf215546Sopenharmony_ci * 450bf215546Sopenharmony_ci * In case of errors we still return values that we currently 451bf215546Sopenharmony_ci * have. 452bf215546Sopenharmony_ci */ 453bf215546Sopenharmony_cistatic EGLBoolean 454bf215546Sopenharmony_cidri2_query_surface(_EGLDisplay *disp, _EGLSurface *surf, 455bf215546Sopenharmony_ci EGLint attribute, EGLint *value) 456bf215546Sopenharmony_ci{ 457bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 458bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 459bf215546Sopenharmony_ci int x, y, w, h; 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci __DRIdrawable *drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci switch (attribute) { 464bf215546Sopenharmony_ci case EGL_WIDTH: 465bf215546Sopenharmony_ci case EGL_HEIGHT: 466bf215546Sopenharmony_ci if (x11_get_drawable_info(drawable, &x, &y, &w, &h, dri2_surf)) { 467bf215546Sopenharmony_ci surf->Width = w; 468bf215546Sopenharmony_ci surf->Height = h; 469bf215546Sopenharmony_ci } 470bf215546Sopenharmony_ci break; 471bf215546Sopenharmony_ci default: 472bf215546Sopenharmony_ci break; 473bf215546Sopenharmony_ci } 474bf215546Sopenharmony_ci return _eglQuerySurface(disp, surf, attribute, value); 475bf215546Sopenharmony_ci} 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci/** 478bf215546Sopenharmony_ci * Process list of buffer received from the server 479bf215546Sopenharmony_ci * 480bf215546Sopenharmony_ci * Processes the list of buffers received in a reply from the server to either 481bf215546Sopenharmony_ci * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat. 482bf215546Sopenharmony_ci */ 483bf215546Sopenharmony_cistatic void 484bf215546Sopenharmony_cidri2_x11_process_buffers(struct dri2_egl_surface *dri2_surf, 485bf215546Sopenharmony_ci xcb_dri2_dri2_buffer_t *buffers, unsigned count) 486bf215546Sopenharmony_ci{ 487bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = 488bf215546Sopenharmony_ci dri2_egl_display(dri2_surf->base.Resource.Display); 489bf215546Sopenharmony_ci xcb_rectangle_t rectangle; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci dri2_surf->have_fake_front = false; 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci /* This assumes the DRI2 buffer attachment tokens matches the 494bf215546Sopenharmony_ci * __DRIbuffer tokens. */ 495bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) { 496bf215546Sopenharmony_ci dri2_surf->buffers[i].attachment = buffers[i].attachment; 497bf215546Sopenharmony_ci dri2_surf->buffers[i].name = buffers[i].name; 498bf215546Sopenharmony_ci dri2_surf->buffers[i].pitch = buffers[i].pitch; 499bf215546Sopenharmony_ci dri2_surf->buffers[i].cpp = buffers[i].cpp; 500bf215546Sopenharmony_ci dri2_surf->buffers[i].flags = buffers[i].flags; 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci /* We only use the DRI drivers single buffer configs. This 503bf215546Sopenharmony_ci * means that if we try to render to a window, DRI2 will give us 504bf215546Sopenharmony_ci * the fake front buffer, which we'll use as a back buffer. 505bf215546Sopenharmony_ci * Note that EGL doesn't require that several clients rendering 506bf215546Sopenharmony_ci * to the same window must see the same aux buffers. */ 507bf215546Sopenharmony_ci if (dri2_surf->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT) 508bf215546Sopenharmony_ci dri2_surf->have_fake_front = true; 509bf215546Sopenharmony_ci } 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci if (dri2_surf->region != XCB_NONE) 512bf215546Sopenharmony_ci xcb_xfixes_destroy_region(dri2_dpy->conn, dri2_surf->region); 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci rectangle.x = 0; 515bf215546Sopenharmony_ci rectangle.y = 0; 516bf215546Sopenharmony_ci rectangle.width = dri2_surf->base.Width; 517bf215546Sopenharmony_ci rectangle.height = dri2_surf->base.Height; 518bf215546Sopenharmony_ci dri2_surf->region = xcb_generate_id(dri2_dpy->conn); 519bf215546Sopenharmony_ci xcb_xfixes_create_region(dri2_dpy->conn, dri2_surf->region, 1, &rectangle); 520bf215546Sopenharmony_ci} 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_cistatic __DRIbuffer * 523bf215546Sopenharmony_cidri2_x11_get_buffers(__DRIdrawable * driDrawable, 524bf215546Sopenharmony_ci int *width, int *height, 525bf215546Sopenharmony_ci unsigned int *attachments, int count, 526bf215546Sopenharmony_ci int *out_count, void *loaderPrivate) 527bf215546Sopenharmony_ci{ 528bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 529bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = 530bf215546Sopenharmony_ci dri2_egl_display(dri2_surf->base.Resource.Display); 531bf215546Sopenharmony_ci xcb_dri2_dri2_buffer_t *buffers; 532bf215546Sopenharmony_ci xcb_dri2_get_buffers_reply_t *reply; 533bf215546Sopenharmony_ci xcb_dri2_get_buffers_cookie_t cookie; 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_ci (void) driDrawable; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn, 538bf215546Sopenharmony_ci dri2_surf->drawable, 539bf215546Sopenharmony_ci count, count, attachments); 540bf215546Sopenharmony_ci reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, cookie, NULL); 541bf215546Sopenharmony_ci if (reply == NULL) 542bf215546Sopenharmony_ci return NULL; 543bf215546Sopenharmony_ci buffers = xcb_dri2_get_buffers_buffers (reply); 544bf215546Sopenharmony_ci if (buffers == NULL) { 545bf215546Sopenharmony_ci free(reply); 546bf215546Sopenharmony_ci return NULL; 547bf215546Sopenharmony_ci } 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci *out_count = reply->count; 550bf215546Sopenharmony_ci dri2_surf->base.Width = *width = reply->width; 551bf215546Sopenharmony_ci dri2_surf->base.Height = *height = reply->height; 552bf215546Sopenharmony_ci dri2_x11_process_buffers(dri2_surf, buffers, *out_count); 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci free(reply); 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci return dri2_surf->buffers; 557bf215546Sopenharmony_ci} 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_cistatic __DRIbuffer * 560bf215546Sopenharmony_cidri2_x11_get_buffers_with_format(__DRIdrawable * driDrawable, 561bf215546Sopenharmony_ci int *width, int *height, 562bf215546Sopenharmony_ci unsigned int *attachments, int count, 563bf215546Sopenharmony_ci int *out_count, void *loaderPrivate) 564bf215546Sopenharmony_ci{ 565bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 566bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = 567bf215546Sopenharmony_ci dri2_egl_display(dri2_surf->base.Resource.Display); 568bf215546Sopenharmony_ci xcb_dri2_dri2_buffer_t *buffers; 569bf215546Sopenharmony_ci xcb_dri2_get_buffers_with_format_reply_t *reply; 570bf215546Sopenharmony_ci xcb_dri2_get_buffers_with_format_cookie_t cookie; 571bf215546Sopenharmony_ci xcb_dri2_attach_format_t *format_attachments; 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci (void) driDrawable; 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_ci format_attachments = (xcb_dri2_attach_format_t *) attachments; 576bf215546Sopenharmony_ci cookie = xcb_dri2_get_buffers_with_format_unchecked (dri2_dpy->conn, 577bf215546Sopenharmony_ci dri2_surf->drawable, 578bf215546Sopenharmony_ci count, count, 579bf215546Sopenharmony_ci format_attachments); 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci reply = xcb_dri2_get_buffers_with_format_reply (dri2_dpy->conn, 582bf215546Sopenharmony_ci cookie, NULL); 583bf215546Sopenharmony_ci if (reply == NULL) 584bf215546Sopenharmony_ci return NULL; 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci buffers = xcb_dri2_get_buffers_with_format_buffers (reply); 587bf215546Sopenharmony_ci dri2_surf->base.Width = *width = reply->width; 588bf215546Sopenharmony_ci dri2_surf->base.Height = *height = reply->height; 589bf215546Sopenharmony_ci *out_count = reply->count; 590bf215546Sopenharmony_ci dri2_x11_process_buffers(dri2_surf, buffers, *out_count); 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci free(reply); 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci return dri2_surf->buffers; 595bf215546Sopenharmony_ci} 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_cistatic void 598bf215546Sopenharmony_cidri2_x11_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) 599bf215546Sopenharmony_ci{ 600bf215546Sopenharmony_ci (void) driDrawable; 601bf215546Sopenharmony_ci 602bf215546Sopenharmony_ci /* FIXME: Does EGL support front buffer rendering at all? */ 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci#if 0 605bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci dri2WaitGL(dri2_surf); 608bf215546Sopenharmony_ci#else 609bf215546Sopenharmony_ci (void) loaderPrivate; 610bf215546Sopenharmony_ci#endif 611bf215546Sopenharmony_ci} 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_cistatic int 614bf215546Sopenharmony_cidri2_x11_do_authenticate(struct dri2_egl_display *dri2_dpy, uint32_t id) 615bf215546Sopenharmony_ci{ 616bf215546Sopenharmony_ci xcb_dri2_authenticate_reply_t *authenticate; 617bf215546Sopenharmony_ci xcb_dri2_authenticate_cookie_t authenticate_cookie; 618bf215546Sopenharmony_ci int ret = 0; 619bf215546Sopenharmony_ci 620bf215546Sopenharmony_ci authenticate_cookie = 621bf215546Sopenharmony_ci xcb_dri2_authenticate_unchecked(dri2_dpy->conn, dri2_dpy->screen->root, id); 622bf215546Sopenharmony_ci authenticate = 623bf215546Sopenharmony_ci xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL); 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci if (authenticate == NULL || !authenticate->authenticated) 626bf215546Sopenharmony_ci ret = -1; 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci free(authenticate); 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci return ret; 631bf215546Sopenharmony_ci} 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_cistatic EGLBoolean 634bf215546Sopenharmony_cidri2_x11_local_authenticate(struct dri2_egl_display *dri2_dpy) 635bf215546Sopenharmony_ci{ 636bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 637bf215546Sopenharmony_ci drm_magic_t magic; 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_ci if (drmGetMagic(dri2_dpy->fd, &magic)) { 640bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to get drm magic"); 641bf215546Sopenharmony_ci return EGL_FALSE; 642bf215546Sopenharmony_ci } 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci if (dri2_x11_do_authenticate(dri2_dpy, magic) < 0) { 645bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to authenticate"); 646bf215546Sopenharmony_ci return EGL_FALSE; 647bf215546Sopenharmony_ci } 648bf215546Sopenharmony_ci#endif 649bf215546Sopenharmony_ci return EGL_TRUE; 650bf215546Sopenharmony_ci} 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_cistatic EGLBoolean 653bf215546Sopenharmony_cidri2_x11_connect(struct dri2_egl_display *dri2_dpy) 654bf215546Sopenharmony_ci{ 655bf215546Sopenharmony_ci xcb_xfixes_query_version_reply_t *xfixes_query; 656bf215546Sopenharmony_ci xcb_xfixes_query_version_cookie_t xfixes_query_cookie; 657bf215546Sopenharmony_ci xcb_dri2_query_version_reply_t *dri2_query; 658bf215546Sopenharmony_ci xcb_dri2_query_version_cookie_t dri2_query_cookie; 659bf215546Sopenharmony_ci xcb_dri2_connect_reply_t *connect; 660bf215546Sopenharmony_ci xcb_dri2_connect_cookie_t connect_cookie; 661bf215546Sopenharmony_ci xcb_generic_error_t *error; 662bf215546Sopenharmony_ci char *driver_name, *loader_driver_name, *device_name; 663bf215546Sopenharmony_ci const xcb_query_extension_reply_t *extension; 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id); 666bf215546Sopenharmony_ci xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id); 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_xfixes_id); 669bf215546Sopenharmony_ci if (!(extension && extension->present)) 670bf215546Sopenharmony_ci return EGL_FALSE; 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri2_id); 673bf215546Sopenharmony_ci if (!(extension && extension->present)) 674bf215546Sopenharmony_ci return EGL_FALSE; 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn, 677bf215546Sopenharmony_ci XCB_XFIXES_MAJOR_VERSION, 678bf215546Sopenharmony_ci XCB_XFIXES_MINOR_VERSION); 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci dri2_query_cookie = xcb_dri2_query_version (dri2_dpy->conn, 681bf215546Sopenharmony_ci XCB_DRI2_MAJOR_VERSION, 682bf215546Sopenharmony_ci XCB_DRI2_MINOR_VERSION); 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci connect_cookie = xcb_dri2_connect_unchecked(dri2_dpy->conn, dri2_dpy->screen->root, 685bf215546Sopenharmony_ci XCB_DRI2_DRIVER_TYPE_DRI); 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci xfixes_query = 688bf215546Sopenharmony_ci xcb_xfixes_query_version_reply (dri2_dpy->conn, 689bf215546Sopenharmony_ci xfixes_query_cookie, &error); 690bf215546Sopenharmony_ci if (xfixes_query == NULL || 691bf215546Sopenharmony_ci error != NULL || xfixes_query->major_version < 2) { 692bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to query xfixes version"); 693bf215546Sopenharmony_ci free(error); 694bf215546Sopenharmony_ci free(xfixes_query); 695bf215546Sopenharmony_ci return EGL_FALSE; 696bf215546Sopenharmony_ci } 697bf215546Sopenharmony_ci free(xfixes_query); 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci dri2_query = 700bf215546Sopenharmony_ci xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error); 701bf215546Sopenharmony_ci if (dri2_query == NULL || error != NULL) { 702bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to query version"); 703bf215546Sopenharmony_ci free(error); 704bf215546Sopenharmony_ci free(dri2_query); 705bf215546Sopenharmony_ci return EGL_FALSE; 706bf215546Sopenharmony_ci } 707bf215546Sopenharmony_ci dri2_dpy->dri2_major = dri2_query->major_version; 708bf215546Sopenharmony_ci dri2_dpy->dri2_minor = dri2_query->minor_version; 709bf215546Sopenharmony_ci free(dri2_query); 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL); 712bf215546Sopenharmony_ci if (connect == NULL || 713bf215546Sopenharmony_ci connect->driver_name_length + connect->device_name_length == 0) { 714bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to authenticate"); 715bf215546Sopenharmony_ci free(connect); 716bf215546Sopenharmony_ci return EGL_FALSE; 717bf215546Sopenharmony_ci } 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci device_name = xcb_dri2_connect_device_name (connect); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci dri2_dpy->fd = loader_open_device(device_name); 722bf215546Sopenharmony_ci if (dri2_dpy->fd == -1) { 723bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, 724bf215546Sopenharmony_ci "DRI2: could not open %s (%s)", device_name, strerror(errno)); 725bf215546Sopenharmony_ci free(connect); 726bf215546Sopenharmony_ci return EGL_FALSE; 727bf215546Sopenharmony_ci } 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci if (!dri2_x11_local_authenticate(dri2_dpy)) { 730bf215546Sopenharmony_ci close(dri2_dpy->fd); 731bf215546Sopenharmony_ci free(connect); 732bf215546Sopenharmony_ci return EGL_FALSE; 733bf215546Sopenharmony_ci } 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci driver_name = xcb_dri2_connect_driver_name (connect); 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci /* If Mesa knows about the appropriate driver for this fd, then trust it. 738bf215546Sopenharmony_ci * Otherwise, default to the server's value. 739bf215546Sopenharmony_ci */ 740bf215546Sopenharmony_ci loader_driver_name = loader_get_driver_for_fd(dri2_dpy->fd); 741bf215546Sopenharmony_ci if (loader_driver_name) { 742bf215546Sopenharmony_ci dri2_dpy->driver_name = loader_driver_name; 743bf215546Sopenharmony_ci } else { 744bf215546Sopenharmony_ci dri2_dpy->driver_name = 745bf215546Sopenharmony_ci strndup(driver_name, 746bf215546Sopenharmony_ci xcb_dri2_connect_driver_name_length(connect)); 747bf215546Sopenharmony_ci } 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ci if (dri2_dpy->driver_name == NULL) { 750bf215546Sopenharmony_ci close(dri2_dpy->fd); 751bf215546Sopenharmony_ci free(connect); 752bf215546Sopenharmony_ci return EGL_FALSE; 753bf215546Sopenharmony_ci } 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 756bf215546Sopenharmony_ci dri2_dpy->device_name = 757bf215546Sopenharmony_ci strndup(device_name, 758bf215546Sopenharmony_ci xcb_dri2_connect_device_name_length(connect)); 759bf215546Sopenharmony_ci#endif 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci free(connect); 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci return EGL_TRUE; 764bf215546Sopenharmony_ci} 765bf215546Sopenharmony_ci 766bf215546Sopenharmony_cistatic int 767bf215546Sopenharmony_cidri2_x11_authenticate(_EGLDisplay *disp, uint32_t id) 768bf215546Sopenharmony_ci{ 769bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci return dri2_x11_do_authenticate(dri2_dpy, id); 772bf215546Sopenharmony_ci} 773bf215546Sopenharmony_ci 774bf215546Sopenharmony_cistatic EGLBoolean 775bf215546Sopenharmony_cidri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy, 776bf215546Sopenharmony_ci _EGLDisplay *disp, bool supports_preserved) 777bf215546Sopenharmony_ci{ 778bf215546Sopenharmony_ci xcb_depth_iterator_t d; 779bf215546Sopenharmony_ci xcb_visualtype_t *visuals; 780bf215546Sopenharmony_ci int config_count = 0; 781bf215546Sopenharmony_ci EGLint surface_type; 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci d = xcb_screen_allowed_depths_iterator(dri2_dpy->screen); 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci surface_type = 786bf215546Sopenharmony_ci EGL_WINDOW_BIT | 787bf215546Sopenharmony_ci EGL_PIXMAP_BIT | 788bf215546Sopenharmony_ci EGL_PBUFFER_BIT; 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci if (supports_preserved) 791bf215546Sopenharmony_ci surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT; 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci while (d.rem > 0) { 794bf215546Sopenharmony_ci EGLBoolean class_added[6] = { 0, }; 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci visuals = xcb_depth_visuals(d.data); 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci for (int i = 0; i < xcb_depth_visuals_length(d.data); i++) { 799bf215546Sopenharmony_ci if (class_added[visuals[i]._class]) 800bf215546Sopenharmony_ci continue; 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci class_added[visuals[i]._class] = EGL_TRUE; 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_ci for (int j = 0; dri2_dpy->driver_configs[j]; j++) { 805bf215546Sopenharmony_ci struct dri2_egl_config *dri2_conf; 806bf215546Sopenharmony_ci const __DRIconfig *config = dri2_dpy->driver_configs[j]; 807bf215546Sopenharmony_ci 808bf215546Sopenharmony_ci const EGLint config_attrs[] = { 809bf215546Sopenharmony_ci EGL_NATIVE_VISUAL_ID, visuals[i].visual_id, 810bf215546Sopenharmony_ci EGL_NATIVE_VISUAL_TYPE, visuals[i]._class, 811bf215546Sopenharmony_ci EGL_NONE 812bf215546Sopenharmony_ci }; 813bf215546Sopenharmony_ci 814bf215546Sopenharmony_ci int rgba_shifts[4] = { 815bf215546Sopenharmony_ci ffs(visuals[i].red_mask) - 1, 816bf215546Sopenharmony_ci ffs(visuals[i].green_mask) - 1, 817bf215546Sopenharmony_ci ffs(visuals[i].blue_mask) - 1, 818bf215546Sopenharmony_ci -1, 819bf215546Sopenharmony_ci }; 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci unsigned int rgba_sizes[4] = { 822bf215546Sopenharmony_ci util_bitcount(visuals[i].red_mask), 823bf215546Sopenharmony_ci util_bitcount(visuals[i].green_mask), 824bf215546Sopenharmony_ci util_bitcount(visuals[i].blue_mask), 825bf215546Sopenharmony_ci 0, 826bf215546Sopenharmony_ci }; 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci dri2_conf = dri2_add_config(disp, config, config_count + 1, 829bf215546Sopenharmony_ci surface_type, config_attrs, 830bf215546Sopenharmony_ci rgba_shifts, rgba_sizes); 831bf215546Sopenharmony_ci if (dri2_conf) 832bf215546Sopenharmony_ci if (dri2_conf->base.ConfigID == config_count + 1) 833bf215546Sopenharmony_ci config_count++; 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci /* Allow a 24-bit RGB visual to match a 32-bit RGBA EGLConfig. 836bf215546Sopenharmony_ci * Ditto for 30-bit RGB visuals to match a 32-bit RGBA EGLConfig. 837bf215546Sopenharmony_ci * Otherwise it will only match a 32-bit RGBA visual. On a 838bf215546Sopenharmony_ci * composited window manager on X11, this will make all of the 839bf215546Sopenharmony_ci * EGLConfigs with destination alpha get blended by the 840bf215546Sopenharmony_ci * compositor. This is probably not what the application 841bf215546Sopenharmony_ci * wants... especially on drivers that only have 32-bit RGBA 842bf215546Sopenharmony_ci * EGLConfigs! */ 843bf215546Sopenharmony_ci if (d.data->depth == 24 || d.data->depth == 30) { 844bf215546Sopenharmony_ci unsigned int rgba_mask = ~(visuals[i].red_mask | 845bf215546Sopenharmony_ci visuals[i].green_mask | 846bf215546Sopenharmony_ci visuals[i].blue_mask); 847bf215546Sopenharmony_ci rgba_shifts[3] = ffs(rgba_mask) - 1; 848bf215546Sopenharmony_ci rgba_sizes[3] = util_bitcount(rgba_mask); 849bf215546Sopenharmony_ci dri2_conf = dri2_add_config(disp, config, config_count + 1, 850bf215546Sopenharmony_ci surface_type, config_attrs, 851bf215546Sopenharmony_ci rgba_shifts, rgba_sizes); 852bf215546Sopenharmony_ci if (dri2_conf) 853bf215546Sopenharmony_ci if (dri2_conf->base.ConfigID == config_count + 1) 854bf215546Sopenharmony_ci config_count++; 855bf215546Sopenharmony_ci } 856bf215546Sopenharmony_ci } 857bf215546Sopenharmony_ci } 858bf215546Sopenharmony_ci 859bf215546Sopenharmony_ci xcb_depth_next(&d); 860bf215546Sopenharmony_ci } 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_ci if (!config_count) { 863bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to create any config"); 864bf215546Sopenharmony_ci return EGL_FALSE; 865bf215546Sopenharmony_ci } 866bf215546Sopenharmony_ci 867bf215546Sopenharmony_ci return EGL_TRUE; 868bf215546Sopenharmony_ci} 869bf215546Sopenharmony_ci 870bf215546Sopenharmony_cistatic EGLBoolean 871bf215546Sopenharmony_cidri2_copy_region(_EGLDisplay *disp, 872bf215546Sopenharmony_ci _EGLSurface *draw, xcb_xfixes_region_t region) 873bf215546Sopenharmony_ci{ 874bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 875bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); 876bf215546Sopenharmony_ci enum xcb_dri2_attachment_t render_attachment; 877bf215546Sopenharmony_ci xcb_dri2_copy_region_cookie_t cookie; 878bf215546Sopenharmony_ci 879bf215546Sopenharmony_ci /* No-op for a pixmap or pbuffer surface */ 880bf215546Sopenharmony_ci if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) 881bf215546Sopenharmony_ci return EGL_TRUE; 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci if (dri2_dpy->flush) 884bf215546Sopenharmony_ci dri2_dpy->flush->flush(dri2_surf->dri_drawable); 885bf215546Sopenharmony_ci else 886bf215546Sopenharmony_ci dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ci if (dri2_surf->have_fake_front) 889bf215546Sopenharmony_ci render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT; 890bf215546Sopenharmony_ci else 891bf215546Sopenharmony_ci render_attachment = XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT; 892bf215546Sopenharmony_ci 893bf215546Sopenharmony_ci cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn, 894bf215546Sopenharmony_ci dri2_surf->drawable, 895bf215546Sopenharmony_ci region, 896bf215546Sopenharmony_ci XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT, 897bf215546Sopenharmony_ci render_attachment); 898bf215546Sopenharmony_ci free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL)); 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci return EGL_TRUE; 901bf215546Sopenharmony_ci} 902bf215546Sopenharmony_ci 903bf215546Sopenharmony_cistatic int64_t 904bf215546Sopenharmony_cidri2_x11_swap_buffers_msc(_EGLDisplay *disp, _EGLSurface *draw, 905bf215546Sopenharmony_ci int64_t msc, int64_t divisor, int64_t remainder) 906bf215546Sopenharmony_ci{ 907bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 908bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); 909bf215546Sopenharmony_ci uint32_t msc_hi = msc >> 32; 910bf215546Sopenharmony_ci uint32_t msc_lo = msc & 0xffffffff; 911bf215546Sopenharmony_ci uint32_t divisor_hi = divisor >> 32; 912bf215546Sopenharmony_ci uint32_t divisor_lo = divisor & 0xffffffff; 913bf215546Sopenharmony_ci uint32_t remainder_hi = remainder >> 32; 914bf215546Sopenharmony_ci uint32_t remainder_lo = remainder & 0xffffffff; 915bf215546Sopenharmony_ci xcb_dri2_swap_buffers_cookie_t cookie; 916bf215546Sopenharmony_ci xcb_dri2_swap_buffers_reply_t *reply; 917bf215546Sopenharmony_ci int64_t swap_count = -1; 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_ci if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available) { 920bf215546Sopenharmony_ci swap_count = dri2_copy_region(disp, draw, dri2_surf->region) ? 0 : -1; 921bf215546Sopenharmony_ci } else { 922bf215546Sopenharmony_ci dri2_flush_drawable_for_swapbuffers(disp, draw); 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, 925bf215546Sopenharmony_ci dri2_surf->drawable, msc_hi, 926bf215546Sopenharmony_ci msc_lo, divisor_hi, divisor_lo, 927bf215546Sopenharmony_ci remainder_hi, remainder_lo); 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL); 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci if (reply) { 932bf215546Sopenharmony_ci swap_count = combine_u32_into_u64(reply->swap_hi, reply->swap_lo); 933bf215546Sopenharmony_ci free(reply); 934bf215546Sopenharmony_ci } 935bf215546Sopenharmony_ci } 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci /* Since we aren't watching for the server's invalidate events like we're 938bf215546Sopenharmony_ci * supposed to (due to XCB providing no mechanism for filtering the events 939bf215546Sopenharmony_ci * the way xlib does), and SwapBuffers is a common cause of invalidate 940bf215546Sopenharmony_ci * events, just shove one down to the driver, even though we haven't told 941bf215546Sopenharmony_ci * the driver that we're the kind of loader that provides reliable 942bf215546Sopenharmony_ci * invalidate events. This causes the driver to request buffers again at 943bf215546Sopenharmony_ci * its next draw, so that we get the correct buffers if a pageflip 944bf215546Sopenharmony_ci * happened. The driver should still be using the viewport hack to catch 945bf215546Sopenharmony_ci * window resizes. 946bf215546Sopenharmony_ci */ 947bf215546Sopenharmony_ci if (dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate) 948bf215546Sopenharmony_ci dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); 949bf215546Sopenharmony_ci 950bf215546Sopenharmony_ci return swap_count; 951bf215546Sopenharmony_ci} 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_cistatic EGLBoolean 954bf215546Sopenharmony_cidri2_x11_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) 955bf215546Sopenharmony_ci{ 956bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 957bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci if (!dri2_dpy->flush) { 960bf215546Sopenharmony_ci dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); 961bf215546Sopenharmony_ci return EGL_TRUE; 962bf215546Sopenharmony_ci } 963bf215546Sopenharmony_ci 964bf215546Sopenharmony_ci if (dri2_x11_swap_buffers_msc(disp, draw, 0, 0, 0) == -1) { 965bf215546Sopenharmony_ci /* Swap failed with a window drawable. */ 966bf215546Sopenharmony_ci return _eglError(EGL_BAD_NATIVE_WINDOW, __func__); 967bf215546Sopenharmony_ci } 968bf215546Sopenharmony_ci return EGL_TRUE; 969bf215546Sopenharmony_ci} 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_cistatic EGLBoolean 972bf215546Sopenharmony_cidri2_x11_swap_buffers_region(_EGLDisplay *disp, _EGLSurface *draw, 973bf215546Sopenharmony_ci EGLint numRects, const EGLint *rects) 974bf215546Sopenharmony_ci{ 975bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 976bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); 977bf215546Sopenharmony_ci EGLBoolean ret; 978bf215546Sopenharmony_ci xcb_xfixes_region_t region; 979bf215546Sopenharmony_ci xcb_rectangle_t rectangles[16]; 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_ci if (numRects > (int)ARRAY_SIZE(rectangles)) 982bf215546Sopenharmony_ci return dri2_copy_region(disp, draw, dri2_surf->region); 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci for (int i = 0; i < numRects; i++) { 985bf215546Sopenharmony_ci rectangles[i].x = rects[i * 4]; 986bf215546Sopenharmony_ci rectangles[i].y = dri2_surf->base.Height - rects[i * 4 + 1] - rects[i * 4 + 3]; 987bf215546Sopenharmony_ci rectangles[i].width = rects[i * 4 + 2]; 988bf215546Sopenharmony_ci rectangles[i].height = rects[i * 4 + 3]; 989bf215546Sopenharmony_ci } 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_ci region = xcb_generate_id(dri2_dpy->conn); 992bf215546Sopenharmony_ci xcb_xfixes_create_region(dri2_dpy->conn, region, numRects, rectangles); 993bf215546Sopenharmony_ci ret = dri2_copy_region(disp, draw, region); 994bf215546Sopenharmony_ci xcb_xfixes_destroy_region(dri2_dpy->conn, region); 995bf215546Sopenharmony_ci 996bf215546Sopenharmony_ci return ret; 997bf215546Sopenharmony_ci} 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_cistatic EGLBoolean 1000bf215546Sopenharmony_cidri2_x11_post_sub_buffer(_EGLDisplay *disp, _EGLSurface *draw, 1001bf215546Sopenharmony_ci EGLint x, EGLint y, EGLint width, EGLint height) 1002bf215546Sopenharmony_ci{ 1003bf215546Sopenharmony_ci const EGLint rect[4] = { x, y, width, height }; 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci if (x < 0 || y < 0 || width < 0 || height < 0) 1006bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "eglPostSubBufferNV"); 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci return dri2_x11_swap_buffers_region(disp, draw, 1, rect); 1009bf215546Sopenharmony_ci} 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_cistatic EGLBoolean 1012bf215546Sopenharmony_cidri2_x11_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval) 1013bf215546Sopenharmony_ci{ 1014bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1015bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1016bf215546Sopenharmony_ci 1017bf215546Sopenharmony_ci if (dri2_dpy->kopper) { 1018bf215546Sopenharmony_ci dri2_dpy->kopper->setSwapInterval(dri2_surf->dri_drawable, interval); 1019bf215546Sopenharmony_ci return EGL_TRUE; 1020bf215546Sopenharmony_ci } 1021bf215546Sopenharmony_ci 1022bf215546Sopenharmony_ci if (dri2_dpy->swap_available) 1023bf215546Sopenharmony_ci xcb_dri2_swap_interval(dri2_dpy->conn, dri2_surf->drawable, interval); 1024bf215546Sopenharmony_ci 1025bf215546Sopenharmony_ci return EGL_TRUE; 1026bf215546Sopenharmony_ci} 1027bf215546Sopenharmony_ci 1028bf215546Sopenharmony_cistatic EGLBoolean 1029bf215546Sopenharmony_cidri2_x11_copy_buffers(_EGLDisplay *disp, _EGLSurface *surf, void *native_pixmap_target) 1030bf215546Sopenharmony_ci{ 1031bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1032bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1033bf215546Sopenharmony_ci xcb_gcontext_t gc; 1034bf215546Sopenharmony_ci xcb_pixmap_t target; 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_pixmap_target)); 1037bf215546Sopenharmony_ci target = (uintptr_t) native_pixmap_target; 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci if (dri2_dpy->flush) 1040bf215546Sopenharmony_ci dri2_dpy->flush->flush(dri2_surf->dri_drawable); 1041bf215546Sopenharmony_ci else 1042bf215546Sopenharmony_ci dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); 1043bf215546Sopenharmony_ci 1044bf215546Sopenharmony_ci gc = xcb_generate_id(dri2_dpy->conn); 1045bf215546Sopenharmony_ci xcb_create_gc(dri2_dpy->conn, gc, target, 0, NULL); 1046bf215546Sopenharmony_ci xcb_copy_area(dri2_dpy->conn, 1047bf215546Sopenharmony_ci dri2_surf->drawable, 1048bf215546Sopenharmony_ci target, 1049bf215546Sopenharmony_ci gc, 1050bf215546Sopenharmony_ci 0, 0, 1051bf215546Sopenharmony_ci 0, 0, 1052bf215546Sopenharmony_ci dri2_surf->base.Width, 1053bf215546Sopenharmony_ci dri2_surf->base.Height); 1054bf215546Sopenharmony_ci xcb_free_gc(dri2_dpy->conn, gc); 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci return EGL_TRUE; 1057bf215546Sopenharmony_ci} 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ciuint32_t 1060bf215546Sopenharmony_cidri2_format_for_depth(struct dri2_egl_display *dri2_dpy, uint32_t depth) 1061bf215546Sopenharmony_ci{ 1062bf215546Sopenharmony_ci switch (depth) { 1063bf215546Sopenharmony_ci case 16: 1064bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_RGB565; 1065bf215546Sopenharmony_ci case 24: 1066bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_XRGB8888; 1067bf215546Sopenharmony_ci case 30: 1068bf215546Sopenharmony_ci /* Different preferred formats for different hw */ 1069bf215546Sopenharmony_ci if (dri2_x11_get_red_mask_for_depth(dri2_dpy, 30) == 0x3ff) 1070bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_XBGR2101010; 1071bf215546Sopenharmony_ci else 1072bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_XRGB2101010; 1073bf215546Sopenharmony_ci case 32: 1074bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_ARGB8888; 1075bf215546Sopenharmony_ci default: 1076bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_NONE; 1077bf215546Sopenharmony_ci } 1078bf215546Sopenharmony_ci} 1079bf215546Sopenharmony_ci 1080bf215546Sopenharmony_cistatic _EGLImage * 1081bf215546Sopenharmony_cidri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, 1082bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 1083bf215546Sopenharmony_ci{ 1084bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1085bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img; 1086bf215546Sopenharmony_ci unsigned int attachments[1]; 1087bf215546Sopenharmony_ci xcb_drawable_t drawable; 1088bf215546Sopenharmony_ci xcb_dri2_get_buffers_cookie_t buffers_cookie; 1089bf215546Sopenharmony_ci xcb_dri2_get_buffers_reply_t *buffers_reply; 1090bf215546Sopenharmony_ci xcb_dri2_dri2_buffer_t *buffers; 1091bf215546Sopenharmony_ci xcb_get_geometry_cookie_t geometry_cookie; 1092bf215546Sopenharmony_ci xcb_get_geometry_reply_t *geometry_reply; 1093bf215546Sopenharmony_ci xcb_generic_error_t *error; 1094bf215546Sopenharmony_ci int stride, format; 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_ci (void) ctx; 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_ci drawable = (xcb_drawable_t) (uintptr_t) buffer; 1099bf215546Sopenharmony_ci xcb_dri2_create_drawable (dri2_dpy->conn, drawable); 1100bf215546Sopenharmony_ci attachments[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT; 1101bf215546Sopenharmony_ci buffers_cookie = 1102bf215546Sopenharmony_ci xcb_dri2_get_buffers_unchecked (dri2_dpy->conn, 1103bf215546Sopenharmony_ci drawable, 1, 1, attachments); 1104bf215546Sopenharmony_ci geometry_cookie = xcb_get_geometry (dri2_dpy->conn, drawable); 1105bf215546Sopenharmony_ci buffers_reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, 1106bf215546Sopenharmony_ci buffers_cookie, NULL); 1107bf215546Sopenharmony_ci if (buffers_reply == NULL) 1108bf215546Sopenharmony_ci return NULL; 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_ci buffers = xcb_dri2_get_buffers_buffers (buffers_reply); 1111bf215546Sopenharmony_ci if (buffers == NULL) { 1112bf215546Sopenharmony_ci free(buffers_reply); 1113bf215546Sopenharmony_ci return NULL; 1114bf215546Sopenharmony_ci } 1115bf215546Sopenharmony_ci 1116bf215546Sopenharmony_ci geometry_reply = xcb_get_geometry_reply (dri2_dpy->conn, 1117bf215546Sopenharmony_ci geometry_cookie, &error); 1118bf215546Sopenharmony_ci if (geometry_reply == NULL || error != NULL) { 1119bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); 1120bf215546Sopenharmony_ci free(error); 1121bf215546Sopenharmony_ci free(buffers_reply); 1122bf215546Sopenharmony_ci free(geometry_reply); 1123bf215546Sopenharmony_ci return NULL; 1124bf215546Sopenharmony_ci } 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_ci format = dri2_format_for_depth(dri2_dpy, geometry_reply->depth); 1127bf215546Sopenharmony_ci if (format == __DRI_IMAGE_FORMAT_NONE) { 1128bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, 1129bf215546Sopenharmony_ci "dri2_create_image_khr: unsupported pixmap depth"); 1130bf215546Sopenharmony_ci free(buffers_reply); 1131bf215546Sopenharmony_ci free(geometry_reply); 1132bf215546Sopenharmony_ci return NULL; 1133bf215546Sopenharmony_ci } 1134bf215546Sopenharmony_ci 1135bf215546Sopenharmony_ci dri2_img = malloc(sizeof *dri2_img); 1136bf215546Sopenharmony_ci if (!dri2_img) { 1137bf215546Sopenharmony_ci free(buffers_reply); 1138bf215546Sopenharmony_ci free(geometry_reply); 1139bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); 1140bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 1141bf215546Sopenharmony_ci } 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci _eglInitImage(&dri2_img->base, disp); 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_ci stride = buffers[0].pitch / buffers[0].cpp; 1146bf215546Sopenharmony_ci dri2_img->dri_image = 1147bf215546Sopenharmony_ci dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, 1148bf215546Sopenharmony_ci buffers_reply->width, 1149bf215546Sopenharmony_ci buffers_reply->height, 1150bf215546Sopenharmony_ci format, 1151bf215546Sopenharmony_ci buffers[0].name, 1152bf215546Sopenharmony_ci stride, 1153bf215546Sopenharmony_ci dri2_img); 1154bf215546Sopenharmony_ci 1155bf215546Sopenharmony_ci free(buffers_reply); 1156bf215546Sopenharmony_ci free(geometry_reply); 1157bf215546Sopenharmony_ci 1158bf215546Sopenharmony_ci return &dri2_img->base; 1159bf215546Sopenharmony_ci} 1160bf215546Sopenharmony_ci 1161bf215546Sopenharmony_cistatic _EGLImage * 1162bf215546Sopenharmony_cidri2_x11_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target, 1163bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 1164bf215546Sopenharmony_ci{ 1165bf215546Sopenharmony_ci switch (target) { 1166bf215546Sopenharmony_ci case EGL_NATIVE_PIXMAP_KHR: 1167bf215546Sopenharmony_ci return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list); 1168bf215546Sopenharmony_ci default: 1169bf215546Sopenharmony_ci return dri2_create_image_khr(disp, ctx, target, buffer, attr_list); 1170bf215546Sopenharmony_ci } 1171bf215546Sopenharmony_ci} 1172bf215546Sopenharmony_ci 1173bf215546Sopenharmony_cistatic EGLBoolean 1174bf215546Sopenharmony_cidri2_x11_get_sync_values(_EGLDisplay *display, _EGLSurface *surface, 1175bf215546Sopenharmony_ci EGLuint64KHR *ust, EGLuint64KHR *msc, 1176bf215546Sopenharmony_ci EGLuint64KHR *sbc) 1177bf215546Sopenharmony_ci{ 1178bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(display); 1179bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); 1180bf215546Sopenharmony_ci xcb_dri2_get_msc_cookie_t cookie; 1181bf215546Sopenharmony_ci xcb_dri2_get_msc_reply_t *reply; 1182bf215546Sopenharmony_ci 1183bf215546Sopenharmony_ci cookie = xcb_dri2_get_msc(dri2_dpy->conn, dri2_surf->drawable); 1184bf215546Sopenharmony_ci reply = xcb_dri2_get_msc_reply(dri2_dpy->conn, cookie, NULL); 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci if (!reply) 1187bf215546Sopenharmony_ci return _eglError(EGL_BAD_ACCESS, __func__); 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ci *ust = ((EGLuint64KHR) reply->ust_hi << 32) | reply->ust_lo; 1190bf215546Sopenharmony_ci *msc = ((EGLuint64KHR) reply->msc_hi << 32) | reply->msc_lo; 1191bf215546Sopenharmony_ci *sbc = ((EGLuint64KHR) reply->sbc_hi << 32) | reply->sbc_lo; 1192bf215546Sopenharmony_ci free(reply); 1193bf215546Sopenharmony_ci 1194bf215546Sopenharmony_ci return EGL_TRUE; 1195bf215546Sopenharmony_ci} 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_cistatic EGLBoolean 1198bf215546Sopenharmony_cidri2_kopper_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval) 1199bf215546Sopenharmony_ci{ 1200bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1201bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1202bf215546Sopenharmony_ci 1203bf215546Sopenharmony_ci /* This can legitimately be null for lavapipe */ 1204bf215546Sopenharmony_ci if (dri2_dpy->kopper) 1205bf215546Sopenharmony_ci dri2_dpy->kopper->setSwapInterval(dri2_surf->dri_drawable, interval); 1206bf215546Sopenharmony_ci 1207bf215546Sopenharmony_ci return EGL_TRUE; 1208bf215546Sopenharmony_ci} 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_cistatic _EGLSurface * 1211bf215546Sopenharmony_cidri2_kopper_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, 1212bf215546Sopenharmony_ci void *native_window, 1213bf215546Sopenharmony_ci const EGLint *attrib_list) 1214bf215546Sopenharmony_ci{ 1215bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1216bf215546Sopenharmony_ci _EGLSurface *surf; 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ci surf = dri2_x11_create_surface(disp, EGL_WINDOW_BIT, conf, 1219bf215546Sopenharmony_ci native_window, attrib_list); 1220bf215546Sopenharmony_ci if (surf != NULL) { 1221bf215546Sopenharmony_ci /* When we first create the DRI2 drawable, its swap interval on the 1222bf215546Sopenharmony_ci * server side is 1. 1223bf215546Sopenharmony_ci */ 1224bf215546Sopenharmony_ci surf->SwapInterval = 1; 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci /* Override that with a driconf-set value. */ 1227bf215546Sopenharmony_ci dri2_kopper_swap_interval(disp, surf, dri2_dpy->default_swap_interval); 1228bf215546Sopenharmony_ci } 1229bf215546Sopenharmony_ci 1230bf215546Sopenharmony_ci return surf; 1231bf215546Sopenharmony_ci} 1232bf215546Sopenharmony_ci 1233bf215546Sopenharmony_cistatic EGLint 1234bf215546Sopenharmony_cidri2_kopper_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surf) 1235bf215546Sopenharmony_ci{ 1236bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1237bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1238bf215546Sopenharmony_ci 1239bf215546Sopenharmony_ci /* This can legitimately be null for lavapipe */ 1240bf215546Sopenharmony_ci if (dri2_dpy->kopper) 1241bf215546Sopenharmony_ci return dri2_dpy->kopper->queryBufferAge(dri2_surf->dri_drawable); 1242bf215546Sopenharmony_ci 1243bf215546Sopenharmony_ci return 0; 1244bf215546Sopenharmony_ci} 1245bf215546Sopenharmony_ci 1246bf215546Sopenharmony_cistatic const struct dri2_egl_display_vtbl dri2_x11_swrast_display_vtbl = { 1247bf215546Sopenharmony_ci .authenticate = NULL, 1248bf215546Sopenharmony_ci .create_window_surface = dri2_x11_create_window_surface, 1249bf215546Sopenharmony_ci .create_pixmap_surface = dri2_x11_create_pixmap_surface, 1250bf215546Sopenharmony_ci .create_pbuffer_surface = dri2_x11_create_pbuffer_surface, 1251bf215546Sopenharmony_ci .destroy_surface = dri2_x11_destroy_surface, 1252bf215546Sopenharmony_ci .create_image = dri2_create_image_khr, 1253bf215546Sopenharmony_ci .swap_buffers = dri2_x11_swap_buffers, 1254bf215546Sopenharmony_ci .swap_buffers_region = dri2_x11_swap_buffers_region, 1255bf215546Sopenharmony_ci .post_sub_buffer = dri2_x11_post_sub_buffer, 1256bf215546Sopenharmony_ci .copy_buffers = dri2_x11_copy_buffers, 1257bf215546Sopenharmony_ci /* XXX: should really implement this since X11 has pixmaps */ 1258bf215546Sopenharmony_ci .query_surface = dri2_query_surface, 1259bf215546Sopenharmony_ci .get_dri_drawable = dri2_surface_get_dri_drawable, 1260bf215546Sopenharmony_ci}; 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_cistatic const struct dri2_egl_display_vtbl dri2_x11_kopper_display_vtbl = { 1263bf215546Sopenharmony_ci .authenticate = NULL, 1264bf215546Sopenharmony_ci .create_window_surface = dri2_kopper_create_window_surface, 1265bf215546Sopenharmony_ci .create_pixmap_surface = dri2_x11_create_pixmap_surface, 1266bf215546Sopenharmony_ci .create_pbuffer_surface = dri2_x11_create_pbuffer_surface, 1267bf215546Sopenharmony_ci .destroy_surface = dri2_x11_destroy_surface, 1268bf215546Sopenharmony_ci .create_image = dri2_create_image_khr, 1269bf215546Sopenharmony_ci .swap_interval = dri2_kopper_swap_interval, 1270bf215546Sopenharmony_ci .swap_buffers = dri2_x11_swap_buffers, 1271bf215546Sopenharmony_ci .swap_buffers_region = dri2_x11_swap_buffers_region, 1272bf215546Sopenharmony_ci .post_sub_buffer = dri2_x11_post_sub_buffer, 1273bf215546Sopenharmony_ci .copy_buffers = dri2_x11_copy_buffers, 1274bf215546Sopenharmony_ci .query_buffer_age = dri2_kopper_query_buffer_age, 1275bf215546Sopenharmony_ci /* XXX: should really implement this since X11 has pixmaps */ 1276bf215546Sopenharmony_ci .query_surface = dri2_query_surface, 1277bf215546Sopenharmony_ci .get_dri_drawable = dri2_surface_get_dri_drawable, 1278bf215546Sopenharmony_ci}; 1279bf215546Sopenharmony_ci 1280bf215546Sopenharmony_cistatic const struct dri2_egl_display_vtbl dri2_x11_display_vtbl = { 1281bf215546Sopenharmony_ci .authenticate = dri2_x11_authenticate, 1282bf215546Sopenharmony_ci .create_window_surface = dri2_x11_create_window_surface, 1283bf215546Sopenharmony_ci .create_pixmap_surface = dri2_x11_create_pixmap_surface, 1284bf215546Sopenharmony_ci .create_pbuffer_surface = dri2_x11_create_pbuffer_surface, 1285bf215546Sopenharmony_ci .destroy_surface = dri2_x11_destroy_surface, 1286bf215546Sopenharmony_ci .create_image = dri2_x11_create_image_khr, 1287bf215546Sopenharmony_ci .swap_interval = dri2_x11_swap_interval, 1288bf215546Sopenharmony_ci .swap_buffers = dri2_x11_swap_buffers, 1289bf215546Sopenharmony_ci .swap_buffers_region = dri2_x11_swap_buffers_region, 1290bf215546Sopenharmony_ci .post_sub_buffer = dri2_x11_post_sub_buffer, 1291bf215546Sopenharmony_ci .copy_buffers = dri2_x11_copy_buffers, 1292bf215546Sopenharmony_ci .query_surface = dri2_query_surface, 1293bf215546Sopenharmony_ci .get_sync_values = dri2_x11_get_sync_values, 1294bf215546Sopenharmony_ci .get_dri_drawable = dri2_surface_get_dri_drawable, 1295bf215546Sopenharmony_ci}; 1296bf215546Sopenharmony_ci 1297bf215546Sopenharmony_cistatic const __DRIswrastLoaderExtension swrast_loader_extension = { 1298bf215546Sopenharmony_ci .base = { __DRI_SWRAST_LOADER, 1 }, 1299bf215546Sopenharmony_ci 1300bf215546Sopenharmony_ci .getDrawableInfo = swrastGetDrawableInfo, 1301bf215546Sopenharmony_ci .putImage = swrastPutImage, 1302bf215546Sopenharmony_ci .getImage = swrastGetImage, 1303bf215546Sopenharmony_ci}; 1304bf215546Sopenharmony_ci 1305bf215546Sopenharmony_cistatic void 1306bf215546Sopenharmony_cikopperSetSurfaceCreateInfo(void *_draw, struct kopper_loader_info *ci) 1307bf215546Sopenharmony_ci{ 1308bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = _draw; 1309bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); 1310bf215546Sopenharmony_ci 1311bf215546Sopenharmony_ci if (dri2_surf->base.Type != EGL_WINDOW_BIT) 1312bf215546Sopenharmony_ci return; 1313bf215546Sopenharmony_ci ci->xcb.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 1314bf215546Sopenharmony_ci ci->xcb.pNext = NULL; 1315bf215546Sopenharmony_ci ci->xcb.flags = 0; 1316bf215546Sopenharmony_ci ci->xcb.connection = dri2_dpy->conn; 1317bf215546Sopenharmony_ci ci->xcb.window = dri2_surf->drawable; 1318bf215546Sopenharmony_ci ci->has_alpha = dri2_surf->depth == 32; 1319bf215546Sopenharmony_ci} 1320bf215546Sopenharmony_ci 1321bf215546Sopenharmony_cistatic const __DRIkopperLoaderExtension kopper_loader_extension = { 1322bf215546Sopenharmony_ci .base = { __DRI_KOPPER_LOADER, 1 }, 1323bf215546Sopenharmony_ci 1324bf215546Sopenharmony_ci .SetSurfaceCreateInfo = kopperSetSurfaceCreateInfo, 1325bf215546Sopenharmony_ci}; 1326bf215546Sopenharmony_ci 1327bf215546Sopenharmony_cistatic const __DRIextension *swrast_loader_extensions[] = { 1328bf215546Sopenharmony_ci &swrast_loader_extension.base, 1329bf215546Sopenharmony_ci &image_lookup_extension.base, 1330bf215546Sopenharmony_ci &kopper_loader_extension.base, 1331bf215546Sopenharmony_ci NULL, 1332bf215546Sopenharmony_ci}; 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_cistatic int 1335bf215546Sopenharmony_cidri2_find_screen_for_display(const _EGLDisplay *disp, int fallback_screen) 1336bf215546Sopenharmony_ci{ 1337bf215546Sopenharmony_ci const EGLAttrib *attr; 1338bf215546Sopenharmony_ci 1339bf215546Sopenharmony_ci if (!disp->Options.Attribs) 1340bf215546Sopenharmony_ci return fallback_screen; 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci for (attr = disp->Options.Attribs; attr[0] != EGL_NONE; attr += 2) { 1343bf215546Sopenharmony_ci if (attr[0] == EGL_PLATFORM_X11_SCREEN_EXT || 1344bf215546Sopenharmony_ci attr[0] == EGL_PLATFORM_XCB_SCREEN_EXT) 1345bf215546Sopenharmony_ci return attr[1]; 1346bf215546Sopenharmony_ci } 1347bf215546Sopenharmony_ci 1348bf215546Sopenharmony_ci return fallback_screen; 1349bf215546Sopenharmony_ci} 1350bf215546Sopenharmony_ci 1351bf215546Sopenharmony_cistatic EGLBoolean 1352bf215546Sopenharmony_cidri2_get_xcb_connection(_EGLDisplay *disp, 1353bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy) 1354bf215546Sopenharmony_ci{ 1355bf215546Sopenharmony_ci xcb_screen_iterator_t s; 1356bf215546Sopenharmony_ci int screen; 1357bf215546Sopenharmony_ci const char *msg; 1358bf215546Sopenharmony_ci 1359bf215546Sopenharmony_ci disp->DriverData = (void *) dri2_dpy; 1360bf215546Sopenharmony_ci if (disp->PlatformDisplay == NULL) { 1361bf215546Sopenharmony_ci dri2_dpy->conn = xcb_connect(NULL, &screen); 1362bf215546Sopenharmony_ci dri2_dpy->own_device = true; 1363bf215546Sopenharmony_ci screen = dri2_find_screen_for_display(disp, screen); 1364bf215546Sopenharmony_ci } else if (disp->Platform == _EGL_PLATFORM_X11) { 1365bf215546Sopenharmony_ci Display *dpy = disp->PlatformDisplay; 1366bf215546Sopenharmony_ci dri2_dpy->conn = XGetXCBConnection(dpy); 1367bf215546Sopenharmony_ci screen = DefaultScreen(dpy); 1368bf215546Sopenharmony_ci } else { 1369bf215546Sopenharmony_ci /* _EGL_PLATFORM_XCB */ 1370bf215546Sopenharmony_ci dri2_dpy->conn = disp->PlatformDisplay; 1371bf215546Sopenharmony_ci screen = dri2_find_screen_for_display(disp, 0); 1372bf215546Sopenharmony_ci } 1373bf215546Sopenharmony_ci 1374bf215546Sopenharmony_ci if (!dri2_dpy->conn || xcb_connection_has_error(dri2_dpy->conn)) { 1375bf215546Sopenharmony_ci msg = "xcb_connect failed"; 1376bf215546Sopenharmony_ci goto disconnect; 1377bf215546Sopenharmony_ci } 1378bf215546Sopenharmony_ci 1379bf215546Sopenharmony_ci s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); 1380bf215546Sopenharmony_ci dri2_dpy->screen = get_xcb_screen(s, screen); 1381bf215546Sopenharmony_ci if (!dri2_dpy->screen) { 1382bf215546Sopenharmony_ci msg = "failed to get xcb screen"; 1383bf215546Sopenharmony_ci goto disconnect; 1384bf215546Sopenharmony_ci } 1385bf215546Sopenharmony_ci 1386bf215546Sopenharmony_ci return EGL_TRUE; 1387bf215546Sopenharmony_cidisconnect: 1388bf215546Sopenharmony_ci if (disp->PlatformDisplay == NULL) 1389bf215546Sopenharmony_ci xcb_disconnect(dri2_dpy->conn); 1390bf215546Sopenharmony_ci 1391bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, msg); 1392bf215546Sopenharmony_ci} 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_cistatic void 1395bf215546Sopenharmony_cidri2_x11_setup_swap_interval(_EGLDisplay *disp) 1396bf215546Sopenharmony_ci{ 1397bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1398bf215546Sopenharmony_ci int arbitrary_max_interval = 1000; 1399bf215546Sopenharmony_ci 1400bf215546Sopenharmony_ci /* default behavior for no SwapBuffers support: no vblank syncing 1401bf215546Sopenharmony_ci * either. 1402bf215546Sopenharmony_ci */ 1403bf215546Sopenharmony_ci dri2_dpy->min_swap_interval = 0; 1404bf215546Sopenharmony_ci dri2_dpy->max_swap_interval = 0; 1405bf215546Sopenharmony_ci dri2_dpy->default_swap_interval = 0; 1406bf215546Sopenharmony_ci 1407bf215546Sopenharmony_ci if (!dri2_dpy->swap_available) 1408bf215546Sopenharmony_ci return; 1409bf215546Sopenharmony_ci 1410bf215546Sopenharmony_ci /* If we do have swapbuffers, then we can support pretty much any swap 1411bf215546Sopenharmony_ci * interval. Unless we're kopper, for now. 1412bf215546Sopenharmony_ci */ 1413bf215546Sopenharmony_ci if (dri2_dpy->kopper) 1414bf215546Sopenharmony_ci arbitrary_max_interval = 1; 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ci dri2_setup_swap_interval(disp, arbitrary_max_interval); 1417bf215546Sopenharmony_ci} 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_cistatic EGLBoolean 1420bf215546Sopenharmony_cidri2_initialize_x11_swrast(_EGLDisplay *disp) 1421bf215546Sopenharmony_ci{ 1422bf215546Sopenharmony_ci _EGLDevice *dev; 1423bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy; 1424bf215546Sopenharmony_ci 1425bf215546Sopenharmony_ci dri2_dpy = calloc(1, sizeof *dri2_dpy); 1426bf215546Sopenharmony_ci if (!dri2_dpy) 1427bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, "eglInitialize"); 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci dri2_dpy->fd = -1; 1430bf215546Sopenharmony_ci if (!dri2_get_xcb_connection(disp, dri2_dpy)) 1431bf215546Sopenharmony_ci goto cleanup; 1432bf215546Sopenharmony_ci 1433bf215546Sopenharmony_ci dev = _eglAddDevice(dri2_dpy->fd, true); 1434bf215546Sopenharmony_ci if (!dev) { 1435bf215546Sopenharmony_ci _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice"); 1436bf215546Sopenharmony_ci goto cleanup; 1437bf215546Sopenharmony_ci } 1438bf215546Sopenharmony_ci 1439bf215546Sopenharmony_ci disp->Device = dev; 1440bf215546Sopenharmony_ci 1441bf215546Sopenharmony_ci /* 1442bf215546Sopenharmony_ci * Every hardware driver_name is set using strdup. Doing the same in 1443bf215546Sopenharmony_ci * here will allow is to simply free the memory at dri2_terminate(). 1444bf215546Sopenharmony_ci */ 1445bf215546Sopenharmony_ci dri2_dpy->driver_name = strdup(disp->Options.Zink ? "zink" : "swrast"); 1446bf215546Sopenharmony_ci if (!dri2_load_driver_swrast(disp)) 1447bf215546Sopenharmony_ci goto cleanup; 1448bf215546Sopenharmony_ci 1449bf215546Sopenharmony_ci dri2_dpy->loader_extensions = swrast_loader_extensions; 1450bf215546Sopenharmony_ci 1451bf215546Sopenharmony_ci if (!dri2_create_screen(disp)) 1452bf215546Sopenharmony_ci goto cleanup; 1453bf215546Sopenharmony_ci 1454bf215546Sopenharmony_ci if (!dri2_setup_extensions(disp)) 1455bf215546Sopenharmony_ci goto cleanup; 1456bf215546Sopenharmony_ci 1457bf215546Sopenharmony_ci dri2_setup_screen(disp); 1458bf215546Sopenharmony_ci 1459bf215546Sopenharmony_ci if (disp->Options.Zink) { 1460bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 1461bf215546Sopenharmony_ci dri2_dpy->device_name = strdup("zink"); 1462bf215546Sopenharmony_ci#endif 1463bf215546Sopenharmony_ci dri2_dpy->swap_available = EGL_TRUE; 1464bf215546Sopenharmony_ci dri2_x11_setup_swap_interval(disp); 1465bf215546Sopenharmony_ci if (!dri2_dpy->is_different_gpu) 1466bf215546Sopenharmony_ci disp->Extensions.KHR_image_pixmap = EGL_TRUE; 1467bf215546Sopenharmony_ci disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; 1468bf215546Sopenharmony_ci disp->Extensions.CHROMIUM_sync_control = EGL_TRUE; 1469bf215546Sopenharmony_ci disp->Extensions.EXT_buffer_age = EGL_TRUE; 1470bf215546Sopenharmony_ci disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE; 1471bf215546Sopenharmony_ci 1472bf215546Sopenharmony_ci //dri2_set_WL_bind_wayland_display(disp); 1473bf215546Sopenharmony_ci } 1474bf215546Sopenharmony_ci 1475bf215546Sopenharmony_ci if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true)) 1476bf215546Sopenharmony_ci goto cleanup; 1477bf215546Sopenharmony_ci 1478bf215546Sopenharmony_ci /* Fill vtbl last to prevent accidentally calling virtual function during 1479bf215546Sopenharmony_ci * initialization. 1480bf215546Sopenharmony_ci */ 1481bf215546Sopenharmony_ci if (disp->Options.Zink) 1482bf215546Sopenharmony_ci dri2_dpy->vtbl = &dri2_x11_kopper_display_vtbl; 1483bf215546Sopenharmony_ci else 1484bf215546Sopenharmony_ci dri2_dpy->vtbl = &dri2_x11_swrast_display_vtbl; 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci return EGL_TRUE; 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci cleanup: 1489bf215546Sopenharmony_ci dri2_display_destroy(disp); 1490bf215546Sopenharmony_ci return EGL_FALSE; 1491bf215546Sopenharmony_ci} 1492bf215546Sopenharmony_ci 1493bf215546Sopenharmony_ci#ifdef HAVE_DRI3 1494bf215546Sopenharmony_ci 1495bf215546Sopenharmony_cistatic const __DRIextension *dri3_image_loader_extensions[] = { 1496bf215546Sopenharmony_ci &dri3_image_loader_extension.base, 1497bf215546Sopenharmony_ci &image_lookup_extension.base, 1498bf215546Sopenharmony_ci &use_invalidate.base, 1499bf215546Sopenharmony_ci &background_callable_extension.base, 1500bf215546Sopenharmony_ci NULL, 1501bf215546Sopenharmony_ci}; 1502bf215546Sopenharmony_ci 1503bf215546Sopenharmony_cistatic EGLBoolean 1504bf215546Sopenharmony_cidri2_initialize_x11_dri3(_EGLDisplay *disp) 1505bf215546Sopenharmony_ci{ 1506bf215546Sopenharmony_ci _EGLDevice *dev; 1507bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy; 1508bf215546Sopenharmony_ci 1509bf215546Sopenharmony_ci dri2_dpy = calloc(1, sizeof *dri2_dpy); 1510bf215546Sopenharmony_ci if (!dri2_dpy) 1511bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, "eglInitialize"); 1512bf215546Sopenharmony_ci 1513bf215546Sopenharmony_ci dri2_dpy->fd = -1; 1514bf215546Sopenharmony_ci if (!dri2_get_xcb_connection(disp, dri2_dpy)) 1515bf215546Sopenharmony_ci goto cleanup; 1516bf215546Sopenharmony_ci 1517bf215546Sopenharmony_ci if (!dri3_x11_connect(dri2_dpy)) 1518bf215546Sopenharmony_ci goto cleanup; 1519bf215546Sopenharmony_ci 1520bf215546Sopenharmony_ci dev = _eglAddDevice(dri2_dpy->fd, false); 1521bf215546Sopenharmony_ci if (!dev) { 1522bf215546Sopenharmony_ci _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice"); 1523bf215546Sopenharmony_ci goto cleanup; 1524bf215546Sopenharmony_ci } 1525bf215546Sopenharmony_ci 1526bf215546Sopenharmony_ci disp->Device = dev; 1527bf215546Sopenharmony_ci 1528bf215546Sopenharmony_ci if (!dri2_load_driver_dri3(disp)) 1529bf215546Sopenharmony_ci goto cleanup; 1530bf215546Sopenharmony_ci 1531bf215546Sopenharmony_ci dri2_dpy->loader_extensions = dri3_image_loader_extensions; 1532bf215546Sopenharmony_ci 1533bf215546Sopenharmony_ci dri2_dpy->swap_available = true; 1534bf215546Sopenharmony_ci dri2_dpy->invalidate_available = true; 1535bf215546Sopenharmony_ci 1536bf215546Sopenharmony_ci if (!dri2_create_screen(disp)) 1537bf215546Sopenharmony_ci goto cleanup; 1538bf215546Sopenharmony_ci 1539bf215546Sopenharmony_ci if (!dri2_setup_extensions(disp)) 1540bf215546Sopenharmony_ci goto cleanup; 1541bf215546Sopenharmony_ci 1542bf215546Sopenharmony_ci dri2_setup_screen(disp); 1543bf215546Sopenharmony_ci 1544bf215546Sopenharmony_ci dri2_x11_setup_swap_interval(disp); 1545bf215546Sopenharmony_ci 1546bf215546Sopenharmony_ci if (!dri2_dpy->is_different_gpu) 1547bf215546Sopenharmony_ci disp->Extensions.KHR_image_pixmap = EGL_TRUE; 1548bf215546Sopenharmony_ci disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; 1549bf215546Sopenharmony_ci disp->Extensions.CHROMIUM_sync_control = EGL_TRUE; 1550bf215546Sopenharmony_ci disp->Extensions.EXT_buffer_age = EGL_TRUE; 1551bf215546Sopenharmony_ci disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE; 1552bf215546Sopenharmony_ci 1553bf215546Sopenharmony_ci dri2_set_WL_bind_wayland_display(disp); 1554bf215546Sopenharmony_ci 1555bf215546Sopenharmony_ci if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, false)) 1556bf215546Sopenharmony_ci goto cleanup; 1557bf215546Sopenharmony_ci 1558bf215546Sopenharmony_ci dri2_dpy->loader_dri3_ext.core = dri2_dpy->core; 1559bf215546Sopenharmony_ci dri2_dpy->loader_dri3_ext.image_driver = dri2_dpy->image_driver; 1560bf215546Sopenharmony_ci dri2_dpy->loader_dri3_ext.flush = dri2_dpy->flush; 1561bf215546Sopenharmony_ci dri2_dpy->loader_dri3_ext.tex_buffer = dri2_dpy->tex_buffer; 1562bf215546Sopenharmony_ci dri2_dpy->loader_dri3_ext.image = dri2_dpy->image; 1563bf215546Sopenharmony_ci dri2_dpy->loader_dri3_ext.config = dri2_dpy->config; 1564bf215546Sopenharmony_ci 1565bf215546Sopenharmony_ci /* Fill vtbl last to prevent accidentally calling virtual function during 1566bf215546Sopenharmony_ci * initialization. 1567bf215546Sopenharmony_ci */ 1568bf215546Sopenharmony_ci dri2_dpy->vtbl = &dri3_x11_display_vtbl; 1569bf215546Sopenharmony_ci 1570bf215546Sopenharmony_ci _eglLog(_EGL_INFO, "Using DRI3"); 1571bf215546Sopenharmony_ci 1572bf215546Sopenharmony_ci return EGL_TRUE; 1573bf215546Sopenharmony_ci 1574bf215546Sopenharmony_ci cleanup: 1575bf215546Sopenharmony_ci dri2_display_destroy(disp); 1576bf215546Sopenharmony_ci return EGL_FALSE; 1577bf215546Sopenharmony_ci} 1578bf215546Sopenharmony_ci#endif 1579bf215546Sopenharmony_ci 1580bf215546Sopenharmony_cistatic const __DRIdri2LoaderExtension dri2_loader_extension_old = { 1581bf215546Sopenharmony_ci .base = { __DRI_DRI2_LOADER, 2 }, 1582bf215546Sopenharmony_ci 1583bf215546Sopenharmony_ci .getBuffers = dri2_x11_get_buffers, 1584bf215546Sopenharmony_ci .flushFrontBuffer = dri2_x11_flush_front_buffer, 1585bf215546Sopenharmony_ci .getBuffersWithFormat = NULL, 1586bf215546Sopenharmony_ci}; 1587bf215546Sopenharmony_ci 1588bf215546Sopenharmony_cistatic const __DRIdri2LoaderExtension dri2_loader_extension = { 1589bf215546Sopenharmony_ci .base = { __DRI_DRI2_LOADER, 3 }, 1590bf215546Sopenharmony_ci 1591bf215546Sopenharmony_ci .getBuffers = dri2_x11_get_buffers, 1592bf215546Sopenharmony_ci .flushFrontBuffer = dri2_x11_flush_front_buffer, 1593bf215546Sopenharmony_ci .getBuffersWithFormat = dri2_x11_get_buffers_with_format, 1594bf215546Sopenharmony_ci}; 1595bf215546Sopenharmony_ci 1596bf215546Sopenharmony_cistatic const __DRIextension *dri2_loader_extensions_old[] = { 1597bf215546Sopenharmony_ci &dri2_loader_extension_old.base, 1598bf215546Sopenharmony_ci &image_lookup_extension.base, 1599bf215546Sopenharmony_ci &background_callable_extension.base, 1600bf215546Sopenharmony_ci NULL, 1601bf215546Sopenharmony_ci}; 1602bf215546Sopenharmony_ci 1603bf215546Sopenharmony_cistatic const __DRIextension *dri2_loader_extensions[] = { 1604bf215546Sopenharmony_ci &dri2_loader_extension.base, 1605bf215546Sopenharmony_ci &image_lookup_extension.base, 1606bf215546Sopenharmony_ci &use_invalidate.base, 1607bf215546Sopenharmony_ci &background_callable_extension.base, 1608bf215546Sopenharmony_ci NULL, 1609bf215546Sopenharmony_ci}; 1610bf215546Sopenharmony_ci 1611bf215546Sopenharmony_cistatic EGLBoolean 1612bf215546Sopenharmony_cidri2_initialize_x11_dri2(_EGLDisplay *disp) 1613bf215546Sopenharmony_ci{ 1614bf215546Sopenharmony_ci _EGLDevice *dev; 1615bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy; 1616bf215546Sopenharmony_ci 1617bf215546Sopenharmony_ci dri2_dpy = calloc(1, sizeof *dri2_dpy); 1618bf215546Sopenharmony_ci if (!dri2_dpy) 1619bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, "eglInitialize"); 1620bf215546Sopenharmony_ci 1621bf215546Sopenharmony_ci dri2_dpy->fd = -1; 1622bf215546Sopenharmony_ci if (!dri2_get_xcb_connection(disp, dri2_dpy)) 1623bf215546Sopenharmony_ci goto cleanup; 1624bf215546Sopenharmony_ci 1625bf215546Sopenharmony_ci if (!dri2_x11_connect(dri2_dpy)) 1626bf215546Sopenharmony_ci goto cleanup; 1627bf215546Sopenharmony_ci 1628bf215546Sopenharmony_ci dev = _eglAddDevice(dri2_dpy->fd, false); 1629bf215546Sopenharmony_ci if (!dev) { 1630bf215546Sopenharmony_ci _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice"); 1631bf215546Sopenharmony_ci goto cleanup; 1632bf215546Sopenharmony_ci } 1633bf215546Sopenharmony_ci 1634bf215546Sopenharmony_ci disp->Device = dev; 1635bf215546Sopenharmony_ci 1636bf215546Sopenharmony_ci if (!dri2_load_driver(disp)) 1637bf215546Sopenharmony_ci goto cleanup; 1638bf215546Sopenharmony_ci 1639bf215546Sopenharmony_ci if (dri2_dpy->dri2_minor >= 1) 1640bf215546Sopenharmony_ci dri2_dpy->loader_extensions = dri2_loader_extensions; 1641bf215546Sopenharmony_ci else 1642bf215546Sopenharmony_ci dri2_dpy->loader_extensions = dri2_loader_extensions_old; 1643bf215546Sopenharmony_ci 1644bf215546Sopenharmony_ci dri2_dpy->swap_available = (dri2_dpy->dri2_minor >= 2); 1645bf215546Sopenharmony_ci dri2_dpy->invalidate_available = (dri2_dpy->dri2_minor >= 3); 1646bf215546Sopenharmony_ci 1647bf215546Sopenharmony_ci if (!dri2_create_screen(disp)) 1648bf215546Sopenharmony_ci goto cleanup; 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_ci if (!dri2_setup_extensions(disp)) 1651bf215546Sopenharmony_ci goto cleanup; 1652bf215546Sopenharmony_ci 1653bf215546Sopenharmony_ci dri2_setup_screen(disp); 1654bf215546Sopenharmony_ci 1655bf215546Sopenharmony_ci dri2_x11_setup_swap_interval(disp); 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci disp->Extensions.KHR_image_pixmap = EGL_TRUE; 1658bf215546Sopenharmony_ci disp->Extensions.NOK_swap_region = EGL_TRUE; 1659bf215546Sopenharmony_ci disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; 1660bf215546Sopenharmony_ci disp->Extensions.NV_post_sub_buffer = EGL_TRUE; 1661bf215546Sopenharmony_ci disp->Extensions.CHROMIUM_sync_control = EGL_TRUE; 1662bf215546Sopenharmony_ci 1663bf215546Sopenharmony_ci dri2_set_WL_bind_wayland_display(disp); 1664bf215546Sopenharmony_ci 1665bf215546Sopenharmony_ci if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true)) 1666bf215546Sopenharmony_ci goto cleanup; 1667bf215546Sopenharmony_ci 1668bf215546Sopenharmony_ci /* Fill vtbl last to prevent accidentally calling virtual function during 1669bf215546Sopenharmony_ci * initialization. 1670bf215546Sopenharmony_ci */ 1671bf215546Sopenharmony_ci dri2_dpy->vtbl = &dri2_x11_display_vtbl; 1672bf215546Sopenharmony_ci 1673bf215546Sopenharmony_ci _eglLog(_EGL_INFO, "Using DRI2"); 1674bf215546Sopenharmony_ci 1675bf215546Sopenharmony_ci return EGL_TRUE; 1676bf215546Sopenharmony_ci 1677bf215546Sopenharmony_ci cleanup: 1678bf215546Sopenharmony_ci dri2_display_destroy(disp); 1679bf215546Sopenharmony_ci return EGL_FALSE; 1680bf215546Sopenharmony_ci} 1681bf215546Sopenharmony_ci 1682bf215546Sopenharmony_ciEGLBoolean 1683bf215546Sopenharmony_cidri2_initialize_x11(_EGLDisplay *disp) 1684bf215546Sopenharmony_ci{ 1685bf215546Sopenharmony_ci if (disp->Options.ForceSoftware) 1686bf215546Sopenharmony_ci return dri2_initialize_x11_swrast(disp); 1687bf215546Sopenharmony_ci 1688bf215546Sopenharmony_ci#ifdef HAVE_DRI3 1689bf215546Sopenharmony_ci if (!env_var_as_boolean("LIBGL_DRI3_DISABLE", false)) 1690bf215546Sopenharmony_ci if (dri2_initialize_x11_dri3(disp)) 1691bf215546Sopenharmony_ci return EGL_TRUE; 1692bf215546Sopenharmony_ci#endif 1693bf215546Sopenharmony_ci 1694bf215546Sopenharmony_ci if (!env_var_as_boolean("LIBGL_DRI2_DISABLE", false)) 1695bf215546Sopenharmony_ci if (dri2_initialize_x11_dri2(disp)) 1696bf215546Sopenharmony_ci return EGL_TRUE; 1697bf215546Sopenharmony_ci 1698bf215546Sopenharmony_ci return EGL_FALSE; 1699bf215546Sopenharmony_ci} 1700bf215546Sopenharmony_ci 1701bf215546Sopenharmony_civoid 1702bf215546Sopenharmony_cidri2_teardown_x11(struct dri2_egl_display *dri2_dpy) 1703bf215546Sopenharmony_ci{ 1704bf215546Sopenharmony_ci if (dri2_dpy->own_device) 1705bf215546Sopenharmony_ci xcb_disconnect(dri2_dpy->conn); 1706bf215546Sopenharmony_ci} 1707