1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2010 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 <stdbool.h> 31bf215546Sopenharmony_ci#include <stdlib.h> 32bf215546Sopenharmony_ci#include <string.h> 33bf215546Sopenharmony_ci#include <stdio.h> 34bf215546Sopenharmony_ci#include <limits.h> 35bf215546Sopenharmony_ci#include <dlfcn.h> 36bf215546Sopenharmony_ci#include <fcntl.h> 37bf215546Sopenharmony_ci#include <errno.h> 38bf215546Sopenharmony_ci#include <unistd.h> 39bf215546Sopenharmony_ci#include <c11/threads.h> 40bf215546Sopenharmony_ci#include <time.h> 41bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 42bf215546Sopenharmony_ci#include <xf86drm.h> 43bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 44bf215546Sopenharmony_ci#endif 45bf215546Sopenharmony_ci#include <GL/gl.h> 46bf215546Sopenharmony_ci#include <GL/internal/dri_interface.h> 47bf215546Sopenharmony_ci#include <sys/types.h> 48bf215546Sopenharmony_ci#include <sys/stat.h> 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 51bf215546Sopenharmony_ci#include <wayland-client.h> 52bf215546Sopenharmony_ci#include "wayland-drm.h" 53bf215546Sopenharmony_ci#include "wayland-drm-client-protocol.h" 54bf215546Sopenharmony_ci#include "linux-dmabuf-unstable-v1-client-protocol.h" 55bf215546Sopenharmony_ci#endif 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM 58bf215546Sopenharmony_ci#include "X11/Xlibint.h" 59bf215546Sopenharmony_ci#endif 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci#include "egldefines.h" 62bf215546Sopenharmony_ci#include "egl_dri2.h" 63bf215546Sopenharmony_ci#include "GL/mesa_glinterop.h" 64bf215546Sopenharmony_ci#include "loader/loader.h" 65bf215546Sopenharmony_ci#include "util/libsync.h" 66bf215546Sopenharmony_ci#include "util/os_file.h" 67bf215546Sopenharmony_ci#include "util/u_atomic.h" 68bf215546Sopenharmony_ci#include "util/u_vector.h" 69bf215546Sopenharmony_ci#include "mapi/glapi/glapi.h" 70bf215546Sopenharmony_ci#include "util/bitscan.h" 71bf215546Sopenharmony_ci#include "util/driconf.h" 72bf215546Sopenharmony_ci#include "util/u_math.h" 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci#include "ohos_log.h" 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci#define NUM_ATTRIBS 12 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic const struct dri2_pbuffer_visual { 79bf215546Sopenharmony_ci const char *format_name; 80bf215546Sopenharmony_ci unsigned int dri_image_format; 81bf215546Sopenharmony_ci int rgba_shifts[4]; 82bf215546Sopenharmony_ci unsigned int rgba_sizes[4]; 83bf215546Sopenharmony_ci} dri2_pbuffer_visuals[] = { 84bf215546Sopenharmony_ci { 85bf215546Sopenharmony_ci "ABGR16F", 86bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_ABGR16161616F, 87bf215546Sopenharmony_ci { 0, 16, 32, 48 }, 88bf215546Sopenharmony_ci { 16, 16, 16, 16 } 89bf215546Sopenharmony_ci }, 90bf215546Sopenharmony_ci { 91bf215546Sopenharmony_ci "XBGR16F", 92bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_XBGR16161616F, 93bf215546Sopenharmony_ci { 0, 16, 32, -1 }, 94bf215546Sopenharmony_ci { 16, 16, 16, 0 } 95bf215546Sopenharmony_ci }, 96bf215546Sopenharmony_ci { 97bf215546Sopenharmony_ci "A2RGB10", 98bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_ARGB2101010, 99bf215546Sopenharmony_ci { 20, 10, 0, 30 }, 100bf215546Sopenharmony_ci { 10, 10, 10, 2 } 101bf215546Sopenharmony_ci }, 102bf215546Sopenharmony_ci { 103bf215546Sopenharmony_ci "X2RGB10", 104bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_XRGB2101010, 105bf215546Sopenharmony_ci { 20, 10, 0, -1 }, 106bf215546Sopenharmony_ci { 10, 10, 10, 0 } 107bf215546Sopenharmony_ci }, 108bf215546Sopenharmony_ci { 109bf215546Sopenharmony_ci "ARGB8888", 110bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_ARGB8888, 111bf215546Sopenharmony_ci { 16, 8, 0, 24 }, 112bf215546Sopenharmony_ci { 8, 8, 8, 8 } 113bf215546Sopenharmony_ci }, 114bf215546Sopenharmony_ci { 115bf215546Sopenharmony_ci "RGB888", 116bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_XRGB8888, 117bf215546Sopenharmony_ci { 16, 8, 0, -1 }, 118bf215546Sopenharmony_ci { 8, 8, 8, 0 } 119bf215546Sopenharmony_ci }, 120bf215546Sopenharmony_ci { 121bf215546Sopenharmony_ci "RGB565", 122bf215546Sopenharmony_ci __DRI_IMAGE_FORMAT_RGB565, 123bf215546Sopenharmony_ci { 11, 5, 0, -1 }, 124bf215546Sopenharmony_ci { 5, 6, 5, 0 } 125bf215546Sopenharmony_ci }, 126bf215546Sopenharmony_ci}; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_cistatic void 129bf215546Sopenharmony_cidri_set_background_context(void *loaderPrivate) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 132bf215546Sopenharmony_ci _EGLThreadInfo *t = _eglGetCurrentThread(); 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci _eglBindContextToThread(ctx, t); 135bf215546Sopenharmony_ci} 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_cistatic void 138bf215546Sopenharmony_cidri2_gl_flush() 139bf215546Sopenharmony_ci{ 140bf215546Sopenharmony_ci static void (*glFlush)(void); 141bf215546Sopenharmony_ci static mtx_t glFlushMutex = _MTX_INITIALIZER_NP; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci mtx_lock(&glFlushMutex); 144bf215546Sopenharmony_ci if (!glFlush) 145bf215546Sopenharmony_ci glFlush = _glapi_get_proc_address("glFlush"); 146bf215546Sopenharmony_ci mtx_unlock(&glFlushMutex); 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci /* if glFlush is not available things are horribly broken */ 149bf215546Sopenharmony_ci if (!glFlush) { 150bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to find glFlush entry point"); 151bf215546Sopenharmony_ci return; 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci glFlush(); 155bf215546Sopenharmony_ci} 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_cistatic GLboolean 158bf215546Sopenharmony_cidri_is_thread_safe(void *loaderPrivate) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 161bf215546Sopenharmony_ci UNUSED _EGLDisplay *display = dri2_surf->base.Resource.Display; 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM 164bf215546Sopenharmony_ci Display *xdpy = (Display*)display->PlatformDisplay; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci /* Check Xlib is running in thread safe mode when running on EGL/X11-xlib 167bf215546Sopenharmony_ci * platform 168bf215546Sopenharmony_ci * 169bf215546Sopenharmony_ci * 'lock_fns' is the XLockDisplay function pointer of the X11 display 'dpy'. 170bf215546Sopenharmony_ci * It wll be NULL if XInitThreads wasn't called. 171bf215546Sopenharmony_ci */ 172bf215546Sopenharmony_ci if (display->Platform == _EGL_PLATFORM_X11 && xdpy && !xdpy->lock_fns) 173bf215546Sopenharmony_ci return false; 174bf215546Sopenharmony_ci#endif 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci return true; 177bf215546Sopenharmony_ci} 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ciconst __DRIbackgroundCallableExtension background_callable_extension = { 180bf215546Sopenharmony_ci .base = { __DRI_BACKGROUND_CALLABLE, 2 }, 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci .setBackgroundContext = dri_set_background_context, 183bf215546Sopenharmony_ci .isThreadSafe = dri_is_thread_safe, 184bf215546Sopenharmony_ci}; 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ciconst __DRIuseInvalidateExtension use_invalidate = { 187bf215546Sopenharmony_ci .base = { __DRI_USE_INVALIDATE, 1 } 188bf215546Sopenharmony_ci}; 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_cistatic void 191bf215546Sopenharmony_cidri2_get_pbuffer_drawable_info(__DRIdrawable * draw, 192bf215546Sopenharmony_ci int *x, int *y, int *w, int *h, 193bf215546Sopenharmony_ci void *loaderPrivate) 194bf215546Sopenharmony_ci{ 195bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci *x = *y = 0; 198bf215546Sopenharmony_ci *w = dri2_surf->base.Width; 199bf215546Sopenharmony_ci *h = dri2_surf->base.Height; 200bf215546Sopenharmony_ci} 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_cistatic int 203bf215546Sopenharmony_cidri2_get_bytes_per_pixel(struct dri2_egl_surface *dri2_surf) 204bf215546Sopenharmony_ci{ 205bf215546Sopenharmony_ci const int depth = dri2_surf->base.Config->BufferSize; 206bf215546Sopenharmony_ci return depth ? util_next_power_of_two(depth / 8) : 0; 207bf215546Sopenharmony_ci} 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_cistatic void 210bf215546Sopenharmony_cidri2_put_image(__DRIdrawable * draw, int op, 211bf215546Sopenharmony_ci int x, int y, int w, int h, 212bf215546Sopenharmony_ci char *data, void *loaderPrivate) 213bf215546Sopenharmony_ci{ 214bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 215bf215546Sopenharmony_ci const int bpp = dri2_get_bytes_per_pixel(dri2_surf); 216bf215546Sopenharmony_ci const int width = dri2_surf->base.Width; 217bf215546Sopenharmony_ci const int height = dri2_surf->base.Height; 218bf215546Sopenharmony_ci const int dst_stride = width*bpp; 219bf215546Sopenharmony_ci const int src_stride = w*bpp; 220bf215546Sopenharmony_ci const int x_offset = x*bpp; 221bf215546Sopenharmony_ci int copy_width = src_stride; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci if (!dri2_surf->swrast_device_buffer) 224bf215546Sopenharmony_ci dri2_surf->swrast_device_buffer = malloc(height*dst_stride); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci if (dri2_surf->swrast_device_buffer) { 227bf215546Sopenharmony_ci const char *src = data; 228bf215546Sopenharmony_ci char *dst = dri2_surf->swrast_device_buffer; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci dst += x_offset; 231bf215546Sopenharmony_ci dst += y*dst_stride; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci /* Drivers are allowed to submit OOB PutImage requests, so clip here. */ 234bf215546Sopenharmony_ci if (copy_width > dst_stride - x_offset) 235bf215546Sopenharmony_ci copy_width = dst_stride - x_offset; 236bf215546Sopenharmony_ci if (h > height - y) 237bf215546Sopenharmony_ci h = height - y; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci for (; 0 < h; --h) { 240bf215546Sopenharmony_ci memcpy(dst, src, copy_width); 241bf215546Sopenharmony_ci dst += dst_stride; 242bf215546Sopenharmony_ci src += src_stride; 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci } 245bf215546Sopenharmony_ci} 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_cistatic void 248bf215546Sopenharmony_cidri2_get_image(__DRIdrawable * read, 249bf215546Sopenharmony_ci int x, int y, int w, int h, 250bf215546Sopenharmony_ci char *data, void *loaderPrivate) 251bf215546Sopenharmony_ci{ 252bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = loaderPrivate; 253bf215546Sopenharmony_ci const int bpp = dri2_get_bytes_per_pixel(dri2_surf); 254bf215546Sopenharmony_ci const int width = dri2_surf->base.Width; 255bf215546Sopenharmony_ci const int height = dri2_surf->base.Height; 256bf215546Sopenharmony_ci const int src_stride = width*bpp; 257bf215546Sopenharmony_ci const int dst_stride = w*bpp; 258bf215546Sopenharmony_ci const int x_offset = x*bpp; 259bf215546Sopenharmony_ci int copy_width = dst_stride; 260bf215546Sopenharmony_ci const char *src = dri2_surf->swrast_device_buffer; 261bf215546Sopenharmony_ci char *dst = data; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci if (!src) { 264bf215546Sopenharmony_ci memset(data, 0, copy_width * h); 265bf215546Sopenharmony_ci return; 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci src += x_offset; 269bf215546Sopenharmony_ci src += y*src_stride; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* Drivers are allowed to submit OOB GetImage requests, so clip here. */ 272bf215546Sopenharmony_ci if (copy_width > src_stride - x_offset) 273bf215546Sopenharmony_ci copy_width = src_stride - x_offset; 274bf215546Sopenharmony_ci if (h > height - y) 275bf215546Sopenharmony_ci h = height - y; 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci for (; 0 < h; --h) { 278bf215546Sopenharmony_ci memcpy(dst, src, copy_width); 279bf215546Sopenharmony_ci src += src_stride; 280bf215546Sopenharmony_ci dst += dst_stride; 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci} 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci/* HACK: technically we should have swrast_null, instead of these. 286bf215546Sopenharmony_ci */ 287bf215546Sopenharmony_ciconst __DRIswrastLoaderExtension swrast_pbuffer_loader_extension = { 288bf215546Sopenharmony_ci .base = { __DRI_SWRAST_LOADER, 1 }, 289bf215546Sopenharmony_ci .getDrawableInfo = dri2_get_pbuffer_drawable_info, 290bf215546Sopenharmony_ci .putImage = dri2_put_image, 291bf215546Sopenharmony_ci .getImage = dri2_get_image, 292bf215546Sopenharmony_ci}; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_cistatic const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = { 295bf215546Sopenharmony_ci [__DRI_ATTRIB_BUFFER_SIZE ] = EGL_BUFFER_SIZE, 296bf215546Sopenharmony_ci [__DRI_ATTRIB_LEVEL] = EGL_LEVEL, 297bf215546Sopenharmony_ci [__DRI_ATTRIB_LUMINANCE_SIZE] = EGL_LUMINANCE_SIZE, 298bf215546Sopenharmony_ci [__DRI_ATTRIB_DEPTH_SIZE] = EGL_DEPTH_SIZE, 299bf215546Sopenharmony_ci [__DRI_ATTRIB_STENCIL_SIZE] = EGL_STENCIL_SIZE, 300bf215546Sopenharmony_ci [__DRI_ATTRIB_SAMPLE_BUFFERS] = EGL_SAMPLE_BUFFERS, 301bf215546Sopenharmony_ci [__DRI_ATTRIB_SAMPLES] = EGL_SAMPLES, 302bf215546Sopenharmony_ci [__DRI_ATTRIB_MAX_PBUFFER_WIDTH] = EGL_MAX_PBUFFER_WIDTH, 303bf215546Sopenharmony_ci [__DRI_ATTRIB_MAX_PBUFFER_HEIGHT] = EGL_MAX_PBUFFER_HEIGHT, 304bf215546Sopenharmony_ci [__DRI_ATTRIB_MAX_PBUFFER_PIXELS] = EGL_MAX_PBUFFER_PIXELS, 305bf215546Sopenharmony_ci [__DRI_ATTRIB_MAX_SWAP_INTERVAL] = EGL_MAX_SWAP_INTERVAL, 306bf215546Sopenharmony_ci [__DRI_ATTRIB_MIN_SWAP_INTERVAL] = EGL_MIN_SWAP_INTERVAL, 307bf215546Sopenharmony_ci [__DRI_ATTRIB_YINVERTED] = EGL_Y_INVERTED_NOK, 308bf215546Sopenharmony_ci}; 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ciconst __DRIconfig * 311bf215546Sopenharmony_cidri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type, 312bf215546Sopenharmony_ci EGLenum colorspace) 313bf215546Sopenharmony_ci{ 314bf215546Sopenharmony_ci const bool double_buffer = surface_type == EGL_WINDOW_BIT; 315bf215546Sopenharmony_ci const bool srgb = colorspace == EGL_GL_COLORSPACE_SRGB_KHR; 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci return conf->dri_config[double_buffer][srgb]; 318bf215546Sopenharmony_ci} 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_cistatic EGLBoolean 321bf215546Sopenharmony_cidri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) 322bf215546Sopenharmony_ci{ 323bf215546Sopenharmony_ci if (_eglCompareConfigs(conf, criteria, NULL, EGL_FALSE) != 0) 324bf215546Sopenharmony_ci return EGL_FALSE; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci if (!_eglMatchConfig(conf, criteria)) 327bf215546Sopenharmony_ci return EGL_FALSE; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci return EGL_TRUE; 330bf215546Sopenharmony_ci} 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_civoid 333bf215546Sopenharmony_cidri2_get_shifts_and_sizes(const __DRIcoreExtension *core, 334bf215546Sopenharmony_ci const __DRIconfig *config, int *shifts, 335bf215546Sopenharmony_ci unsigned int *sizes) 336bf215546Sopenharmony_ci{ 337bf215546Sopenharmony_ci unsigned int mask; 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci if (core->getConfigAttrib(config, __DRI_ATTRIB_RED_SHIFT, (unsigned int *)&shifts[0])) { 340bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_SHIFT, (unsigned int *)&shifts[1]); 341bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_SHIFT, (unsigned int *)&shifts[2]); 342bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_SHIFT, (unsigned int *)&shifts[3]); 343bf215546Sopenharmony_ci } else { 344bf215546Sopenharmony_ci /* Driver isn't exposing shifts, so convert masks to shifts */ 345bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_RED_MASK, &mask); 346bf215546Sopenharmony_ci shifts[0] = ffs(mask) - 1; 347bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_MASK, &mask); 348bf215546Sopenharmony_ci shifts[1] = ffs(mask) - 1; 349bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_MASK, &mask); 350bf215546Sopenharmony_ci shifts[2] = ffs(mask) - 1; 351bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_MASK, &mask); 352bf215546Sopenharmony_ci shifts[3] = ffs(mask) - 1; 353bf215546Sopenharmony_ci } 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_RED_SIZE, &sizes[0]); 356bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_GREEN_SIZE, &sizes[1]); 357bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_BLUE_SIZE, &sizes[2]); 358bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_SIZE, &sizes[3]); 359bf215546Sopenharmony_ci} 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_civoid 362bf215546Sopenharmony_cidri2_get_render_type_float(const __DRIcoreExtension *core, 363bf215546Sopenharmony_ci const __DRIconfig *config, 364bf215546Sopenharmony_ci bool *is_float) 365bf215546Sopenharmony_ci{ 366bf215546Sopenharmony_ci unsigned int render_type; 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci core->getConfigAttrib(config, __DRI_ATTRIB_RENDER_TYPE, &render_type); 369bf215546Sopenharmony_ci *is_float = (render_type & __DRI_ATTRIB_FLOAT_BIT) ? true : false; 370bf215546Sopenharmony_ci} 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ciunsigned int 373bf215546Sopenharmony_cidri2_image_format_for_pbuffer_config(struct dri2_egl_display *dri2_dpy, 374bf215546Sopenharmony_ci const __DRIconfig *config) 375bf215546Sopenharmony_ci{ 376bf215546Sopenharmony_ci int shifts[4]; 377bf215546Sopenharmony_ci unsigned int sizes[4]; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci dri2_get_shifts_and_sizes(dri2_dpy->core, config, shifts, sizes); 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(dri2_pbuffer_visuals); ++i) { 382bf215546Sopenharmony_ci const struct dri2_pbuffer_visual *visual = &dri2_pbuffer_visuals[i]; 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci if (shifts[0] == visual->rgba_shifts[0] && 385bf215546Sopenharmony_ci shifts[1] == visual->rgba_shifts[1] && 386bf215546Sopenharmony_ci shifts[2] == visual->rgba_shifts[2] && 387bf215546Sopenharmony_ci shifts[3] == visual->rgba_shifts[3] && 388bf215546Sopenharmony_ci sizes[0] == visual->rgba_sizes[0] && 389bf215546Sopenharmony_ci sizes[1] == visual->rgba_sizes[1] && 390bf215546Sopenharmony_ci sizes[2] == visual->rgba_sizes[2] && 391bf215546Sopenharmony_ci sizes[3] == visual->rgba_sizes[3]) { 392bf215546Sopenharmony_ci return visual->dri_image_format; 393bf215546Sopenharmony_ci } 394bf215546Sopenharmony_ci } 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci return __DRI_IMAGE_FORMAT_NONE; 397bf215546Sopenharmony_ci} 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_cistruct dri2_egl_config * 400bf215546Sopenharmony_cidri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, 401bf215546Sopenharmony_ci EGLint surface_type, const EGLint *attr_list, 402bf215546Sopenharmony_ci const int *rgba_shifts, const unsigned int *rgba_sizes) 403bf215546Sopenharmony_ci{ 404bf215546Sopenharmony_ci struct dri2_egl_config *conf; 405bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 406bf215546Sopenharmony_ci _EGLConfig base; 407bf215546Sopenharmony_ci unsigned int attrib, value, double_buffer; 408bf215546Sopenharmony_ci bool srgb = false; 409bf215546Sopenharmony_ci EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; 410bf215546Sopenharmony_ci int dri_shifts[4] = { -1, -1, -1, -1 }; 411bf215546Sopenharmony_ci unsigned int dri_sizes[4] = { 0, 0, 0, 0 }; 412bf215546Sopenharmony_ci _EGLConfig *matching_config; 413bf215546Sopenharmony_ci EGLint num_configs = 0; 414bf215546Sopenharmony_ci EGLint config_id; 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci _eglInitConfig(&base, disp, id); 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci double_buffer = 0; 419bf215546Sopenharmony_ci bind_to_texture_rgb = 0; 420bf215546Sopenharmony_ci bind_to_texture_rgba = 0; 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci for (int i = 0; i < __DRI_ATTRIB_MAX; ++i) { 423bf215546Sopenharmony_ci if (!dri2_dpy->core->indexConfigAttrib(dri_config, i, &attrib, &value)) 424bf215546Sopenharmony_ci break; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci switch (attrib) { 427bf215546Sopenharmony_ci case __DRI_ATTRIB_RENDER_TYPE: 428bf215546Sopenharmony_ci if (value & __DRI_ATTRIB_FLOAT_BIT) 429bf215546Sopenharmony_ci base.ComponentType = EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT; 430bf215546Sopenharmony_ci if (value & __DRI_ATTRIB_RGBA_BIT) 431bf215546Sopenharmony_ci value = EGL_RGB_BUFFER; 432bf215546Sopenharmony_ci else if (value & __DRI_ATTRIB_LUMINANCE_BIT) 433bf215546Sopenharmony_ci value = EGL_LUMINANCE_BUFFER; 434bf215546Sopenharmony_ci else 435bf215546Sopenharmony_ci return NULL; 436bf215546Sopenharmony_ci base.ColorBufferType = value; 437bf215546Sopenharmony_ci break; 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci case __DRI_ATTRIB_CONFIG_CAVEAT: 440bf215546Sopenharmony_ci if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) 441bf215546Sopenharmony_ci value = EGL_NON_CONFORMANT_CONFIG; 442bf215546Sopenharmony_ci else if (value & __DRI_ATTRIB_SLOW_BIT) 443bf215546Sopenharmony_ci value = EGL_SLOW_CONFIG; 444bf215546Sopenharmony_ci else 445bf215546Sopenharmony_ci value = EGL_NONE; 446bf215546Sopenharmony_ci base.ConfigCaveat = value; 447bf215546Sopenharmony_ci break; 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: 450bf215546Sopenharmony_ci bind_to_texture_rgb = value; 451bf215546Sopenharmony_ci break; 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: 454bf215546Sopenharmony_ci bind_to_texture_rgba = value; 455bf215546Sopenharmony_ci break; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci case __DRI_ATTRIB_DOUBLE_BUFFER: 458bf215546Sopenharmony_ci double_buffer = value; 459bf215546Sopenharmony_ci break; 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci case __DRI_ATTRIB_RED_SIZE: 462bf215546Sopenharmony_ci dri_sizes[0] = value; 463bf215546Sopenharmony_ci base.RedSize = value; 464bf215546Sopenharmony_ci break; 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci case __DRI_ATTRIB_RED_MASK: 467bf215546Sopenharmony_ci dri_shifts[0] = ffs(value) - 1; 468bf215546Sopenharmony_ci break; 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci case __DRI_ATTRIB_RED_SHIFT: 471bf215546Sopenharmony_ci dri_shifts[0] = value; 472bf215546Sopenharmony_ci break; 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci case __DRI_ATTRIB_GREEN_SIZE: 475bf215546Sopenharmony_ci dri_sizes[1] = value; 476bf215546Sopenharmony_ci base.GreenSize = value; 477bf215546Sopenharmony_ci break; 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci case __DRI_ATTRIB_GREEN_MASK: 480bf215546Sopenharmony_ci dri_shifts[1] = ffs(value) - 1; 481bf215546Sopenharmony_ci break; 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci case __DRI_ATTRIB_GREEN_SHIFT: 484bf215546Sopenharmony_ci dri_shifts[1] = value; 485bf215546Sopenharmony_ci break; 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci case __DRI_ATTRIB_BLUE_SIZE: 488bf215546Sopenharmony_ci dri_sizes[2] = value; 489bf215546Sopenharmony_ci base.BlueSize = value; 490bf215546Sopenharmony_ci break; 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci case __DRI_ATTRIB_BLUE_MASK: 493bf215546Sopenharmony_ci dri_shifts[2] = ffs(value) - 1; 494bf215546Sopenharmony_ci break; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci case __DRI_ATTRIB_BLUE_SHIFT: 497bf215546Sopenharmony_ci dri_shifts[2] = value; 498bf215546Sopenharmony_ci break; 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_ci case __DRI_ATTRIB_ALPHA_SIZE: 501bf215546Sopenharmony_ci dri_sizes[3] = value; 502bf215546Sopenharmony_ci base.AlphaSize = value; 503bf215546Sopenharmony_ci break; 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci case __DRI_ATTRIB_ALPHA_MASK: 506bf215546Sopenharmony_ci dri_shifts[3] = ffs(value) - 1; 507bf215546Sopenharmony_ci break; 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci case __DRI_ATTRIB_ALPHA_SHIFT: 510bf215546Sopenharmony_ci dri_shifts[3] = value; 511bf215546Sopenharmony_ci break; 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_ci case __DRI_ATTRIB_ACCUM_RED_SIZE: 514bf215546Sopenharmony_ci case __DRI_ATTRIB_ACCUM_GREEN_SIZE: 515bf215546Sopenharmony_ci case __DRI_ATTRIB_ACCUM_BLUE_SIZE: 516bf215546Sopenharmony_ci case __DRI_ATTRIB_ACCUM_ALPHA_SIZE: 517bf215546Sopenharmony_ci /* Don't expose visuals with the accumulation buffer. */ 518bf215546Sopenharmony_ci if (value > 0) 519bf215546Sopenharmony_ci return NULL; 520bf215546Sopenharmony_ci break; 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci case __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE: 523bf215546Sopenharmony_ci srgb = value != 0; 524bf215546Sopenharmony_ci if (!disp->Extensions.KHR_gl_colorspace && srgb) 525bf215546Sopenharmony_ci return NULL; 526bf215546Sopenharmony_ci break; 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci case __DRI_ATTRIB_MAX_PBUFFER_WIDTH: 529bf215546Sopenharmony_ci base.MaxPbufferWidth = _EGL_MAX_PBUFFER_WIDTH; 530bf215546Sopenharmony_ci break; 531bf215546Sopenharmony_ci case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT: 532bf215546Sopenharmony_ci base.MaxPbufferHeight = _EGL_MAX_PBUFFER_HEIGHT; 533bf215546Sopenharmony_ci break; 534bf215546Sopenharmony_ci case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER: 535bf215546Sopenharmony_ci if (disp->Extensions.KHR_mutable_render_buffer) 536bf215546Sopenharmony_ci surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR; 537bf215546Sopenharmony_ci break; 538bf215546Sopenharmony_ci default: 539bf215546Sopenharmony_ci key = dri2_to_egl_attribute_map[attrib]; 540bf215546Sopenharmony_ci if (key != 0) 541bf215546Sopenharmony_ci _eglSetConfigKey(&base, key, value); 542bf215546Sopenharmony_ci break; 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci if (attr_list) 547bf215546Sopenharmony_ci for (int i = 0; attr_list[i] != EGL_NONE; i += 2) 548bf215546Sopenharmony_ci _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]); 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci if (rgba_shifts && memcmp(rgba_shifts, dri_shifts, sizeof(dri_shifts))) 551bf215546Sopenharmony_ci return NULL; 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci if (rgba_sizes && memcmp(rgba_sizes, dri_sizes, sizeof(dri_sizes))) 554bf215546Sopenharmony_ci return NULL; 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci base.NativeRenderable = EGL_TRUE; 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci base.SurfaceType = surface_type; 559bf215546Sopenharmony_ci if (surface_type & (EGL_PBUFFER_BIT | 560bf215546Sopenharmony_ci (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) { 561bf215546Sopenharmony_ci base.BindToTextureRGB = bind_to_texture_rgb; 562bf215546Sopenharmony_ci if (base.AlphaSize > 0) 563bf215546Sopenharmony_ci base.BindToTextureRGBA = bind_to_texture_rgba; 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci if (double_buffer) { 567bf215546Sopenharmony_ci surface_type &= ~EGL_PIXMAP_BIT; 568bf215546Sopenharmony_ci } 569bf215546Sopenharmony_ci 570bf215546Sopenharmony_ci if (!surface_type) 571bf215546Sopenharmony_ci return NULL; 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci base.RenderableType = disp->ClientAPIs; 574bf215546Sopenharmony_ci base.Conformant = disp->ClientAPIs; 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci base.MinSwapInterval = dri2_dpy->min_swap_interval; 577bf215546Sopenharmony_ci base.MaxSwapInterval = dri2_dpy->max_swap_interval; 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci if (!_eglValidateConfig(&base, EGL_FALSE)) { 580bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); 581bf215546Sopenharmony_ci return NULL; 582bf215546Sopenharmony_ci } 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci config_id = base.ConfigID; 585bf215546Sopenharmony_ci base.ConfigID = EGL_DONT_CARE; 586bf215546Sopenharmony_ci base.SurfaceType = EGL_DONT_CARE; 587bf215546Sopenharmony_ci num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1, 588bf215546Sopenharmony_ci (_EGLArrayForEach) dri2_match_config, &base); 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci if (num_configs == 1) { 591bf215546Sopenharmony_ci conf = (struct dri2_egl_config *) matching_config; 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci if (!conf->dri_config[double_buffer][srgb]) 594bf215546Sopenharmony_ci conf->dri_config[double_buffer][srgb] = dri_config; 595bf215546Sopenharmony_ci else 596bf215546Sopenharmony_ci /* a similar config type is already added (unlikely) => discard */ 597bf215546Sopenharmony_ci return NULL; 598bf215546Sopenharmony_ci } 599bf215546Sopenharmony_ci else if (num_configs == 0) { 600bf215546Sopenharmony_ci conf = calloc(1, sizeof *conf); 601bf215546Sopenharmony_ci if (conf == NULL) 602bf215546Sopenharmony_ci return NULL; 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci conf->dri_config[double_buffer][srgb] = dri_config; 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci memcpy(&conf->base, &base, sizeof base); 607bf215546Sopenharmony_ci conf->base.SurfaceType = 0; 608bf215546Sopenharmony_ci conf->base.ConfigID = config_id; 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci _eglLinkConfig(&conf->base); 611bf215546Sopenharmony_ci } 612bf215546Sopenharmony_ci else { 613bf215546Sopenharmony_ci unreachable("duplicates should not be possible"); 614bf215546Sopenharmony_ci return NULL; 615bf215546Sopenharmony_ci } 616bf215546Sopenharmony_ci 617bf215546Sopenharmony_ci conf->base.SurfaceType |= surface_type; 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci return conf; 620bf215546Sopenharmony_ci} 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ciEGLBoolean 623bf215546Sopenharmony_cidri2_add_pbuffer_configs_for_visuals(_EGLDisplay *disp) 624bf215546Sopenharmony_ci{ 625bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 626bf215546Sopenharmony_ci unsigned int format_count[ARRAY_SIZE(dri2_pbuffer_visuals)] = { 0 }; 627bf215546Sopenharmony_ci unsigned int config_count = 0; 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci for (unsigned i = 0; dri2_dpy->driver_configs[i] != NULL; i++) { 630bf215546Sopenharmony_ci for (unsigned j = 0; j < ARRAY_SIZE(dri2_pbuffer_visuals); j++) { 631bf215546Sopenharmony_ci struct dri2_egl_config *dri2_conf; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i], 634bf215546Sopenharmony_ci config_count + 1, EGL_PBUFFER_BIT, NULL, 635bf215546Sopenharmony_ci dri2_pbuffer_visuals[j].rgba_shifts, dri2_pbuffer_visuals[j].rgba_sizes); 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci if (dri2_conf) { 638bf215546Sopenharmony_ci if (dri2_conf->base.ConfigID == config_count + 1) 639bf215546Sopenharmony_ci config_count++; 640bf215546Sopenharmony_ci format_count[j]++; 641bf215546Sopenharmony_ci } 642bf215546Sopenharmony_ci } 643bf215546Sopenharmony_ci } 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(format_count); i++) { 646bf215546Sopenharmony_ci if (!format_count[i]) { 647bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "No DRI config supports native format %s", 648bf215546Sopenharmony_ci dri2_pbuffer_visuals[i].format_name); 649bf215546Sopenharmony_ci } 650bf215546Sopenharmony_ci } 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci return (config_count != 0); 653bf215546Sopenharmony_ci} 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ciGLboolean 656bf215546Sopenharmony_cidri2_validate_egl_image(void *image, void *data) 657bf215546Sopenharmony_ci{ 658bf215546Sopenharmony_ci _EGLDisplay *disp = data; 659bf215546Sopenharmony_ci _EGLImage *img; 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci mtx_lock(&disp->Mutex); 662bf215546Sopenharmony_ci img = _eglLookupImage(image, disp); 663bf215546Sopenharmony_ci mtx_unlock(&disp->Mutex); 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci if (img == NULL) { 666bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_validate_egl_image"); 667bf215546Sopenharmony_ci return false; 668bf215546Sopenharmony_ci } 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_ci return true; 671bf215546Sopenharmony_ci} 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci__DRIimage * 674bf215546Sopenharmony_cidri2_lookup_egl_image_validated(void *image, void *data) 675bf215546Sopenharmony_ci{ 676bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img; 677bf215546Sopenharmony_ci 678bf215546Sopenharmony_ci (void)data; 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci dri2_img = dri2_egl_image(image); 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci return dri2_img->dri_image; 683bf215546Sopenharmony_ci} 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci__DRIimage * 686bf215546Sopenharmony_cidri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) 687bf215546Sopenharmony_ci{ 688bf215546Sopenharmony_ci (void) screen; 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci if (!dri2_validate_egl_image(image, data)) 691bf215546Sopenharmony_ci return NULL; 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci return dri2_lookup_egl_image_validated(image, data); 694bf215546Sopenharmony_ci} 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ciconst __DRIimageLookupExtension image_lookup_extension = { 697bf215546Sopenharmony_ci .base = { __DRI_IMAGE_LOOKUP, 2 }, 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci .lookupEGLImage = dri2_lookup_egl_image, 700bf215546Sopenharmony_ci .validateEGLImage = dri2_validate_egl_image, 701bf215546Sopenharmony_ci .lookupEGLImageValidated = dri2_lookup_egl_image_validated, 702bf215546Sopenharmony_ci}; 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_cistruct dri2_extension_match { 705bf215546Sopenharmony_ci const char *name; 706bf215546Sopenharmony_ci int version; 707bf215546Sopenharmony_ci int offset; 708bf215546Sopenharmony_ci}; 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_cistatic const struct dri2_extension_match dri3_driver_extensions[] = { 711bf215546Sopenharmony_ci { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, 712bf215546Sopenharmony_ci { __DRI_IMAGE_DRIVER, 1, offsetof(struct dri2_egl_display, image_driver) }, 713bf215546Sopenharmony_ci { NULL, 0, 0 } 714bf215546Sopenharmony_ci}; 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_cistatic const struct dri2_extension_match dri2_driver_extensions[] = { 717bf215546Sopenharmony_ci { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, 718bf215546Sopenharmony_ci { __DRI_DRI2, 2, offsetof(struct dri2_egl_display, dri2) }, 719bf215546Sopenharmony_ci { NULL, 0, 0 } 720bf215546Sopenharmony_ci}; 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_cistatic const struct dri2_extension_match dri2_core_extensions[] = { 723bf215546Sopenharmony_ci { __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) }, 724bf215546Sopenharmony_ci { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, 725bf215546Sopenharmony_ci { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) }, 726bf215546Sopenharmony_ci { NULL, 0, 0 } 727bf215546Sopenharmony_ci}; 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_cistatic const struct dri2_extension_match swrast_driver_extensions[] = { 730bf215546Sopenharmony_ci { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, 731bf215546Sopenharmony_ci { __DRI_SWRAST, 2, offsetof(struct dri2_egl_display, swrast) }, 732bf215546Sopenharmony_ci { NULL, 0, 0 } 733bf215546Sopenharmony_ci}; 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_cistatic const struct dri2_extension_match swrast_core_extensions[] = { 736bf215546Sopenharmony_ci { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, 737bf215546Sopenharmony_ci { NULL, 0, 0 } 738bf215546Sopenharmony_ci}; 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_cistatic const struct dri2_extension_match optional_driver_extensions[] = { 741bf215546Sopenharmony_ci { __DRI_CONFIG_OPTIONS, 1, offsetof(struct dri2_egl_display, configOptions) }, 742bf215546Sopenharmony_ci { NULL, 0, 0 } 743bf215546Sopenharmony_ci}; 744bf215546Sopenharmony_ci 745bf215546Sopenharmony_cistatic const struct dri2_extension_match optional_core_extensions[] = { 746bf215546Sopenharmony_ci { __DRI2_ROBUSTNESS, 1, offsetof(struct dri2_egl_display, robustness) }, 747bf215546Sopenharmony_ci { __DRI2_CONFIG_QUERY, 1, offsetof(struct dri2_egl_display, config) }, 748bf215546Sopenharmony_ci { __DRI2_FENCE, 1, offsetof(struct dri2_egl_display, fence) }, 749bf215546Sopenharmony_ci { __DRI2_BUFFER_DAMAGE, 1, offsetof(struct dri2_egl_display, buffer_damage) }, 750bf215546Sopenharmony_ci { __DRI2_RENDERER_QUERY, 1, offsetof(struct dri2_egl_display, rendererQuery) }, 751bf215546Sopenharmony_ci { __DRI2_INTEROP, 1, offsetof(struct dri2_egl_display, interop) }, 752bf215546Sopenharmony_ci { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) }, 753bf215546Sopenharmony_ci { __DRI2_FLUSH_CONTROL, 1, offsetof(struct dri2_egl_display, flush_control) }, 754bf215546Sopenharmony_ci { __DRI2_BLOB, 1, offsetof(struct dri2_egl_display, blob) }, 755bf215546Sopenharmony_ci { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1, offsetof(struct dri2_egl_display, mutable_render_buffer) }, 756bf215546Sopenharmony_ci { __DRI_KOPPER, 1, offsetof(struct dri2_egl_display, kopper) }, 757bf215546Sopenharmony_ci { NULL, 0, 0 } 758bf215546Sopenharmony_ci}; 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_cistatic EGLBoolean 761bf215546Sopenharmony_cidri2_bind_extensions(struct dri2_egl_display *dri2_dpy, 762bf215546Sopenharmony_ci const struct dri2_extension_match *matches, 763bf215546Sopenharmony_ci const __DRIextension **extensions, 764bf215546Sopenharmony_ci bool optional) 765bf215546Sopenharmony_ci{ 766bf215546Sopenharmony_ci int ret = EGL_TRUE; 767bf215546Sopenharmony_ci void *field; 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ci for (int i = 0; extensions[i]; i++) { 770bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "found extension `%s'", extensions[i]->name); 771bf215546Sopenharmony_ci for (int j = 0; matches[j].name; j++) { 772bf215546Sopenharmony_ci if (strcmp(extensions[i]->name, matches[j].name) == 0 && 773bf215546Sopenharmony_ci extensions[i]->version >= matches[j].version) { 774bf215546Sopenharmony_ci field = ((char *) dri2_dpy + matches[j].offset); 775bf215546Sopenharmony_ci *(const __DRIextension **) field = extensions[i]; 776bf215546Sopenharmony_ci _eglLog(_EGL_INFO, "found extension %s version %d", 777bf215546Sopenharmony_ci extensions[i]->name, extensions[i]->version); 778bf215546Sopenharmony_ci break; 779bf215546Sopenharmony_ci } 780bf215546Sopenharmony_ci } 781bf215546Sopenharmony_ci } 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci for (int j = 0; matches[j].name; j++) { 784bf215546Sopenharmony_ci field = ((char *) dri2_dpy + matches[j].offset); 785bf215546Sopenharmony_ci if (*(const __DRIextension **) field == NULL) { 786bf215546Sopenharmony_ci if (optional) { 787bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "did not find optional extension %s version %d", 788bf215546Sopenharmony_ci matches[j].name, matches[j].version); 789bf215546Sopenharmony_ci } else { 790bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "did not find extension %s version %d", 791bf215546Sopenharmony_ci matches[j].name, matches[j].version); 792bf215546Sopenharmony_ci ret = EGL_FALSE; 793bf215546Sopenharmony_ci } 794bf215546Sopenharmony_ci } 795bf215546Sopenharmony_ci } 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci return ret; 798bf215546Sopenharmony_ci} 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_cistatic const __DRIextension ** 801bf215546Sopenharmony_cidri2_open_driver(_EGLDisplay *disp) 802bf215546Sopenharmony_ci{ 803bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 804bf215546Sopenharmony_ci static const char *search_path_vars[] = { 805bf215546Sopenharmony_ci "LIBGL_DRIVERS_PATH", 806bf215546Sopenharmony_ci NULL, 807bf215546Sopenharmony_ci }; 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci return loader_open_driver(dri2_dpy->driver_name, 810bf215546Sopenharmony_ci &dri2_dpy->driver, 811bf215546Sopenharmony_ci search_path_vars); 812bf215546Sopenharmony_ci} 813bf215546Sopenharmony_ci 814bf215546Sopenharmony_cistatic EGLBoolean 815bf215546Sopenharmony_cidri2_load_driver_common(_EGLDisplay *disp, 816bf215546Sopenharmony_ci const struct dri2_extension_match *driver_extensions) 817bf215546Sopenharmony_ci{ 818bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 819bf215546Sopenharmony_ci const __DRIextension **extensions; 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci extensions = dri2_open_driver(disp); 822bf215546Sopenharmony_ci if (!extensions) 823bf215546Sopenharmony_ci return EGL_FALSE; 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_ci if (!dri2_bind_extensions(dri2_dpy, driver_extensions, extensions, false)) { 826bf215546Sopenharmony_ci dlclose(dri2_dpy->driver); 827bf215546Sopenharmony_ci dri2_dpy->driver = NULL; 828bf215546Sopenharmony_ci return EGL_FALSE; 829bf215546Sopenharmony_ci } 830bf215546Sopenharmony_ci dri2_dpy->driver_extensions = extensions; 831bf215546Sopenharmony_ci 832bf215546Sopenharmony_ci dri2_bind_extensions(dri2_dpy, optional_driver_extensions, extensions, true); 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci return EGL_TRUE; 835bf215546Sopenharmony_ci} 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ciEGLBoolean 838bf215546Sopenharmony_cidri2_load_driver(_EGLDisplay *disp) 839bf215546Sopenharmony_ci{ 840bf215546Sopenharmony_ci return dri2_load_driver_common(disp, dri2_driver_extensions); 841bf215546Sopenharmony_ci} 842bf215546Sopenharmony_ci 843bf215546Sopenharmony_ciEGLBoolean 844bf215546Sopenharmony_cidri2_load_driver_dri3(_EGLDisplay *disp) 845bf215546Sopenharmony_ci{ 846bf215546Sopenharmony_ci return dri2_load_driver_common(disp, dri3_driver_extensions); 847bf215546Sopenharmony_ci} 848bf215546Sopenharmony_ci 849bf215546Sopenharmony_ciEGLBoolean 850bf215546Sopenharmony_cidri2_load_driver_swrast(_EGLDisplay *disp) 851bf215546Sopenharmony_ci{ 852bf215546Sopenharmony_ci return dri2_load_driver_common(disp, swrast_driver_extensions); 853bf215546Sopenharmony_ci} 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_cistatic unsigned 856bf215546Sopenharmony_cidri2_renderer_query_integer(struct dri2_egl_display *dri2_dpy, int param) 857bf215546Sopenharmony_ci{ 858bf215546Sopenharmony_ci const __DRI2rendererQueryExtension *rendererQuery = dri2_dpy->rendererQuery; 859bf215546Sopenharmony_ci unsigned int value = 0; 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci if (!rendererQuery || 862bf215546Sopenharmony_ci rendererQuery->queryInteger(dri2_dpy->dri_screen, param, &value) == -1) 863bf215546Sopenharmony_ci return 0; 864bf215546Sopenharmony_ci 865bf215546Sopenharmony_ci return value; 866bf215546Sopenharmony_ci} 867bf215546Sopenharmony_ci 868bf215546Sopenharmony_cistatic const char * 869bf215546Sopenharmony_cidri2_query_driver_name(_EGLDisplay *disp) 870bf215546Sopenharmony_ci{ 871bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 872bf215546Sopenharmony_ci return dri2_dpy->driver_name; 873bf215546Sopenharmony_ci} 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_cistatic char * 876bf215546Sopenharmony_cidri2_query_driver_config(_EGLDisplay *disp) 877bf215546Sopenharmony_ci{ 878bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 879bf215546Sopenharmony_ci const __DRIconfigOptionsExtension *ext = dri2_dpy->configOptions; 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_ci if (ext->base.version >= 2) 882bf215546Sopenharmony_ci return ext->getXml(dri2_dpy->driver_name); 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci return strdup(ext->xml); 885bf215546Sopenharmony_ci} 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_civoid 889bf215546Sopenharmony_cidri2_setup_screen(_EGLDisplay *disp) 890bf215546Sopenharmony_ci{ 891bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 892bf215546Sopenharmony_ci unsigned int api_mask; 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci /* 895bf215546Sopenharmony_ci * EGL 1.5 specification defines the default value to 1. Moreover, 896bf215546Sopenharmony_ci * eglSwapInterval() is required to clamp requested value to the supported 897bf215546Sopenharmony_ci * range. Since the default value is implicitly assumed to be supported, 898bf215546Sopenharmony_ci * use it as both minimum and maximum for the platforms that do not allow 899bf215546Sopenharmony_ci * changing the interval. Platforms, which allow it (e.g. x11, wayland) 900bf215546Sopenharmony_ci * override these values already. 901bf215546Sopenharmony_ci */ 902bf215546Sopenharmony_ci dri2_dpy->min_swap_interval = 1; 903bf215546Sopenharmony_ci dri2_dpy->max_swap_interval = 1; 904bf215546Sopenharmony_ci dri2_dpy->default_swap_interval = 1; 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_ci if (dri2_dpy->image_driver) { 907bf215546Sopenharmony_ci api_mask = dri2_dpy->image_driver->getAPIMask(dri2_dpy->dri_screen); 908bf215546Sopenharmony_ci } else if (dri2_dpy->dri2) { 909bf215546Sopenharmony_ci api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen); 910bf215546Sopenharmony_ci } else { 911bf215546Sopenharmony_ci assert(dri2_dpy->swrast); 912bf215546Sopenharmony_ci api_mask = 1 << __DRI_API_OPENGL | 913bf215546Sopenharmony_ci 1 << __DRI_API_GLES | 914bf215546Sopenharmony_ci 1 << __DRI_API_GLES2 | 915bf215546Sopenharmony_ci 1 << __DRI_API_GLES3; 916bf215546Sopenharmony_ci } 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci disp->ClientAPIs = 0; 919bf215546Sopenharmony_ci if ((api_mask & (1 <<__DRI_API_OPENGL)) && _eglIsApiValid(EGL_OPENGL_API)) 920bf215546Sopenharmony_ci disp->ClientAPIs |= EGL_OPENGL_BIT; 921bf215546Sopenharmony_ci if ((api_mask & (1 << __DRI_API_GLES)) && _eglIsApiValid(EGL_OPENGL_ES_API)) 922bf215546Sopenharmony_ci disp->ClientAPIs |= EGL_OPENGL_ES_BIT; 923bf215546Sopenharmony_ci if ((api_mask & (1 << __DRI_API_GLES2)) && _eglIsApiValid(EGL_OPENGL_ES_API)) 924bf215546Sopenharmony_ci disp->ClientAPIs |= EGL_OPENGL_ES2_BIT; 925bf215546Sopenharmony_ci if ((api_mask & (1 << __DRI_API_GLES3)) && _eglIsApiValid(EGL_OPENGL_ES_API)) 926bf215546Sopenharmony_ci disp->ClientAPIs |= EGL_OPENGL_ES3_BIT_KHR; 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci assert(dri2_dpy->image_driver || dri2_dpy->dri2 || dri2_dpy->swrast); 929bf215546Sopenharmony_ci disp->Extensions.KHR_no_config_context = EGL_TRUE; 930bf215546Sopenharmony_ci disp->Extensions.KHR_surfaceless_context = EGL_TRUE; 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci if (dri2_dpy->configOptions) { 933bf215546Sopenharmony_ci disp->Extensions.MESA_query_driver = EGL_TRUE; 934bf215546Sopenharmony_ci } 935bf215546Sopenharmony_ci 936bf215546Sopenharmony_ci /* Report back to EGL the bitmask of priorities supported */ 937bf215546Sopenharmony_ci disp->Extensions.IMG_context_priority = 938bf215546Sopenharmony_ci dri2_renderer_query_integer(dri2_dpy, 939bf215546Sopenharmony_ci __DRI2_RENDERER_HAS_CONTEXT_PRIORITY); 940bf215546Sopenharmony_ci 941bf215546Sopenharmony_ci disp->Extensions.EXT_pixel_format_float = EGL_TRUE; 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci if (dri2_renderer_query_integer(dri2_dpy, 944bf215546Sopenharmony_ci __DRI2_RENDERER_HAS_FRAMEBUFFER_SRGB)) 945bf215546Sopenharmony_ci disp->Extensions.KHR_gl_colorspace = EGL_TRUE; 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci if (dri2_dpy->image_driver || 948bf215546Sopenharmony_ci (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) || 949bf215546Sopenharmony_ci (dri2_dpy->swrast && dri2_dpy->swrast->base.version >= 3)) { 950bf215546Sopenharmony_ci disp->Extensions.KHR_create_context = EGL_TRUE; 951bf215546Sopenharmony_ci 952bf215546Sopenharmony_ci if (dri2_dpy->robustness) 953bf215546Sopenharmony_ci disp->Extensions.EXT_create_context_robustness = EGL_TRUE; 954bf215546Sopenharmony_ci } 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci if (dri2_renderer_query_integer(dri2_dpy, 957bf215546Sopenharmony_ci __DRI2_RENDERER_HAS_NO_ERROR_CONTEXT)) 958bf215546Sopenharmony_ci disp->Extensions.KHR_create_context_no_error = EGL_TRUE; 959bf215546Sopenharmony_ci 960bf215546Sopenharmony_ci if (dri2_dpy->fence) { 961bf215546Sopenharmony_ci disp->Extensions.KHR_fence_sync = EGL_TRUE; 962bf215546Sopenharmony_ci disp->Extensions.KHR_wait_sync = EGL_TRUE; 963bf215546Sopenharmony_ci if (dri2_dpy->fence->get_fence_from_cl_event) 964bf215546Sopenharmony_ci disp->Extensions.KHR_cl_event2 = EGL_TRUE; 965bf215546Sopenharmony_ci if (dri2_dpy->fence->base.version >= 2 && 966bf215546Sopenharmony_ci dri2_dpy->fence->get_capabilities) { 967bf215546Sopenharmony_ci unsigned capabilities = 968bf215546Sopenharmony_ci dri2_dpy->fence->get_capabilities(dri2_dpy->dri_screen); 969bf215546Sopenharmony_ci disp->Extensions.ANDROID_native_fence_sync = 970bf215546Sopenharmony_ci (capabilities & __DRI_FENCE_CAP_NATIVE_FD) != 0; 971bf215546Sopenharmony_ci } 972bf215546Sopenharmony_ci } 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci if (dri2_dpy->blob) 975bf215546Sopenharmony_ci disp->Extensions.ANDROID_blob_cache = EGL_TRUE; 976bf215546Sopenharmony_ci 977bf215546Sopenharmony_ci disp->Extensions.KHR_reusable_sync = EGL_TRUE; 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci if (dri2_dpy->image) { 980bf215546Sopenharmony_ci if (dri2_dpy->image->base.version >= 10 && 981bf215546Sopenharmony_ci dri2_dpy->image->getCapabilities != NULL) { 982bf215546Sopenharmony_ci int capabilities; 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci capabilities = dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen); 985bf215546Sopenharmony_ci disp->Extensions.MESA_drm_image = (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0; 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci if (dri2_dpy->image->base.version >= 11) 988bf215546Sopenharmony_ci disp->Extensions.MESA_image_dma_buf_export = EGL_TRUE; 989bf215546Sopenharmony_ci } else { 990bf215546Sopenharmony_ci disp->Extensions.MESA_drm_image = EGL_TRUE; 991bf215546Sopenharmony_ci if (dri2_dpy->image->base.version >= 11) 992bf215546Sopenharmony_ci disp->Extensions.MESA_image_dma_buf_export = EGL_TRUE; 993bf215546Sopenharmony_ci } 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_ci disp->Extensions.KHR_image_base = EGL_TRUE; 996bf215546Sopenharmony_ci disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; 997bf215546Sopenharmony_ci if (dri2_dpy->image->base.version >= 5 && 998bf215546Sopenharmony_ci dri2_dpy->image->createImageFromTexture) { 999bf215546Sopenharmony_ci disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE; 1000bf215546Sopenharmony_ci disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE; 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci if (dri2_renderer_query_integer(dri2_dpy, 1003bf215546Sopenharmony_ci __DRI2_RENDERER_HAS_TEXTURE_3D)) 1004bf215546Sopenharmony_ci disp->Extensions.KHR_gl_texture_3D_image = EGL_TRUE; 1005bf215546Sopenharmony_ci } 1006bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 1007bf215546Sopenharmony_ci if (dri2_dpy->image->base.version >= 8 && 1008bf215546Sopenharmony_ci dri2_dpy->image->createImageFromDmaBufs) { 1009bf215546Sopenharmony_ci disp->Extensions.EXT_image_dma_buf_import = EGL_TRUE; 1010bf215546Sopenharmony_ci disp->Extensions.EXT_image_dma_buf_import_modifiers = EGL_TRUE; 1011bf215546Sopenharmony_ci } 1012bf215546Sopenharmony_ci#endif 1013bf215546Sopenharmony_ci } 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci if (dri2_dpy->flush_control) 1016bf215546Sopenharmony_ci disp->Extensions.KHR_context_flush_control = EGL_TRUE; 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ci if (dri2_dpy->buffer_damage && dri2_dpy->buffer_damage->set_damage_region) 1019bf215546Sopenharmony_ci disp->Extensions.KHR_partial_update = EGL_TRUE; 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci disp->Extensions.EXT_protected_surface = 1022bf215546Sopenharmony_ci dri2_renderer_query_integer(dri2_dpy, 1023bf215546Sopenharmony_ci __DRI2_RENDERER_HAS_PROTECTED_CONTENT); 1024bf215546Sopenharmony_ci} 1025bf215546Sopenharmony_ci 1026bf215546Sopenharmony_civoid 1027bf215546Sopenharmony_cidri2_setup_swap_interval(_EGLDisplay *disp, int max_swap_interval) 1028bf215546Sopenharmony_ci{ 1029bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1030bf215546Sopenharmony_ci GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; 1031bf215546Sopenharmony_ci 1032bf215546Sopenharmony_ci /* Allow driconf to override applications.*/ 1033bf215546Sopenharmony_ci if (dri2_dpy->config) 1034bf215546Sopenharmony_ci dri2_dpy->config->configQueryi(dri2_dpy->dri_screen, 1035bf215546Sopenharmony_ci "vblank_mode", &vblank_mode); 1036bf215546Sopenharmony_ci switch (vblank_mode) { 1037bf215546Sopenharmony_ci case DRI_CONF_VBLANK_NEVER: 1038bf215546Sopenharmony_ci dri2_dpy->min_swap_interval = 0; 1039bf215546Sopenharmony_ci dri2_dpy->max_swap_interval = 0; 1040bf215546Sopenharmony_ci dri2_dpy->default_swap_interval = 0; 1041bf215546Sopenharmony_ci break; 1042bf215546Sopenharmony_ci case DRI_CONF_VBLANK_ALWAYS_SYNC: 1043bf215546Sopenharmony_ci dri2_dpy->min_swap_interval = 1; 1044bf215546Sopenharmony_ci dri2_dpy->max_swap_interval = max_swap_interval; 1045bf215546Sopenharmony_ci dri2_dpy->default_swap_interval = 1; 1046bf215546Sopenharmony_ci break; 1047bf215546Sopenharmony_ci case DRI_CONF_VBLANK_DEF_INTERVAL_0: 1048bf215546Sopenharmony_ci dri2_dpy->min_swap_interval = 0; 1049bf215546Sopenharmony_ci dri2_dpy->max_swap_interval = max_swap_interval; 1050bf215546Sopenharmony_ci dri2_dpy->default_swap_interval = 0; 1051bf215546Sopenharmony_ci break; 1052bf215546Sopenharmony_ci default: 1053bf215546Sopenharmony_ci case DRI_CONF_VBLANK_DEF_INTERVAL_1: 1054bf215546Sopenharmony_ci dri2_dpy->min_swap_interval = 0; 1055bf215546Sopenharmony_ci dri2_dpy->max_swap_interval = max_swap_interval; 1056bf215546Sopenharmony_ci dri2_dpy->default_swap_interval = 1; 1057bf215546Sopenharmony_ci break; 1058bf215546Sopenharmony_ci } 1059bf215546Sopenharmony_ci} 1060bf215546Sopenharmony_ci 1061bf215546Sopenharmony_ci/* All platforms but DRM call this function to create the screen and populate 1062bf215546Sopenharmony_ci * the driver_configs. DRM inherits that information from its display - GBM. 1063bf215546Sopenharmony_ci */ 1064bf215546Sopenharmony_ciEGLBoolean 1065bf215546Sopenharmony_cidri2_create_screen(_EGLDisplay *disp) 1066bf215546Sopenharmony_ci{ 1067bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_ci if (dri2_dpy->image_driver) { 1070bf215546Sopenharmony_ci dri2_dpy->dri_screen = 1071bf215546Sopenharmony_ci dri2_dpy->image_driver->createNewScreen2(0, dri2_dpy->fd, 1072bf215546Sopenharmony_ci dri2_dpy->loader_extensions, 1073bf215546Sopenharmony_ci dri2_dpy->driver_extensions, 1074bf215546Sopenharmony_ci &dri2_dpy->driver_configs, 1075bf215546Sopenharmony_ci disp); 1076bf215546Sopenharmony_ci } else if (dri2_dpy->dri2) { 1077bf215546Sopenharmony_ci if (dri2_dpy->dri2->base.version >= 4) { 1078bf215546Sopenharmony_ci dri2_dpy->dri_screen = 1079bf215546Sopenharmony_ci dri2_dpy->dri2->createNewScreen2(0, dri2_dpy->fd, 1080bf215546Sopenharmony_ci dri2_dpy->loader_extensions, 1081bf215546Sopenharmony_ci dri2_dpy->driver_extensions, 1082bf215546Sopenharmony_ci &dri2_dpy->driver_configs, disp); 1083bf215546Sopenharmony_ci } else { 1084bf215546Sopenharmony_ci dri2_dpy->dri_screen = 1085bf215546Sopenharmony_ci dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, 1086bf215546Sopenharmony_ci dri2_dpy->loader_extensions, 1087bf215546Sopenharmony_ci &dri2_dpy->driver_configs, disp); 1088bf215546Sopenharmony_ci } 1089bf215546Sopenharmony_ci } else { 1090bf215546Sopenharmony_ci assert(dri2_dpy->swrast); 1091bf215546Sopenharmony_ci if (dri2_dpy->swrast->base.version >= 4) { 1092bf215546Sopenharmony_ci dri2_dpy->dri_screen = 1093bf215546Sopenharmony_ci dri2_dpy->swrast->createNewScreen2(0, dri2_dpy->loader_extensions, 1094bf215546Sopenharmony_ci dri2_dpy->driver_extensions, 1095bf215546Sopenharmony_ci &dri2_dpy->driver_configs, disp); 1096bf215546Sopenharmony_ci } else { 1097bf215546Sopenharmony_ci dri2_dpy->dri_screen = 1098bf215546Sopenharmony_ci dri2_dpy->swrast->createNewScreen(0, dri2_dpy->loader_extensions, 1099bf215546Sopenharmony_ci &dri2_dpy->driver_configs, disp); 1100bf215546Sopenharmony_ci } 1101bf215546Sopenharmony_ci } 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci if (dri2_dpy->dri_screen == NULL) { 1104bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "egl: failed to create dri2 screen"); 1105bf215546Sopenharmony_ci return EGL_FALSE; 1106bf215546Sopenharmony_ci } 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci dri2_dpy->own_dri_screen = true; 1109bf215546Sopenharmony_ci return EGL_TRUE; 1110bf215546Sopenharmony_ci} 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ciEGLBoolean 1113bf215546Sopenharmony_cidri2_setup_extensions(_EGLDisplay *disp) 1114bf215546Sopenharmony_ci{ 1115bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1116bf215546Sopenharmony_ci const struct dri2_extension_match *mandatory_core_extensions; 1117bf215546Sopenharmony_ci const __DRIextension **extensions; 1118bf215546Sopenharmony_ci 1119bf215546Sopenharmony_ci extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); 1120bf215546Sopenharmony_ci 1121bf215546Sopenharmony_ci if (dri2_dpy->image_driver || dri2_dpy->dri2) 1122bf215546Sopenharmony_ci mandatory_core_extensions = dri2_core_extensions; 1123bf215546Sopenharmony_ci else 1124bf215546Sopenharmony_ci mandatory_core_extensions = swrast_core_extensions; 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_ci if (!dri2_bind_extensions(dri2_dpy, mandatory_core_extensions, extensions, false)) 1127bf215546Sopenharmony_ci return EGL_FALSE; 1128bf215546Sopenharmony_ci 1129bf215546Sopenharmony_ci#ifdef HAVE_DRI3_MODIFIERS 1130bf215546Sopenharmony_ci dri2_dpy->multibuffers_available = 1131bf215546Sopenharmony_ci (dri2_dpy->dri3_major_version > 1 || (dri2_dpy->dri3_major_version == 1 && 1132bf215546Sopenharmony_ci dri2_dpy->dri3_minor_version >= 2)) && 1133bf215546Sopenharmony_ci (dri2_dpy->present_major_version > 1 || (dri2_dpy->present_major_version == 1 && 1134bf215546Sopenharmony_ci dri2_dpy->present_minor_version >= 2)) && 1135bf215546Sopenharmony_ci (dri2_dpy->image && dri2_dpy->image->base.version >= 15); 1136bf215546Sopenharmony_ci#endif 1137bf215546Sopenharmony_ci 1138bf215546Sopenharmony_ci dri2_bind_extensions(dri2_dpy, optional_core_extensions, extensions, true); 1139bf215546Sopenharmony_ci return EGL_TRUE; 1140bf215546Sopenharmony_ci} 1141bf215546Sopenharmony_ci 1142bf215546Sopenharmony_ci/** 1143bf215546Sopenharmony_ci * Called via eglInitialize(), drv->Initialize(). 1144bf215546Sopenharmony_ci * 1145bf215546Sopenharmony_ci * This must be guaranteed to be called exactly once, even if eglInitialize is 1146bf215546Sopenharmony_ci * called many times (without a eglTerminate in between). 1147bf215546Sopenharmony_ci */ 1148bf215546Sopenharmony_cistatic EGLBoolean 1149bf215546Sopenharmony_cidri2_initialize(_EGLDisplay *disp) 1150bf215546Sopenharmony_ci{ 1151bf215546Sopenharmony_ci EGLBoolean ret = EGL_FALSE; 1152bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1153bf215546Sopenharmony_ci 1154bf215546Sopenharmony_ci /* In the case where the application calls eglMakeCurrent(context1), 1155bf215546Sopenharmony_ci * eglTerminate, then eglInitialize again (without a call to eglReleaseThread 1156bf215546Sopenharmony_ci * or eglMakeCurrent(NULL) before that), dri2_dpy structure is still 1157bf215546Sopenharmony_ci * initialized, as we need it to be able to free context1 correctly. 1158bf215546Sopenharmony_ci * 1159bf215546Sopenharmony_ci * It would probably be safest to forcibly release the display with 1160bf215546Sopenharmony_ci * dri2_display_release, to make sure the display is reinitialized correctly. 1161bf215546Sopenharmony_ci * However, the EGL spec states that we need to keep a reference to the 1162bf215546Sopenharmony_ci * current context (so we cannot call dri2_make_current(NULL)), and therefore 1163bf215546Sopenharmony_ci * we would leak context1 as we would be missing the old display connection 1164bf215546Sopenharmony_ci * to free it up correctly. 1165bf215546Sopenharmony_ci */ 1166bf215546Sopenharmony_ci if (dri2_dpy) { 1167bf215546Sopenharmony_ci dri2_dpy->ref_count++; 1168bf215546Sopenharmony_ci return EGL_TRUE; 1169bf215546Sopenharmony_ci } 1170bf215546Sopenharmony_ci 1171bf215546Sopenharmony_ci loader_set_logger(_eglLog); 1172bf215546Sopenharmony_ci 1173bf215546Sopenharmony_ci switch (disp->Platform) { 1174bf215546Sopenharmony_ci case _EGL_PLATFORM_SURFACELESS: 1175bf215546Sopenharmony_ci ret = dri2_initialize_surfaceless(disp); 1176bf215546Sopenharmony_ci break; 1177bf215546Sopenharmony_ci case _EGL_PLATFORM_DEVICE: 1178bf215546Sopenharmony_ci ret = dri2_initialize_device(disp); 1179bf215546Sopenharmony_ci break; 1180bf215546Sopenharmony_ci case _EGL_PLATFORM_X11: 1181bf215546Sopenharmony_ci case _EGL_PLATFORM_XCB: 1182bf215546Sopenharmony_ci ret = dri2_initialize_x11(disp); 1183bf215546Sopenharmony_ci break; 1184bf215546Sopenharmony_ci case _EGL_PLATFORM_DRM: 1185bf215546Sopenharmony_ci ret = dri2_initialize_drm(disp); 1186bf215546Sopenharmony_ci break; 1187bf215546Sopenharmony_ci case _EGL_PLATFORM_WAYLAND: 1188bf215546Sopenharmony_ci ret = dri2_initialize_wayland(disp); 1189bf215546Sopenharmony_ci break; 1190bf215546Sopenharmony_ci case _EGL_PLATFORM_ANDROID: 1191bf215546Sopenharmony_ci ret = dri2_initialize_android(disp); 1192bf215546Sopenharmony_ci break; 1193bf215546Sopenharmony_ci case _EGL_PLATFORM_OHOS: 1194bf215546Sopenharmony_ci // NEED add openharmony init for dri2 1195bf215546Sopenharmony_ci ret = dri2_initialize_ohos(disp); 1196bf215546Sopenharmony_ci break; 1197bf215546Sopenharmony_ci default: 1198bf215546Sopenharmony_ci unreachable("Callers ensure we cannot get here."); 1199bf215546Sopenharmony_ci return EGL_FALSE; 1200bf215546Sopenharmony_ci } 1201bf215546Sopenharmony_ci 1202bf215546Sopenharmony_ci if (!ret) 1203bf215546Sopenharmony_ci return EGL_FALSE; 1204bf215546Sopenharmony_ci 1205bf215546Sopenharmony_ci dri2_dpy = dri2_egl_display(disp); 1206bf215546Sopenharmony_ci dri2_dpy->ref_count++; 1207bf215546Sopenharmony_ci 1208bf215546Sopenharmony_ci return EGL_TRUE; 1209bf215546Sopenharmony_ci} 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_ci/** 1212bf215546Sopenharmony_ci * Decrement display reference count, and free up display if necessary. 1213bf215546Sopenharmony_ci */ 1214bf215546Sopenharmony_cistatic void 1215bf215546Sopenharmony_cidri2_display_release(_EGLDisplay *disp) 1216bf215546Sopenharmony_ci{ 1217bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy; 1218bf215546Sopenharmony_ci 1219bf215546Sopenharmony_ci if (!disp) 1220bf215546Sopenharmony_ci return; 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci dri2_dpy = dri2_egl_display(disp); 1223bf215546Sopenharmony_ci 1224bf215546Sopenharmony_ci assert(dri2_dpy->ref_count > 0); 1225bf215546Sopenharmony_ci dri2_dpy->ref_count--; 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_ci if (dri2_dpy->ref_count > 0) 1228bf215546Sopenharmony_ci return; 1229bf215546Sopenharmony_ci 1230bf215546Sopenharmony_ci _eglCleanupDisplay(disp); 1231bf215546Sopenharmony_ci dri2_display_destroy(disp); 1232bf215546Sopenharmony_ci} 1233bf215546Sopenharmony_ci 1234bf215546Sopenharmony_civoid 1235bf215546Sopenharmony_cidri2_display_destroy(_EGLDisplay *disp) 1236bf215546Sopenharmony_ci{ 1237bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1238bf215546Sopenharmony_ci 1239bf215546Sopenharmony_ci if (dri2_dpy->own_dri_screen) { 1240bf215546Sopenharmony_ci if (dri2_dpy->vtbl && dri2_dpy->vtbl->close_screen_notify) 1241bf215546Sopenharmony_ci dri2_dpy->vtbl->close_screen_notify(disp); 1242bf215546Sopenharmony_ci dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); 1243bf215546Sopenharmony_ci } 1244bf215546Sopenharmony_ci if (dri2_dpy->fd >= 0) 1245bf215546Sopenharmony_ci close(dri2_dpy->fd); 1246bf215546Sopenharmony_ci 1247bf215546Sopenharmony_ci /* Don't dlclose the driver when building with the address sanitizer, so you 1248bf215546Sopenharmony_ci * get good symbols from the leak reports. 1249bf215546Sopenharmony_ci */ 1250bf215546Sopenharmony_ci#if !BUILT_WITH_ASAN || defined(NDEBUG) 1251bf215546Sopenharmony_ci if (dri2_dpy->driver) 1252bf215546Sopenharmony_ci dlclose(dri2_dpy->driver); 1253bf215546Sopenharmony_ci#endif 1254bf215546Sopenharmony_ci 1255bf215546Sopenharmony_ci free(dri2_dpy->driver_name); 1256bf215546Sopenharmony_ci 1257bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 1258bf215546Sopenharmony_ci free(dri2_dpy->device_name); 1259bf215546Sopenharmony_ci#endif 1260bf215546Sopenharmony_ci 1261bf215546Sopenharmony_ci switch (disp->Platform) { 1262bf215546Sopenharmony_ci case _EGL_PLATFORM_X11: 1263bf215546Sopenharmony_ci dri2_teardown_x11(dri2_dpy); 1264bf215546Sopenharmony_ci break; 1265bf215546Sopenharmony_ci case _EGL_PLATFORM_DRM: 1266bf215546Sopenharmony_ci dri2_teardown_drm(dri2_dpy); 1267bf215546Sopenharmony_ci break; 1268bf215546Sopenharmony_ci case _EGL_PLATFORM_WAYLAND: 1269bf215546Sopenharmony_ci dri2_teardown_wayland(dri2_dpy); 1270bf215546Sopenharmony_ci break; 1271bf215546Sopenharmony_ci default: 1272bf215546Sopenharmony_ci /* TODO: add teardown for other platforms */ 1273bf215546Sopenharmony_ci break; 1274bf215546Sopenharmony_ci } 1275bf215546Sopenharmony_ci 1276bf215546Sopenharmony_ci /* The drm platform does not create the screen/driver_configs but reuses 1277bf215546Sopenharmony_ci * the ones from the gbm device. As such the gbm itself is responsible 1278bf215546Sopenharmony_ci * for the cleanup. 1279bf215546Sopenharmony_ci */ 1280bf215546Sopenharmony_ci if (disp->Platform != _EGL_PLATFORM_DRM && dri2_dpy->driver_configs) { 1281bf215546Sopenharmony_ci for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) 1282bf215546Sopenharmony_ci free((__DRIconfig *) dri2_dpy->driver_configs[i]); 1283bf215546Sopenharmony_ci free(dri2_dpy->driver_configs); 1284bf215546Sopenharmony_ci } 1285bf215546Sopenharmony_ci free(dri2_dpy); 1286bf215546Sopenharmony_ci disp->DriverData = NULL; 1287bf215546Sopenharmony_ci} 1288bf215546Sopenharmony_ci 1289bf215546Sopenharmony_ci__DRIbuffer * 1290bf215546Sopenharmony_cidri2_egl_surface_alloc_local_buffer(struct dri2_egl_surface *dri2_surf, 1291bf215546Sopenharmony_ci unsigned int att, unsigned int format) 1292bf215546Sopenharmony_ci{ 1293bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = 1294bf215546Sopenharmony_ci dri2_egl_display(dri2_surf->base.Resource.Display); 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_ci if (att >= ARRAY_SIZE(dri2_surf->local_buffers)) 1297bf215546Sopenharmony_ci return NULL; 1298bf215546Sopenharmony_ci 1299bf215546Sopenharmony_ci if (!dri2_surf->local_buffers[att]) { 1300bf215546Sopenharmony_ci dri2_surf->local_buffers[att] = 1301bf215546Sopenharmony_ci dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen, att, format, 1302bf215546Sopenharmony_ci dri2_surf->base.Width, dri2_surf->base.Height); 1303bf215546Sopenharmony_ci } 1304bf215546Sopenharmony_ci 1305bf215546Sopenharmony_ci return dri2_surf->local_buffers[att]; 1306bf215546Sopenharmony_ci} 1307bf215546Sopenharmony_ci 1308bf215546Sopenharmony_civoid 1309bf215546Sopenharmony_cidri2_egl_surface_free_local_buffers(struct dri2_egl_surface *dri2_surf) 1310bf215546Sopenharmony_ci{ 1311bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = 1312bf215546Sopenharmony_ci dri2_egl_display(dri2_surf->base.Resource.Display); 1313bf215546Sopenharmony_ci 1314bf215546Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(dri2_surf->local_buffers); i++) { 1315bf215546Sopenharmony_ci if (dri2_surf->local_buffers[i]) { 1316bf215546Sopenharmony_ci dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, 1317bf215546Sopenharmony_ci dri2_surf->local_buffers[i]); 1318bf215546Sopenharmony_ci dri2_surf->local_buffers[i] = NULL; 1319bf215546Sopenharmony_ci } 1320bf215546Sopenharmony_ci } 1321bf215546Sopenharmony_ci} 1322bf215546Sopenharmony_ci 1323bf215546Sopenharmony_ci/** 1324bf215546Sopenharmony_ci * Called via eglTerminate(), drv->Terminate(). 1325bf215546Sopenharmony_ci * 1326bf215546Sopenharmony_ci * This must be guaranteed to be called exactly once, even if eglTerminate is 1327bf215546Sopenharmony_ci * called many times (without a eglInitialize in between). 1328bf215546Sopenharmony_ci */ 1329bf215546Sopenharmony_cistatic EGLBoolean 1330bf215546Sopenharmony_cidri2_terminate(_EGLDisplay *disp) 1331bf215546Sopenharmony_ci{ 1332bf215546Sopenharmony_ci /* Release all non-current Context/Surfaces. */ 1333bf215546Sopenharmony_ci _eglReleaseDisplayResources(disp); 1334bf215546Sopenharmony_ci 1335bf215546Sopenharmony_ci dri2_display_release(disp); 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci return EGL_TRUE; 1338bf215546Sopenharmony_ci} 1339bf215546Sopenharmony_ci 1340bf215546Sopenharmony_ci/** 1341bf215546Sopenharmony_ci * Set the error code after a call to 1342bf215546Sopenharmony_ci * dri2_egl_display::dri2::createContextAttribs. 1343bf215546Sopenharmony_ci */ 1344bf215546Sopenharmony_cistatic void 1345bf215546Sopenharmony_cidri2_create_context_attribs_error(int dri_error) 1346bf215546Sopenharmony_ci{ 1347bf215546Sopenharmony_ci EGLint egl_error; 1348bf215546Sopenharmony_ci 1349bf215546Sopenharmony_ci switch (dri_error) { 1350bf215546Sopenharmony_ci case __DRI_CTX_ERROR_SUCCESS: 1351bf215546Sopenharmony_ci return; 1352bf215546Sopenharmony_ci 1353bf215546Sopenharmony_ci case __DRI_CTX_ERROR_NO_MEMORY: 1354bf215546Sopenharmony_ci egl_error = EGL_BAD_ALLOC; 1355bf215546Sopenharmony_ci break; 1356bf215546Sopenharmony_ci 1357bf215546Sopenharmony_ci /* From the EGL_KHR_create_context spec, section "Errors": 1358bf215546Sopenharmony_ci * 1359bf215546Sopenharmony_ci * * If <config> does not support a client API context compatible 1360bf215546Sopenharmony_ci * with the requested API major and minor version, [...] context flags, 1361bf215546Sopenharmony_ci * and context reset notification behavior (for client API types where 1362bf215546Sopenharmony_ci * these attributes are supported), then an EGL_BAD_MATCH error is 1363bf215546Sopenharmony_ci * generated. 1364bf215546Sopenharmony_ci * 1365bf215546Sopenharmony_ci * * If an OpenGL ES context is requested and the values for 1366bf215546Sopenharmony_ci * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and 1367bf215546Sopenharmony_ci * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that 1368bf215546Sopenharmony_ci * is not defined, than an EGL_BAD_MATCH error is generated. 1369bf215546Sopenharmony_ci * 1370bf215546Sopenharmony_ci * * If an OpenGL context is requested, the requested version is 1371bf215546Sopenharmony_ci * greater than 3.2, and the value for attribute 1372bf215546Sopenharmony_ci * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has any 1373bf215546Sopenharmony_ci * bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR and 1374bf215546Sopenharmony_ci * EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has more than 1375bf215546Sopenharmony_ci * one of these bits set; or if the implementation does not support 1376bf215546Sopenharmony_ci * the requested profile, then an EGL_BAD_MATCH error is generated. 1377bf215546Sopenharmony_ci */ 1378bf215546Sopenharmony_ci case __DRI_CTX_ERROR_BAD_API: 1379bf215546Sopenharmony_ci case __DRI_CTX_ERROR_BAD_VERSION: 1380bf215546Sopenharmony_ci case __DRI_CTX_ERROR_BAD_FLAG: 1381bf215546Sopenharmony_ci egl_error = EGL_BAD_MATCH; 1382bf215546Sopenharmony_ci break; 1383bf215546Sopenharmony_ci 1384bf215546Sopenharmony_ci /* From the EGL_KHR_create_context spec, section "Errors": 1385bf215546Sopenharmony_ci * 1386bf215546Sopenharmony_ci * * If an attribute name or attribute value in <attrib_list> is not 1387bf215546Sopenharmony_ci * recognized (including unrecognized bits in bitmask attributes), 1388bf215546Sopenharmony_ci * then an EGL_BAD_ATTRIBUTE error is generated." 1389bf215546Sopenharmony_ci */ 1390bf215546Sopenharmony_ci case __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE: 1391bf215546Sopenharmony_ci case __DRI_CTX_ERROR_UNKNOWN_FLAG: 1392bf215546Sopenharmony_ci egl_error = EGL_BAD_ATTRIBUTE; 1393bf215546Sopenharmony_ci break; 1394bf215546Sopenharmony_ci 1395bf215546Sopenharmony_ci default: 1396bf215546Sopenharmony_ci assert(!"unknown dri_error code"); 1397bf215546Sopenharmony_ci egl_error = EGL_BAD_MATCH; 1398bf215546Sopenharmony_ci break; 1399bf215546Sopenharmony_ci } 1400bf215546Sopenharmony_ci 1401bf215546Sopenharmony_ci _eglError(egl_error, "dri2_create_context"); 1402bf215546Sopenharmony_ci} 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_cistatic bool 1405bf215546Sopenharmony_cidri2_fill_context_attribs(struct dri2_egl_context *dri2_ctx, 1406bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy, 1407bf215546Sopenharmony_ci uint32_t *ctx_attribs, 1408bf215546Sopenharmony_ci unsigned *num_attribs) 1409bf215546Sopenharmony_ci{ 1410bf215546Sopenharmony_ci int pos = 0; 1411bf215546Sopenharmony_ci 1412bf215546Sopenharmony_ci assert(*num_attribs >= NUM_ATTRIBS); 1413bf215546Sopenharmony_ci 1414bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; 1415bf215546Sopenharmony_ci ctx_attribs[pos++] = dri2_ctx->base.ClientMajorVersion; 1416bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_ATTRIB_MINOR_VERSION; 1417bf215546Sopenharmony_ci ctx_attribs[pos++] = dri2_ctx->base.ClientMinorVersion; 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci if (dri2_ctx->base.Flags != 0) { 1420bf215546Sopenharmony_ci /* If the implementation doesn't support the __DRI2_ROBUSTNESS 1421bf215546Sopenharmony_ci * extension, don't even try to send it the robust-access flag. 1422bf215546Sopenharmony_ci * It may explode. Instead, generate the required EGL error here. 1423bf215546Sopenharmony_ci */ 1424bf215546Sopenharmony_ci if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0 1425bf215546Sopenharmony_ci && !dri2_dpy->robustness) { 1426bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "eglCreateContext"); 1427bf215546Sopenharmony_ci return false; 1428bf215546Sopenharmony_ci } 1429bf215546Sopenharmony_ci 1430bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_ATTRIB_FLAGS; 1431bf215546Sopenharmony_ci ctx_attribs[pos++] = dri2_ctx->base.Flags; 1432bf215546Sopenharmony_ci } 1433bf215546Sopenharmony_ci 1434bf215546Sopenharmony_ci if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) { 1435bf215546Sopenharmony_ci /* If the implementation doesn't support the __DRI2_ROBUSTNESS 1436bf215546Sopenharmony_ci * extension, don't even try to send it a reset strategy. It may 1437bf215546Sopenharmony_ci * explode. Instead, generate the required EGL error here. 1438bf215546Sopenharmony_ci */ 1439bf215546Sopenharmony_ci if (!dri2_dpy->robustness) { 1440bf215546Sopenharmony_ci _eglError(EGL_BAD_CONFIG, "eglCreateContext"); 1441bf215546Sopenharmony_ci return false; 1442bf215546Sopenharmony_ci } 1443bf215546Sopenharmony_ci 1444bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_ATTRIB_RESET_STRATEGY; 1445bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_RESET_LOSE_CONTEXT; 1446bf215546Sopenharmony_ci } 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_ci if (dri2_ctx->base.ContextPriority != EGL_CONTEXT_PRIORITY_MEDIUM_IMG) { 1449bf215546Sopenharmony_ci unsigned val; 1450bf215546Sopenharmony_ci 1451bf215546Sopenharmony_ci switch (dri2_ctx->base.ContextPriority) { 1452bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_HIGH_IMG: 1453bf215546Sopenharmony_ci val = __DRI_CTX_PRIORITY_HIGH; 1454bf215546Sopenharmony_ci break; 1455bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: 1456bf215546Sopenharmony_ci val = __DRI_CTX_PRIORITY_MEDIUM; 1457bf215546Sopenharmony_ci break; 1458bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_LOW_IMG: 1459bf215546Sopenharmony_ci val = __DRI_CTX_PRIORITY_LOW; 1460bf215546Sopenharmony_ci break; 1461bf215546Sopenharmony_ci default: 1462bf215546Sopenharmony_ci _eglError(EGL_BAD_CONFIG, "eglCreateContext"); 1463bf215546Sopenharmony_ci return false; 1464bf215546Sopenharmony_ci } 1465bf215546Sopenharmony_ci 1466bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_ATTRIB_PRIORITY; 1467bf215546Sopenharmony_ci ctx_attribs[pos++] = val; 1468bf215546Sopenharmony_ci } 1469bf215546Sopenharmony_ci 1470bf215546Sopenharmony_ci if (dri2_ctx->base.ReleaseBehavior == EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR) { 1471bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR; 1472bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_RELEASE_BEHAVIOR_NONE; 1473bf215546Sopenharmony_ci } 1474bf215546Sopenharmony_ci 1475bf215546Sopenharmony_ci if (dri2_ctx->base.NoError) { 1476bf215546Sopenharmony_ci ctx_attribs[pos++] = __DRI_CTX_ATTRIB_NO_ERROR; 1477bf215546Sopenharmony_ci ctx_attribs[pos++] = true; 1478bf215546Sopenharmony_ci } 1479bf215546Sopenharmony_ci 1480bf215546Sopenharmony_ci *num_attribs = pos; 1481bf215546Sopenharmony_ci 1482bf215546Sopenharmony_ci return true; 1483bf215546Sopenharmony_ci} 1484bf215546Sopenharmony_ci 1485bf215546Sopenharmony_ci/** 1486bf215546Sopenharmony_ci * Called via eglCreateContext(), drv->CreateContext(). 1487bf215546Sopenharmony_ci */ 1488bf215546Sopenharmony_cistatic _EGLContext * 1489bf215546Sopenharmony_cidri2_create_context(_EGLDisplay *disp, _EGLConfig *conf, 1490bf215546Sopenharmony_ci _EGLContext *share_list, const EGLint *attrib_list) 1491bf215546Sopenharmony_ci{ 1492bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx; 1493bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1494bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list); 1495bf215546Sopenharmony_ci __DRIcontext *shared = 1496bf215546Sopenharmony_ci dri2_ctx_shared ? dri2_ctx_shared->dri_context : NULL; 1497bf215546Sopenharmony_ci struct dri2_egl_config *dri2_config = dri2_egl_config(conf); 1498bf215546Sopenharmony_ci const __DRIconfig *dri_config; 1499bf215546Sopenharmony_ci int api; 1500bf215546Sopenharmony_ci unsigned error; 1501bf215546Sopenharmony_ci unsigned num_attribs = NUM_ATTRIBS; 1502bf215546Sopenharmony_ci uint32_t ctx_attribs[NUM_ATTRIBS]; 1503bf215546Sopenharmony_ci 1504bf215546Sopenharmony_ci dri2_ctx = malloc(sizeof *dri2_ctx); 1505bf215546Sopenharmony_ci if (!dri2_ctx) { 1506bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "eglCreateContext"); 1507bf215546Sopenharmony_ci return NULL; 1508bf215546Sopenharmony_ci } 1509bf215546Sopenharmony_ci 1510bf215546Sopenharmony_ci if (!_eglInitContext(&dri2_ctx->base, disp, conf, attrib_list)) 1511bf215546Sopenharmony_ci goto cleanup; 1512bf215546Sopenharmony_ci 1513bf215546Sopenharmony_ci /* The EGL_EXT_create_context_robustness spec says: 1514bf215546Sopenharmony_ci * 1515bf215546Sopenharmony_ci * "Add to the eglCreateContext context creation errors: [...] 1516bf215546Sopenharmony_ci * 1517bf215546Sopenharmony_ci * * If the reset notification behavior of <share_context> and the 1518bf215546Sopenharmony_ci * newly created context are different then an EGL_BAD_MATCH error is 1519bf215546Sopenharmony_ci * generated." 1520bf215546Sopenharmony_ci */ 1521bf215546Sopenharmony_ci if (share_list && share_list->ResetNotificationStrategy != 1522bf215546Sopenharmony_ci dri2_ctx->base.ResetNotificationStrategy) { 1523bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "eglCreateContext"); 1524bf215546Sopenharmony_ci goto cleanup; 1525bf215546Sopenharmony_ci } 1526bf215546Sopenharmony_ci 1527bf215546Sopenharmony_ci /* The EGL_KHR_create_context_no_error spec says: 1528bf215546Sopenharmony_ci * 1529bf215546Sopenharmony_ci * "BAD_MATCH is generated if the value of EGL_CONTEXT_OPENGL_NO_ERROR_KHR 1530bf215546Sopenharmony_ci * used to create <share_context> does not match the value of 1531bf215546Sopenharmony_ci * EGL_CONTEXT_OPENGL_NO_ERROR_KHR for the context being created." 1532bf215546Sopenharmony_ci */ 1533bf215546Sopenharmony_ci if (share_list && share_list->NoError != dri2_ctx->base.NoError) { 1534bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "eglCreateContext"); 1535bf215546Sopenharmony_ci goto cleanup; 1536bf215546Sopenharmony_ci } 1537bf215546Sopenharmony_ci 1538bf215546Sopenharmony_ci switch (dri2_ctx->base.ClientAPI) { 1539bf215546Sopenharmony_ci case EGL_OPENGL_ES_API: 1540bf215546Sopenharmony_ci switch (dri2_ctx->base.ClientMajorVersion) { 1541bf215546Sopenharmony_ci case 1: 1542bf215546Sopenharmony_ci api = __DRI_API_GLES; 1543bf215546Sopenharmony_ci break; 1544bf215546Sopenharmony_ci case 2: 1545bf215546Sopenharmony_ci api = __DRI_API_GLES2; 1546bf215546Sopenharmony_ci break; 1547bf215546Sopenharmony_ci case 3: 1548bf215546Sopenharmony_ci api = __DRI_API_GLES3; 1549bf215546Sopenharmony_ci break; 1550bf215546Sopenharmony_ci default: 1551bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); 1552bf215546Sopenharmony_ci free(dri2_ctx); 1553bf215546Sopenharmony_ci return NULL; 1554bf215546Sopenharmony_ci } 1555bf215546Sopenharmony_ci break; 1556bf215546Sopenharmony_ci case EGL_OPENGL_API: 1557bf215546Sopenharmony_ci if ((dri2_ctx->base.ClientMajorVersion >= 4 1558bf215546Sopenharmony_ci || (dri2_ctx->base.ClientMajorVersion == 3 1559bf215546Sopenharmony_ci && dri2_ctx->base.ClientMinorVersion >= 2)) 1560bf215546Sopenharmony_ci && dri2_ctx->base.Profile == EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) 1561bf215546Sopenharmony_ci api = __DRI_API_OPENGL_CORE; 1562bf215546Sopenharmony_ci else if (dri2_ctx->base.ClientMajorVersion == 3 && 1563bf215546Sopenharmony_ci dri2_ctx->base.ClientMinorVersion == 1) 1564bf215546Sopenharmony_ci api = __DRI_API_OPENGL_CORE; 1565bf215546Sopenharmony_ci else 1566bf215546Sopenharmony_ci api = __DRI_API_OPENGL; 1567bf215546Sopenharmony_ci break; 1568bf215546Sopenharmony_ci default: 1569bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); 1570bf215546Sopenharmony_ci free(dri2_ctx); 1571bf215546Sopenharmony_ci return NULL; 1572bf215546Sopenharmony_ci } 1573bf215546Sopenharmony_ci 1574bf215546Sopenharmony_ci if (conf != NULL) { 1575bf215546Sopenharmony_ci /* The config chosen here isn't necessarily 1576bf215546Sopenharmony_ci * used for surfaces later. 1577bf215546Sopenharmony_ci * A pixmap surface will use the single config. 1578bf215546Sopenharmony_ci * This opportunity depends on disabling the 1579bf215546Sopenharmony_ci * doubleBufferMode check in 1580bf215546Sopenharmony_ci * src/mesa/main/context.c:check_compatible() 1581bf215546Sopenharmony_ci */ 1582bf215546Sopenharmony_ci if (dri2_config->dri_config[1][0]) 1583bf215546Sopenharmony_ci dri_config = dri2_config->dri_config[1][0]; 1584bf215546Sopenharmony_ci else 1585bf215546Sopenharmony_ci dri_config = dri2_config->dri_config[0][0]; 1586bf215546Sopenharmony_ci } 1587bf215546Sopenharmony_ci else 1588bf215546Sopenharmony_ci dri_config = NULL; 1589bf215546Sopenharmony_ci 1590bf215546Sopenharmony_ci if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs, 1591bf215546Sopenharmony_ci &num_attribs)) 1592bf215546Sopenharmony_ci goto cleanup; 1593bf215546Sopenharmony_ci 1594bf215546Sopenharmony_ci if (dri2_dpy->image_driver) { 1595bf215546Sopenharmony_ci dri2_ctx->dri_context = 1596bf215546Sopenharmony_ci dri2_dpy->image_driver->createContextAttribs(dri2_dpy->dri_screen, 1597bf215546Sopenharmony_ci api, 1598bf215546Sopenharmony_ci dri_config, 1599bf215546Sopenharmony_ci shared, 1600bf215546Sopenharmony_ci num_attribs / 2, 1601bf215546Sopenharmony_ci ctx_attribs, 1602bf215546Sopenharmony_ci & error, 1603bf215546Sopenharmony_ci dri2_ctx); 1604bf215546Sopenharmony_ci dri2_create_context_attribs_error(error); 1605bf215546Sopenharmony_ci } else if (dri2_dpy->dri2) { 1606bf215546Sopenharmony_ci if (dri2_dpy->dri2->base.version >= 3) { 1607bf215546Sopenharmony_ci dri2_ctx->dri_context = 1608bf215546Sopenharmony_ci dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen, 1609bf215546Sopenharmony_ci api, 1610bf215546Sopenharmony_ci dri_config, 1611bf215546Sopenharmony_ci shared, 1612bf215546Sopenharmony_ci num_attribs / 2, 1613bf215546Sopenharmony_ci ctx_attribs, 1614bf215546Sopenharmony_ci & error, 1615bf215546Sopenharmony_ci dri2_ctx); 1616bf215546Sopenharmony_ci dri2_create_context_attribs_error(error); 1617bf215546Sopenharmony_ci } else { 1618bf215546Sopenharmony_ci dri2_ctx->dri_context = 1619bf215546Sopenharmony_ci dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen, 1620bf215546Sopenharmony_ci api, 1621bf215546Sopenharmony_ci dri_config, 1622bf215546Sopenharmony_ci shared, 1623bf215546Sopenharmony_ci dri2_ctx); 1624bf215546Sopenharmony_ci } 1625bf215546Sopenharmony_ci } else { 1626bf215546Sopenharmony_ci assert(dri2_dpy->swrast); 1627bf215546Sopenharmony_ci if (dri2_dpy->swrast->base.version >= 3) { 1628bf215546Sopenharmony_ci dri2_ctx->dri_context = 1629bf215546Sopenharmony_ci dri2_dpy->swrast->createContextAttribs(dri2_dpy->dri_screen, 1630bf215546Sopenharmony_ci api, 1631bf215546Sopenharmony_ci dri_config, 1632bf215546Sopenharmony_ci shared, 1633bf215546Sopenharmony_ci num_attribs / 2, 1634bf215546Sopenharmony_ci ctx_attribs, 1635bf215546Sopenharmony_ci & error, 1636bf215546Sopenharmony_ci dri2_ctx); 1637bf215546Sopenharmony_ci dri2_create_context_attribs_error(error); 1638bf215546Sopenharmony_ci } else { 1639bf215546Sopenharmony_ci dri2_ctx->dri_context = 1640bf215546Sopenharmony_ci dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen, 1641bf215546Sopenharmony_ci api, 1642bf215546Sopenharmony_ci dri_config, 1643bf215546Sopenharmony_ci shared, 1644bf215546Sopenharmony_ci dri2_ctx); 1645bf215546Sopenharmony_ci } 1646bf215546Sopenharmony_ci } 1647bf215546Sopenharmony_ci 1648bf215546Sopenharmony_ci if (!dri2_ctx->dri_context) 1649bf215546Sopenharmony_ci goto cleanup; 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_ci return &dri2_ctx->base; 1652bf215546Sopenharmony_ci 1653bf215546Sopenharmony_ci cleanup: 1654bf215546Sopenharmony_ci free(dri2_ctx); 1655bf215546Sopenharmony_ci return NULL; 1656bf215546Sopenharmony_ci} 1657bf215546Sopenharmony_ci 1658bf215546Sopenharmony_ci/** 1659bf215546Sopenharmony_ci * Called via eglDestroyContext(), drv->DestroyContext(). 1660bf215546Sopenharmony_ci */ 1661bf215546Sopenharmony_cistatic EGLBoolean 1662bf215546Sopenharmony_cidri2_destroy_context(_EGLDisplay *disp, _EGLContext *ctx) 1663bf215546Sopenharmony_ci{ 1664bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 1665bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1666bf215546Sopenharmony_ci 1667bf215546Sopenharmony_ci if (_eglPutContext(ctx)) { 1668bf215546Sopenharmony_ci dri2_dpy->core->destroyContext(dri2_ctx->dri_context); 1669bf215546Sopenharmony_ci free(dri2_ctx); 1670bf215546Sopenharmony_ci } 1671bf215546Sopenharmony_ci 1672bf215546Sopenharmony_ci return EGL_TRUE; 1673bf215546Sopenharmony_ci} 1674bf215546Sopenharmony_ci 1675bf215546Sopenharmony_ciEGLBoolean 1676bf215546Sopenharmony_cidri2_init_surface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type, 1677bf215546Sopenharmony_ci _EGLConfig *conf, const EGLint *attrib_list, 1678bf215546Sopenharmony_ci EGLBoolean enable_out_fence, void *native_surface) 1679bf215546Sopenharmony_ci{ 1680bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1681bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1682bf215546Sopenharmony_ci 1683bf215546Sopenharmony_ci dri2_surf->out_fence_fd = -1; 1684bf215546Sopenharmony_ci dri2_surf->enable_out_fence = false; 1685bf215546Sopenharmony_ci if (dri2_dpy->fence && dri2_dpy->fence->base.version >= 2 && 1686bf215546Sopenharmony_ci dri2_dpy->fence->get_capabilities && 1687bf215546Sopenharmony_ci (dri2_dpy->fence->get_capabilities(dri2_dpy->dri_screen) & 1688bf215546Sopenharmony_ci __DRI_FENCE_CAP_NATIVE_FD)) { 1689bf215546Sopenharmony_ci dri2_surf->enable_out_fence = enable_out_fence; 1690bf215546Sopenharmony_ci } 1691bf215546Sopenharmony_ci 1692bf215546Sopenharmony_ci return _eglInitSurface(surf, disp, type, conf, attrib_list, native_surface); 1693bf215546Sopenharmony_ci} 1694bf215546Sopenharmony_ci 1695bf215546Sopenharmony_cistatic void 1696bf215546Sopenharmony_cidri2_surface_set_out_fence_fd( _EGLSurface *surf, int fence_fd) 1697bf215546Sopenharmony_ci{ 1698bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1699bf215546Sopenharmony_ci 1700bf215546Sopenharmony_ci if (dri2_surf->out_fence_fd >= 0) 1701bf215546Sopenharmony_ci close(dri2_surf->out_fence_fd); 1702bf215546Sopenharmony_ci 1703bf215546Sopenharmony_ci dri2_surf->out_fence_fd = fence_fd; 1704bf215546Sopenharmony_ci} 1705bf215546Sopenharmony_ci 1706bf215546Sopenharmony_civoid 1707bf215546Sopenharmony_cidri2_fini_surface(_EGLSurface *surf) 1708bf215546Sopenharmony_ci{ 1709bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1710bf215546Sopenharmony_ci 1711bf215546Sopenharmony_ci dri2_surface_set_out_fence_fd(surf, -1); 1712bf215546Sopenharmony_ci dri2_surf->enable_out_fence = false; 1713bf215546Sopenharmony_ci} 1714bf215546Sopenharmony_ci 1715bf215546Sopenharmony_cistatic EGLBoolean 1716bf215546Sopenharmony_cidri2_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) 1717bf215546Sopenharmony_ci{ 1718bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1719bf215546Sopenharmony_ci 1720bf215546Sopenharmony_ci if (!_eglPutSurface(surf)) 1721bf215546Sopenharmony_ci return EGL_TRUE; 1722bf215546Sopenharmony_ci 1723bf215546Sopenharmony_ci return dri2_dpy->vtbl->destroy_surface(disp, surf); 1724bf215546Sopenharmony_ci} 1725bf215546Sopenharmony_ci 1726bf215546Sopenharmony_cistatic void 1727bf215546Sopenharmony_cidri2_surf_update_fence_fd(_EGLContext *ctx, 1728bf215546Sopenharmony_ci _EGLDisplay *disp, _EGLSurface *surf) 1729bf215546Sopenharmony_ci{ 1730bf215546Sopenharmony_ci __DRIcontext *dri_ctx = dri2_egl_context(ctx)->dri_context; 1731bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1732bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1733bf215546Sopenharmony_ci int fence_fd = -1; 1734bf215546Sopenharmony_ci void *fence; 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci if (!dri2_surf->enable_out_fence) 1737bf215546Sopenharmony_ci return; 1738bf215546Sopenharmony_ci 1739bf215546Sopenharmony_ci fence = dri2_dpy->fence->create_fence_fd(dri_ctx, -1); 1740bf215546Sopenharmony_ci if (fence) { 1741bf215546Sopenharmony_ci fence_fd = dri2_dpy->fence->get_fence_fd(dri2_dpy->dri_screen, 1742bf215546Sopenharmony_ci fence); 1743bf215546Sopenharmony_ci dri2_dpy->fence->destroy_fence(dri2_dpy->dri_screen, fence); 1744bf215546Sopenharmony_ci } 1745bf215546Sopenharmony_ci dri2_surface_set_out_fence_fd(surf, fence_fd); 1746bf215546Sopenharmony_ci} 1747bf215546Sopenharmony_ci 1748bf215546Sopenharmony_ciEGLBoolean 1749bf215546Sopenharmony_cidri2_create_drawable(struct dri2_egl_display *dri2_dpy, 1750bf215546Sopenharmony_ci const __DRIconfig *config, 1751bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf, 1752bf215546Sopenharmony_ci void *loaderPrivate) 1753bf215546Sopenharmony_ci{ 1754bf215546Sopenharmony_ci if (dri2_dpy->kopper) { 1755bf215546Sopenharmony_ci dri2_surf->dri_drawable = 1756bf215546Sopenharmony_ci dri2_dpy->kopper->createNewDrawable(dri2_dpy->dri_screen, config, loaderPrivate, 1757bf215546Sopenharmony_ci dri2_surf->base.Type == EGL_PBUFFER_BIT || 1758bf215546Sopenharmony_ci dri2_surf->base.Type == EGL_PIXMAP_BIT); 1759bf215546Sopenharmony_ci } else { 1760bf215546Sopenharmony_ci __DRIcreateNewDrawableFunc createNewDrawable; 1761bf215546Sopenharmony_ci if (dri2_dpy->image_driver) 1762bf215546Sopenharmony_ci createNewDrawable = dri2_dpy->image_driver->createNewDrawable; 1763bf215546Sopenharmony_ci else if (dri2_dpy->dri2) 1764bf215546Sopenharmony_ci createNewDrawable = dri2_dpy->dri2->createNewDrawable; 1765bf215546Sopenharmony_ci else if (dri2_dpy->swrast) 1766bf215546Sopenharmony_ci createNewDrawable = dri2_dpy->swrast->createNewDrawable; 1767bf215546Sopenharmony_ci else 1768bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, "no createNewDrawable"); 1769bf215546Sopenharmony_ci 1770bf215546Sopenharmony_ci dri2_surf->dri_drawable = createNewDrawable(dri2_dpy->dri_screen, 1771bf215546Sopenharmony_ci config, loaderPrivate); 1772bf215546Sopenharmony_ci } 1773bf215546Sopenharmony_ci if (dri2_surf->dri_drawable == NULL) 1774bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, "createNewDrawable"); 1775bf215546Sopenharmony_ci 1776bf215546Sopenharmony_ci return EGL_TRUE; 1777bf215546Sopenharmony_ci} 1778bf215546Sopenharmony_ci 1779bf215546Sopenharmony_ci/** 1780bf215546Sopenharmony_ci * Called via eglMakeCurrent(), drv->MakeCurrent(). 1781bf215546Sopenharmony_ci */ 1782bf215546Sopenharmony_cistatic EGLBoolean 1783bf215546Sopenharmony_cidri2_make_current(_EGLDisplay *disp, _EGLSurface *dsurf, 1784bf215546Sopenharmony_ci _EGLSurface *rsurf, _EGLContext *ctx) 1785bf215546Sopenharmony_ci{ 1786bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1787bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 1788bf215546Sopenharmony_ci _EGLDisplay *old_disp = NULL; 1789bf215546Sopenharmony_ci struct dri2_egl_display *old_dri2_dpy = NULL; 1790bf215546Sopenharmony_ci _EGLContext *old_ctx; 1791bf215546Sopenharmony_ci _EGLSurface *old_dsurf, *old_rsurf; 1792bf215546Sopenharmony_ci _EGLSurface *tmp_dsurf, *tmp_rsurf; 1793bf215546Sopenharmony_ci __DRIdrawable *ddraw, *rdraw; 1794bf215546Sopenharmony_ci __DRIcontext *cctx; 1795bf215546Sopenharmony_ci EGLint egl_error = EGL_SUCCESS; 1796bf215546Sopenharmony_ci 1797bf215546Sopenharmony_ci if (!dri2_dpy) 1798bf215546Sopenharmony_ci return _eglError(EGL_NOT_INITIALIZED, "eglMakeCurrent"); 1799bf215546Sopenharmony_ci 1800bf215546Sopenharmony_ci /* make new bindings, set the EGL error otherwise */ 1801bf215546Sopenharmony_ci if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) 1802bf215546Sopenharmony_ci return EGL_FALSE; 1803bf215546Sopenharmony_ci 1804bf215546Sopenharmony_ci if (old_ctx == ctx && old_dsurf == dsurf && old_rsurf == rsurf) { 1805bf215546Sopenharmony_ci _eglPutSurface(old_dsurf); 1806bf215546Sopenharmony_ci _eglPutSurface(old_rsurf); 1807bf215546Sopenharmony_ci _eglPutContext(old_ctx); 1808bf215546Sopenharmony_ci return EGL_TRUE; 1809bf215546Sopenharmony_ci } 1810bf215546Sopenharmony_ci 1811bf215546Sopenharmony_ci if (old_ctx) { 1812bf215546Sopenharmony_ci __DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context; 1813bf215546Sopenharmony_ci old_disp = old_ctx->Resource.Display; 1814bf215546Sopenharmony_ci old_dri2_dpy = dri2_egl_display(old_disp); 1815bf215546Sopenharmony_ci 1816bf215546Sopenharmony_ci /* Disable shared buffer mode */ 1817bf215546Sopenharmony_ci if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) && 1818bf215546Sopenharmony_ci old_dri2_dpy->vtbl->set_shared_buffer_mode) { 1819bf215546Sopenharmony_ci old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, false); 1820bf215546Sopenharmony_ci } 1821bf215546Sopenharmony_ci 1822bf215546Sopenharmony_ci dri2_dpy->core->unbindContext(old_cctx); 1823bf215546Sopenharmony_ci 1824bf215546Sopenharmony_ci if (old_dsurf) 1825bf215546Sopenharmony_ci dri2_surf_update_fence_fd(old_ctx, disp, old_dsurf); 1826bf215546Sopenharmony_ci } 1827bf215546Sopenharmony_ci 1828bf215546Sopenharmony_ci ddraw = (dsurf) ? dri2_dpy->vtbl->get_dri_drawable(dsurf) : NULL; 1829bf215546Sopenharmony_ci rdraw = (rsurf) ? dri2_dpy->vtbl->get_dri_drawable(rsurf) : NULL; 1830bf215546Sopenharmony_ci cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; 1831bf215546Sopenharmony_ci 1832bf215546Sopenharmony_ci if (cctx || ddraw || rdraw) { 1833bf215546Sopenharmony_ci if (!dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { 1834bf215546Sopenharmony_ci _EGLContext *tmp_ctx; 1835bf215546Sopenharmony_ci 1836bf215546Sopenharmony_ci /* dri2_dpy->core->bindContext failed. We cannot tell for sure why, but 1837bf215546Sopenharmony_ci * setting the error to EGL_BAD_MATCH is surely better than leaving it 1838bf215546Sopenharmony_ci * as EGL_SUCCESS. 1839bf215546Sopenharmony_ci */ 1840bf215546Sopenharmony_ci egl_error = EGL_BAD_MATCH; 1841bf215546Sopenharmony_ci 1842bf215546Sopenharmony_ci /* undo the previous _eglBindContext */ 1843bf215546Sopenharmony_ci _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &tmp_dsurf, &tmp_rsurf); 1844bf215546Sopenharmony_ci assert(&dri2_ctx->base == ctx && 1845bf215546Sopenharmony_ci tmp_dsurf == dsurf && 1846bf215546Sopenharmony_ci tmp_rsurf == rsurf); 1847bf215546Sopenharmony_ci 1848bf215546Sopenharmony_ci _eglPutSurface(dsurf); 1849bf215546Sopenharmony_ci _eglPutSurface(rsurf); 1850bf215546Sopenharmony_ci _eglPutContext(ctx); 1851bf215546Sopenharmony_ci 1852bf215546Sopenharmony_ci _eglPutSurface(old_dsurf); 1853bf215546Sopenharmony_ci _eglPutSurface(old_rsurf); 1854bf215546Sopenharmony_ci _eglPutContext(old_ctx); 1855bf215546Sopenharmony_ci 1856bf215546Sopenharmony_ci ddraw = (old_dsurf) ? dri2_dpy->vtbl->get_dri_drawable(old_dsurf) : NULL; 1857bf215546Sopenharmony_ci rdraw = (old_rsurf) ? dri2_dpy->vtbl->get_dri_drawable(old_rsurf) : NULL; 1858bf215546Sopenharmony_ci cctx = (old_ctx) ? dri2_egl_context(old_ctx)->dri_context : NULL; 1859bf215546Sopenharmony_ci 1860bf215546Sopenharmony_ci /* undo the previous dri2_dpy->core->unbindContext */ 1861bf215546Sopenharmony_ci if (dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { 1862bf215546Sopenharmony_ci if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) && 1863bf215546Sopenharmony_ci old_dri2_dpy->vtbl->set_shared_buffer_mode) { 1864bf215546Sopenharmony_ci old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, true); 1865bf215546Sopenharmony_ci } 1866bf215546Sopenharmony_ci 1867bf215546Sopenharmony_ci return _eglError(egl_error, "eglMakeCurrent"); 1868bf215546Sopenharmony_ci } 1869bf215546Sopenharmony_ci 1870bf215546Sopenharmony_ci /* We cannot restore the same state as it was before calling 1871bf215546Sopenharmony_ci * eglMakeCurrent() and the spec isn't clear about what to do. We 1872bf215546Sopenharmony_ci * can prevent EGL from calling into the DRI driver with no DRI 1873bf215546Sopenharmony_ci * context bound. 1874bf215546Sopenharmony_ci */ 1875bf215546Sopenharmony_ci dsurf = rsurf = NULL; 1876bf215546Sopenharmony_ci ctx = NULL; 1877bf215546Sopenharmony_ci 1878bf215546Sopenharmony_ci _eglBindContext(ctx, dsurf, rsurf, &tmp_ctx, &tmp_dsurf, &tmp_rsurf); 1879bf215546Sopenharmony_ci assert(tmp_ctx == old_ctx && tmp_dsurf == old_dsurf && 1880bf215546Sopenharmony_ci tmp_rsurf == old_rsurf); 1881bf215546Sopenharmony_ci 1882bf215546Sopenharmony_ci _eglLog(_EGL_WARNING, "DRI2: failed to rebind the previous context"); 1883bf215546Sopenharmony_ci } else { 1884bf215546Sopenharmony_ci /* dri2_dpy->core->bindContext succeeded, so take a reference on the 1885bf215546Sopenharmony_ci * dri2_dpy. This prevents dri2_dpy from being reinitialized when a 1886bf215546Sopenharmony_ci * EGLDisplay is terminated and then initialized again while a 1887bf215546Sopenharmony_ci * context is still bound. See dri2_intitialize() for a more in depth 1888bf215546Sopenharmony_ci * explanation. */ 1889bf215546Sopenharmony_ci dri2_dpy->ref_count++; 1890bf215546Sopenharmony_ci } 1891bf215546Sopenharmony_ci } 1892bf215546Sopenharmony_ci 1893bf215546Sopenharmony_ci dri2_destroy_surface(disp, old_dsurf); 1894bf215546Sopenharmony_ci dri2_destroy_surface(disp, old_rsurf); 1895bf215546Sopenharmony_ci 1896bf215546Sopenharmony_ci if (old_ctx) { 1897bf215546Sopenharmony_ci dri2_destroy_context(disp, old_ctx); 1898bf215546Sopenharmony_ci dri2_display_release(old_disp); 1899bf215546Sopenharmony_ci } 1900bf215546Sopenharmony_ci 1901bf215546Sopenharmony_ci if (egl_error != EGL_SUCCESS) 1902bf215546Sopenharmony_ci return _eglError(egl_error, "eglMakeCurrent"); 1903bf215546Sopenharmony_ci 1904bf215546Sopenharmony_ci if (dsurf && _eglSurfaceHasMutableRenderBuffer(dsurf) && 1905bf215546Sopenharmony_ci dri2_dpy->vtbl->set_shared_buffer_mode) { 1906bf215546Sopenharmony_ci /* Always update the shared buffer mode. This is obviously needed when 1907bf215546Sopenharmony_ci * the active EGL_RENDER_BUFFER is EGL_SINGLE_BUFFER. When 1908bf215546Sopenharmony_ci * EGL_RENDER_BUFFER is EGL_BACK_BUFFER, the update protects us in the 1909bf215546Sopenharmony_ci * case where external non-EGL API may have changed window's shared 1910bf215546Sopenharmony_ci * buffer mode since we last saw it. 1911bf215546Sopenharmony_ci */ 1912bf215546Sopenharmony_ci bool mode = (dsurf->ActiveRenderBuffer == EGL_SINGLE_BUFFER); 1913bf215546Sopenharmony_ci dri2_dpy->vtbl->set_shared_buffer_mode(disp, dsurf, mode); 1914bf215546Sopenharmony_ci } 1915bf215546Sopenharmony_ci 1916bf215546Sopenharmony_ci return EGL_TRUE; 1917bf215546Sopenharmony_ci} 1918bf215546Sopenharmony_ci 1919bf215546Sopenharmony_ci__DRIdrawable * 1920bf215546Sopenharmony_cidri2_surface_get_dri_drawable(_EGLSurface *surf) 1921bf215546Sopenharmony_ci{ 1922bf215546Sopenharmony_ci struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 1923bf215546Sopenharmony_ci 1924bf215546Sopenharmony_ci return dri2_surf->dri_drawable; 1925bf215546Sopenharmony_ci} 1926bf215546Sopenharmony_ci 1927bf215546Sopenharmony_ci/* 1928bf215546Sopenharmony_ci * Called from eglGetProcAddress() via drv->GetProcAddress(). 1929bf215546Sopenharmony_ci */ 1930bf215546Sopenharmony_cistatic _EGLProc 1931bf215546Sopenharmony_cidri2_get_proc_address(const char *procname) 1932bf215546Sopenharmony_ci{ 1933bf215546Sopenharmony_ci DISPLAY_LOGI("procname = %{public}s", procname); 1934bf215546Sopenharmony_ci return _glapi_get_proc_address(procname); 1935bf215546Sopenharmony_ci} 1936bf215546Sopenharmony_ci 1937bf215546Sopenharmony_cistatic _EGLSurface* 1938bf215546Sopenharmony_cidri2_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, 1939bf215546Sopenharmony_ci void *native_window, const EGLint *attrib_list) 1940bf215546Sopenharmony_ci{ 1941bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1942bf215546Sopenharmony_ci return dri2_dpy->vtbl->create_window_surface(disp, conf, native_window, 1943bf215546Sopenharmony_ci attrib_list); 1944bf215546Sopenharmony_ci} 1945bf215546Sopenharmony_ci 1946bf215546Sopenharmony_cistatic _EGLSurface* 1947bf215546Sopenharmony_cidri2_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf, 1948bf215546Sopenharmony_ci void *native_pixmap, const EGLint *attrib_list) 1949bf215546Sopenharmony_ci{ 1950bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1951bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->create_pixmap_surface) 1952bf215546Sopenharmony_ci return NULL; 1953bf215546Sopenharmony_ci return dri2_dpy->vtbl->create_pixmap_surface(disp, conf, native_pixmap, 1954bf215546Sopenharmony_ci attrib_list); 1955bf215546Sopenharmony_ci} 1956bf215546Sopenharmony_ci 1957bf215546Sopenharmony_cistatic _EGLSurface* 1958bf215546Sopenharmony_cidri2_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf, 1959bf215546Sopenharmony_ci const EGLint *attrib_list) 1960bf215546Sopenharmony_ci{ 1961bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1962bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->create_pbuffer_surface) 1963bf215546Sopenharmony_ci return NULL; 1964bf215546Sopenharmony_ci return dri2_dpy->vtbl->create_pbuffer_surface(disp, conf, attrib_list); 1965bf215546Sopenharmony_ci} 1966bf215546Sopenharmony_ci 1967bf215546Sopenharmony_cistatic EGLBoolean 1968bf215546Sopenharmony_cidri2_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval) 1969bf215546Sopenharmony_ci{ 1970bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1971bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->swap_interval) 1972bf215546Sopenharmony_ci return EGL_TRUE; 1973bf215546Sopenharmony_ci return dri2_dpy->vtbl->swap_interval(disp, surf, interval); 1974bf215546Sopenharmony_ci} 1975bf215546Sopenharmony_ci 1976bf215546Sopenharmony_ci/** 1977bf215546Sopenharmony_ci * Asks the client API to flush any rendering to the drawable so that we can 1978bf215546Sopenharmony_ci * do our swapbuffers. 1979bf215546Sopenharmony_ci */ 1980bf215546Sopenharmony_civoid 1981bf215546Sopenharmony_cidri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw) 1982bf215546Sopenharmony_ci{ 1983bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1984bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(draw); 1985bf215546Sopenharmony_ci 1986bf215546Sopenharmony_ci if (dri2_dpy->flush) { 1987bf215546Sopenharmony_ci if (dri2_dpy->flush->base.version >= 4) { 1988bf215546Sopenharmony_ci /* We know there's a current context because: 1989bf215546Sopenharmony_ci * 1990bf215546Sopenharmony_ci * "If surface is not bound to the calling thread’s current 1991bf215546Sopenharmony_ci * context, an EGL_BAD_SURFACE error is generated." 1992bf215546Sopenharmony_ci */ 1993bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1994bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 1995bf215546Sopenharmony_ci 1996bf215546Sopenharmony_ci /* From the EGL 1.4 spec (page 52): 1997bf215546Sopenharmony_ci * 1998bf215546Sopenharmony_ci * "The contents of ancillary buffers are always undefined 1999bf215546Sopenharmony_ci * after calling eglSwapBuffers." 2000bf215546Sopenharmony_ci */ 2001bf215546Sopenharmony_ci dri2_dpy->flush->flush_with_flags(dri2_ctx->dri_context, 2002bf215546Sopenharmony_ci dri_drawable, 2003bf215546Sopenharmony_ci __DRI2_FLUSH_DRAWABLE | 2004bf215546Sopenharmony_ci __DRI2_FLUSH_INVALIDATE_ANCILLARY, 2005bf215546Sopenharmony_ci __DRI2_THROTTLE_SWAPBUFFER); 2006bf215546Sopenharmony_ci } else { 2007bf215546Sopenharmony_ci dri2_dpy->flush->flush(dri_drawable); 2008bf215546Sopenharmony_ci } 2009bf215546Sopenharmony_ci } 2010bf215546Sopenharmony_ci} 2011bf215546Sopenharmony_ci 2012bf215546Sopenharmony_cistatic EGLBoolean 2013bf215546Sopenharmony_cidri2_swap_buffers(_EGLDisplay *disp, _EGLSurface *surf) 2014bf215546Sopenharmony_ci{ 2015bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2016bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 2017bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 2018bf215546Sopenharmony_ci EGLBoolean ret; 2019bf215546Sopenharmony_ci 2020bf215546Sopenharmony_ci if (ctx && surf) 2021bf215546Sopenharmony_ci dri2_surf_update_fence_fd(ctx, disp, surf); 2022bf215546Sopenharmony_ci ret = dri2_dpy->vtbl->swap_buffers(disp, surf); 2023bf215546Sopenharmony_ci 2024bf215546Sopenharmony_ci /* SwapBuffers marks the end of the frame; reset the damage region for 2025bf215546Sopenharmony_ci * use again next time. 2026bf215546Sopenharmony_ci */ 2027bf215546Sopenharmony_ci if (ret && dri2_dpy->buffer_damage && 2028bf215546Sopenharmony_ci dri2_dpy->buffer_damage->set_damage_region) 2029bf215546Sopenharmony_ci dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL); 2030bf215546Sopenharmony_ci 2031bf215546Sopenharmony_ci return ret; 2032bf215546Sopenharmony_ci} 2033bf215546Sopenharmony_ci 2034bf215546Sopenharmony_cistatic EGLBoolean 2035bf215546Sopenharmony_cidri2_swap_buffers_with_damage(_EGLDisplay *disp, _EGLSurface *surf, 2036bf215546Sopenharmony_ci const EGLint *rects, EGLint n_rects) 2037bf215546Sopenharmony_ci{ 2038bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2039bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 2040bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 2041bf215546Sopenharmony_ci EGLBoolean ret; 2042bf215546Sopenharmony_ci 2043bf215546Sopenharmony_ci if (ctx && surf) 2044bf215546Sopenharmony_ci dri2_surf_update_fence_fd(ctx, disp, surf); 2045bf215546Sopenharmony_ci if (dri2_dpy->vtbl->swap_buffers_with_damage) 2046bf215546Sopenharmony_ci ret = dri2_dpy->vtbl->swap_buffers_with_damage(disp, surf, 2047bf215546Sopenharmony_ci rects, n_rects); 2048bf215546Sopenharmony_ci else 2049bf215546Sopenharmony_ci ret = dri2_dpy->vtbl->swap_buffers(disp, surf); 2050bf215546Sopenharmony_ci 2051bf215546Sopenharmony_ci /* SwapBuffers marks the end of the frame; reset the damage region for 2052bf215546Sopenharmony_ci * use again next time. 2053bf215546Sopenharmony_ci */ 2054bf215546Sopenharmony_ci if (ret && dri2_dpy->buffer_damage && 2055bf215546Sopenharmony_ci dri2_dpy->buffer_damage->set_damage_region) 2056bf215546Sopenharmony_ci dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL); 2057bf215546Sopenharmony_ci 2058bf215546Sopenharmony_ci return ret; 2059bf215546Sopenharmony_ci} 2060bf215546Sopenharmony_ci 2061bf215546Sopenharmony_cistatic EGLBoolean 2062bf215546Sopenharmony_cidri2_swap_buffers_region(_EGLDisplay *disp, _EGLSurface *surf, 2063bf215546Sopenharmony_ci EGLint numRects, const EGLint *rects) 2064bf215546Sopenharmony_ci{ 2065bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2066bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 2067bf215546Sopenharmony_ci EGLBoolean ret; 2068bf215546Sopenharmony_ci 2069bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->swap_buffers_region) 2070bf215546Sopenharmony_ci return EGL_FALSE; 2071bf215546Sopenharmony_ci ret = dri2_dpy->vtbl->swap_buffers_region(disp, surf, numRects, rects); 2072bf215546Sopenharmony_ci 2073bf215546Sopenharmony_ci /* SwapBuffers marks the end of the frame; reset the damage region for 2074bf215546Sopenharmony_ci * use again next time. 2075bf215546Sopenharmony_ci */ 2076bf215546Sopenharmony_ci if (ret && dri2_dpy->buffer_damage && 2077bf215546Sopenharmony_ci dri2_dpy->buffer_damage->set_damage_region) 2078bf215546Sopenharmony_ci dri2_dpy->buffer_damage->set_damage_region(dri_drawable, 0, NULL); 2079bf215546Sopenharmony_ci 2080bf215546Sopenharmony_ci return ret; 2081bf215546Sopenharmony_ci} 2082bf215546Sopenharmony_ci 2083bf215546Sopenharmony_cistatic EGLBoolean 2084bf215546Sopenharmony_cidri2_set_damage_region(_EGLDisplay *disp, _EGLSurface *surf, 2085bf215546Sopenharmony_ci EGLint *rects, EGLint n_rects) 2086bf215546Sopenharmony_ci{ 2087bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2088bf215546Sopenharmony_ci __DRIdrawable *drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 2089bf215546Sopenharmony_ci 2090bf215546Sopenharmony_ci if (!dri2_dpy->buffer_damage || !dri2_dpy->buffer_damage->set_damage_region) 2091bf215546Sopenharmony_ci return EGL_FALSE; 2092bf215546Sopenharmony_ci 2093bf215546Sopenharmony_ci dri2_dpy->buffer_damage->set_damage_region(drawable, n_rects, rects); 2094bf215546Sopenharmony_ci return EGL_TRUE; 2095bf215546Sopenharmony_ci} 2096bf215546Sopenharmony_ci 2097bf215546Sopenharmony_cistatic EGLBoolean 2098bf215546Sopenharmony_cidri2_post_sub_buffer(_EGLDisplay *disp, _EGLSurface *surf, 2099bf215546Sopenharmony_ci EGLint x, EGLint y, EGLint width, EGLint height) 2100bf215546Sopenharmony_ci{ 2101bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2102bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->post_sub_buffer) 2103bf215546Sopenharmony_ci return EGL_FALSE; 2104bf215546Sopenharmony_ci return dri2_dpy->vtbl->post_sub_buffer(disp, surf, x, y, width, height); 2105bf215546Sopenharmony_ci} 2106bf215546Sopenharmony_ci 2107bf215546Sopenharmony_cistatic EGLBoolean 2108bf215546Sopenharmony_cidri2_copy_buffers(_EGLDisplay *disp, _EGLSurface *surf, void *native_pixmap_target) 2109bf215546Sopenharmony_ci{ 2110bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2111bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->copy_buffers) 2112bf215546Sopenharmony_ci return _eglError(EGL_BAD_NATIVE_PIXMAP, "no support for native pixmaps"); 2113bf215546Sopenharmony_ci return dri2_dpy->vtbl->copy_buffers(disp, surf, native_pixmap_target); 2114bf215546Sopenharmony_ci} 2115bf215546Sopenharmony_ci 2116bf215546Sopenharmony_cistatic EGLint 2117bf215546Sopenharmony_cidri2_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surf) 2118bf215546Sopenharmony_ci{ 2119bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2120bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->query_buffer_age) 2121bf215546Sopenharmony_ci return 0; 2122bf215546Sopenharmony_ci return dri2_dpy->vtbl->query_buffer_age(disp, surf); 2123bf215546Sopenharmony_ci} 2124bf215546Sopenharmony_ci 2125bf215546Sopenharmony_cistatic EGLBoolean 2126bf215546Sopenharmony_cidri2_wait_client(_EGLDisplay *disp, _EGLContext *ctx) 2127bf215546Sopenharmony_ci{ 2128bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2129bf215546Sopenharmony_ci _EGLSurface *surf = ctx->DrawSurface; 2130bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 2131bf215546Sopenharmony_ci 2132bf215546Sopenharmony_ci /* FIXME: If EGL allows frontbuffer rendering for window surfaces, 2133bf215546Sopenharmony_ci * we need to copy fake to real here.*/ 2134bf215546Sopenharmony_ci 2135bf215546Sopenharmony_ci if (dri2_dpy->flush != NULL) 2136bf215546Sopenharmony_ci dri2_dpy->flush->flush(dri_drawable); 2137bf215546Sopenharmony_ci 2138bf215546Sopenharmony_ci return EGL_TRUE; 2139bf215546Sopenharmony_ci} 2140bf215546Sopenharmony_ci 2141bf215546Sopenharmony_cistatic EGLBoolean 2142bf215546Sopenharmony_cidri2_wait_native(EGLint engine) 2143bf215546Sopenharmony_ci{ 2144bf215546Sopenharmony_ci if (engine != EGL_CORE_NATIVE_ENGINE) 2145bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); 2146bf215546Sopenharmony_ci /* glXWaitX(); */ 2147bf215546Sopenharmony_ci 2148bf215546Sopenharmony_ci return EGL_TRUE; 2149bf215546Sopenharmony_ci} 2150bf215546Sopenharmony_ci 2151bf215546Sopenharmony_cistatic EGLBoolean 2152bf215546Sopenharmony_cidri2_bind_tex_image(_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) 2153bf215546Sopenharmony_ci{ 2154bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2155bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx; 2156bf215546Sopenharmony_ci _EGLContext *ctx; 2157bf215546Sopenharmony_ci GLint format, target; 2158bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 2159bf215546Sopenharmony_ci 2160bf215546Sopenharmony_ci ctx = _eglGetCurrentContext(); 2161bf215546Sopenharmony_ci dri2_ctx = dri2_egl_context(ctx); 2162bf215546Sopenharmony_ci 2163bf215546Sopenharmony_ci if (!_eglBindTexImage(disp, surf, buffer)) 2164bf215546Sopenharmony_ci return EGL_FALSE; 2165bf215546Sopenharmony_ci 2166bf215546Sopenharmony_ci switch (surf->TextureFormat) { 2167bf215546Sopenharmony_ci case EGL_TEXTURE_RGB: 2168bf215546Sopenharmony_ci format = __DRI_TEXTURE_FORMAT_RGB; 2169bf215546Sopenharmony_ci break; 2170bf215546Sopenharmony_ci case EGL_TEXTURE_RGBA: 2171bf215546Sopenharmony_ci format = __DRI_TEXTURE_FORMAT_RGBA; 2172bf215546Sopenharmony_ci break; 2173bf215546Sopenharmony_ci default: 2174bf215546Sopenharmony_ci assert(!"Unexpected texture format in dri2_bind_tex_image()"); 2175bf215546Sopenharmony_ci format = __DRI_TEXTURE_FORMAT_RGBA; 2176bf215546Sopenharmony_ci } 2177bf215546Sopenharmony_ci 2178bf215546Sopenharmony_ci switch (surf->TextureTarget) { 2179bf215546Sopenharmony_ci case EGL_TEXTURE_2D: 2180bf215546Sopenharmony_ci target = GL_TEXTURE_2D; 2181bf215546Sopenharmony_ci break; 2182bf215546Sopenharmony_ci default: 2183bf215546Sopenharmony_ci target = GL_TEXTURE_2D; 2184bf215546Sopenharmony_ci assert(!"Unexpected texture target in dri2_bind_tex_image()"); 2185bf215546Sopenharmony_ci } 2186bf215546Sopenharmony_ci 2187bf215546Sopenharmony_ci dri2_dpy->tex_buffer->setTexBuffer2(dri2_ctx->dri_context, 2188bf215546Sopenharmony_ci target, format, 2189bf215546Sopenharmony_ci dri_drawable); 2190bf215546Sopenharmony_ci 2191bf215546Sopenharmony_ci return EGL_TRUE; 2192bf215546Sopenharmony_ci} 2193bf215546Sopenharmony_ci 2194bf215546Sopenharmony_cistatic EGLBoolean 2195bf215546Sopenharmony_cidri2_release_tex_image(_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) 2196bf215546Sopenharmony_ci{ 2197bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2198bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx; 2199bf215546Sopenharmony_ci _EGLContext *ctx; 2200bf215546Sopenharmony_ci GLint target; 2201bf215546Sopenharmony_ci __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf); 2202bf215546Sopenharmony_ci 2203bf215546Sopenharmony_ci ctx = _eglGetCurrentContext(); 2204bf215546Sopenharmony_ci dri2_ctx = dri2_egl_context(ctx); 2205bf215546Sopenharmony_ci 2206bf215546Sopenharmony_ci if (!_eglReleaseTexImage(disp, surf, buffer)) 2207bf215546Sopenharmony_ci return EGL_FALSE; 2208bf215546Sopenharmony_ci 2209bf215546Sopenharmony_ci switch (surf->TextureTarget) { 2210bf215546Sopenharmony_ci case EGL_TEXTURE_2D: 2211bf215546Sopenharmony_ci target = GL_TEXTURE_2D; 2212bf215546Sopenharmony_ci break; 2213bf215546Sopenharmony_ci default: 2214bf215546Sopenharmony_ci assert(!"missing texture target"); 2215bf215546Sopenharmony_ci } 2216bf215546Sopenharmony_ci 2217bf215546Sopenharmony_ci if (dri2_dpy->tex_buffer->base.version >= 3 && 2218bf215546Sopenharmony_ci dri2_dpy->tex_buffer->releaseTexBuffer != NULL) { 2219bf215546Sopenharmony_ci dri2_dpy->tex_buffer->releaseTexBuffer(dri2_ctx->dri_context, 2220bf215546Sopenharmony_ci target, dri_drawable); 2221bf215546Sopenharmony_ci } 2222bf215546Sopenharmony_ci 2223bf215546Sopenharmony_ci return EGL_TRUE; 2224bf215546Sopenharmony_ci} 2225bf215546Sopenharmony_ci 2226bf215546Sopenharmony_cistatic _EGLImage* 2227bf215546Sopenharmony_cidri2_create_image(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target, 2228bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 2229bf215546Sopenharmony_ci{ 2230bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2231bf215546Sopenharmony_ci return dri2_dpy->vtbl->create_image(disp, ctx, target, buffer, 2232bf215546Sopenharmony_ci attr_list); 2233bf215546Sopenharmony_ci} 2234bf215546Sopenharmony_ci 2235bf215546Sopenharmony_ci_EGLImage * 2236bf215546Sopenharmony_cidri2_create_image_from_dri(_EGLDisplay *disp, __DRIimage *dri_image) 2237bf215546Sopenharmony_ci{ 2238bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img; 2239bf215546Sopenharmony_ci 2240bf215546Sopenharmony_ci if (dri_image == NULL) { 2241bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_image"); 2242bf215546Sopenharmony_ci return NULL; 2243bf215546Sopenharmony_ci } 2244bf215546Sopenharmony_ci 2245bf215546Sopenharmony_ci dri2_img = malloc(sizeof *dri2_img); 2246bf215546Sopenharmony_ci if (!dri2_img) { 2247bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_image"); 2248bf215546Sopenharmony_ci return NULL; 2249bf215546Sopenharmony_ci } 2250bf215546Sopenharmony_ci 2251bf215546Sopenharmony_ci _eglInitImage(&dri2_img->base, disp); 2252bf215546Sopenharmony_ci 2253bf215546Sopenharmony_ci dri2_img->dri_image = dri_image; 2254bf215546Sopenharmony_ci 2255bf215546Sopenharmony_ci return &dri2_img->base; 2256bf215546Sopenharmony_ci} 2257bf215546Sopenharmony_ci 2258bf215546Sopenharmony_ci/** 2259bf215546Sopenharmony_ci * Translate a DRI Image extension error code into an EGL error code. 2260bf215546Sopenharmony_ci */ 2261bf215546Sopenharmony_cistatic EGLint 2262bf215546Sopenharmony_ciegl_error_from_dri_image_error(int dri_error) 2263bf215546Sopenharmony_ci{ 2264bf215546Sopenharmony_ci switch (dri_error) { 2265bf215546Sopenharmony_ci case __DRI_IMAGE_ERROR_SUCCESS: 2266bf215546Sopenharmony_ci return EGL_SUCCESS; 2267bf215546Sopenharmony_ci case __DRI_IMAGE_ERROR_BAD_ALLOC: 2268bf215546Sopenharmony_ci return EGL_BAD_ALLOC; 2269bf215546Sopenharmony_ci case __DRI_IMAGE_ERROR_BAD_MATCH: 2270bf215546Sopenharmony_ci return EGL_BAD_MATCH; 2271bf215546Sopenharmony_ci case __DRI_IMAGE_ERROR_BAD_PARAMETER: 2272bf215546Sopenharmony_ci return EGL_BAD_PARAMETER; 2273bf215546Sopenharmony_ci case __DRI_IMAGE_ERROR_BAD_ACCESS: 2274bf215546Sopenharmony_ci return EGL_BAD_ACCESS; 2275bf215546Sopenharmony_ci default: 2276bf215546Sopenharmony_ci assert(!"unknown dri_error code"); 2277bf215546Sopenharmony_ci return EGL_BAD_ALLOC; 2278bf215546Sopenharmony_ci } 2279bf215546Sopenharmony_ci} 2280bf215546Sopenharmony_ci 2281bf215546Sopenharmony_cistatic _EGLImage * 2282bf215546Sopenharmony_cidri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, 2283bf215546Sopenharmony_ci EGLClientBuffer buffer, 2284bf215546Sopenharmony_ci const EGLint *attr_list) 2285bf215546Sopenharmony_ci{ 2286bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2287bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 2288bf215546Sopenharmony_ci GLuint renderbuffer = (GLuint) (uintptr_t) buffer; 2289bf215546Sopenharmony_ci __DRIimage *dri_image; 2290bf215546Sopenharmony_ci 2291bf215546Sopenharmony_ci if (renderbuffer == 0) { 2292bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 2293bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2294bf215546Sopenharmony_ci } 2295bf215546Sopenharmony_ci 2296bf215546Sopenharmony_ci if (!disp->Extensions.KHR_gl_renderbuffer_image) { 2297bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 2298bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2299bf215546Sopenharmony_ci } 2300bf215546Sopenharmony_ci 2301bf215546Sopenharmony_ci if (dri2_dpy->image->base.version >= 17 && 2302bf215546Sopenharmony_ci dri2_dpy->image->createImageFromRenderbuffer2) { 2303bf215546Sopenharmony_ci unsigned error = ~0; 2304bf215546Sopenharmony_ci 2305bf215546Sopenharmony_ci dri_image = dri2_dpy->image->createImageFromRenderbuffer2( 2306bf215546Sopenharmony_ci dri2_ctx->dri_context, renderbuffer, NULL, &error); 2307bf215546Sopenharmony_ci 2308bf215546Sopenharmony_ci assert(!!dri_image == (error == __DRI_IMAGE_ERROR_SUCCESS)); 2309bf215546Sopenharmony_ci 2310bf215546Sopenharmony_ci if (!dri_image) { 2311bf215546Sopenharmony_ci _eglError(egl_error_from_dri_image_error(error), "dri2_create_image_khr"); 2312bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2313bf215546Sopenharmony_ci } 2314bf215546Sopenharmony_ci } else { 2315bf215546Sopenharmony_ci dri_image = dri2_dpy->image->createImageFromRenderbuffer( 2316bf215546Sopenharmony_ci dri2_ctx->dri_context, renderbuffer, NULL); 2317bf215546Sopenharmony_ci if (!dri_image) { 2318bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); 2319bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2320bf215546Sopenharmony_ci } 2321bf215546Sopenharmony_ci } 2322bf215546Sopenharmony_ci 2323bf215546Sopenharmony_ci return dri2_create_image_from_dri(disp, dri_image); 2324bf215546Sopenharmony_ci} 2325bf215546Sopenharmony_ci 2326bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 2327bf215546Sopenharmony_ci 2328bf215546Sopenharmony_ci/* This structure describes how a wl_buffer maps to one or more 2329bf215546Sopenharmony_ci * __DRIimages. A wl_drm_buffer stores the wl_drm format code and the 2330bf215546Sopenharmony_ci * offsets and strides of the planes in the buffer. This table maps a 2331bf215546Sopenharmony_ci * wl_drm format code to a description of the planes in the buffer 2332bf215546Sopenharmony_ci * that lets us create a __DRIimage for each of the planes. */ 2333bf215546Sopenharmony_ci 2334bf215546Sopenharmony_cistatic const struct wl_drm_components_descriptor { 2335bf215546Sopenharmony_ci uint32_t dri_components; 2336bf215546Sopenharmony_ci EGLint components; 2337bf215546Sopenharmony_ci int nplanes; 2338bf215546Sopenharmony_ci} wl_drm_components[] = { 2339bf215546Sopenharmony_ci { __DRI_IMAGE_COMPONENTS_RGB, EGL_TEXTURE_RGB, 1 }, 2340bf215546Sopenharmony_ci { __DRI_IMAGE_COMPONENTS_RGBA, EGL_TEXTURE_RGBA, 1 }, 2341bf215546Sopenharmony_ci { __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 }, 2342bf215546Sopenharmony_ci { __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 }, 2343bf215546Sopenharmony_ci { __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 }, 2344bf215546Sopenharmony_ci}; 2345bf215546Sopenharmony_ci 2346bf215546Sopenharmony_cistatic _EGLImage * 2347bf215546Sopenharmony_cidri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx, 2348bf215546Sopenharmony_ci EGLClientBuffer _buffer, 2349bf215546Sopenharmony_ci const EGLint *attr_list) 2350bf215546Sopenharmony_ci{ 2351bf215546Sopenharmony_ci struct wl_drm_buffer *buffer; 2352bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2353bf215546Sopenharmony_ci const struct wl_drm_components_descriptor *f; 2354bf215546Sopenharmony_ci __DRIimage *dri_image; 2355bf215546Sopenharmony_ci _EGLImageAttribs attrs; 2356bf215546Sopenharmony_ci int32_t plane; 2357bf215546Sopenharmony_ci 2358bf215546Sopenharmony_ci buffer = wayland_drm_buffer_get(dri2_dpy->wl_server_drm, 2359bf215546Sopenharmony_ci (struct wl_resource *) _buffer); 2360bf215546Sopenharmony_ci if (!buffer) 2361bf215546Sopenharmony_ci return NULL; 2362bf215546Sopenharmony_ci 2363bf215546Sopenharmony_ci if (!_eglParseImageAttribList(&attrs, disp, attr_list)) 2364bf215546Sopenharmony_ci return NULL; 2365bf215546Sopenharmony_ci 2366bf215546Sopenharmony_ci plane = attrs.PlaneWL; 2367bf215546Sopenharmony_ci f = buffer->driver_format; 2368bf215546Sopenharmony_ci if (plane < 0 || plane >= f->nplanes) { 2369bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, 2370bf215546Sopenharmony_ci "dri2_create_image_wayland_wl_buffer (plane out of bounds)"); 2371bf215546Sopenharmony_ci return NULL; 2372bf215546Sopenharmony_ci } 2373bf215546Sopenharmony_ci 2374bf215546Sopenharmony_ci dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL); 2375bf215546Sopenharmony_ci if (dri_image == NULL && plane == 0) 2376bf215546Sopenharmony_ci dri_image = dri2_dpy->image->dupImage(buffer->driver_buffer, NULL); 2377bf215546Sopenharmony_ci if (dri_image == NULL) { 2378bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); 2379bf215546Sopenharmony_ci return NULL; 2380bf215546Sopenharmony_ci } 2381bf215546Sopenharmony_ci 2382bf215546Sopenharmony_ci return dri2_create_image_from_dri(disp, dri_image); 2383bf215546Sopenharmony_ci} 2384bf215546Sopenharmony_ci#endif 2385bf215546Sopenharmony_ci 2386bf215546Sopenharmony_cistatic EGLBoolean 2387bf215546Sopenharmony_cidri2_get_sync_values_chromium(_EGLDisplay *disp, _EGLSurface *surf, 2388bf215546Sopenharmony_ci EGLuint64KHR *ust, EGLuint64KHR *msc, 2389bf215546Sopenharmony_ci EGLuint64KHR *sbc) 2390bf215546Sopenharmony_ci{ 2391bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2392bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->get_sync_values) 2393bf215546Sopenharmony_ci return EGL_FALSE; 2394bf215546Sopenharmony_ci return dri2_dpy->vtbl->get_sync_values(disp, surf, ust, msc, sbc); 2395bf215546Sopenharmony_ci} 2396bf215546Sopenharmony_ci 2397bf215546Sopenharmony_ci/** 2398bf215546Sopenharmony_ci * Set the error code after a call to 2399bf215546Sopenharmony_ci * dri2_egl_image::dri_image::createImageFromTexture. 2400bf215546Sopenharmony_ci */ 2401bf215546Sopenharmony_cistatic void 2402bf215546Sopenharmony_cidri2_create_image_khr_texture_error(int dri_error) 2403bf215546Sopenharmony_ci{ 2404bf215546Sopenharmony_ci EGLint egl_error = egl_error_from_dri_image_error(dri_error); 2405bf215546Sopenharmony_ci 2406bf215546Sopenharmony_ci if (egl_error != EGL_SUCCESS) 2407bf215546Sopenharmony_ci _eglError(egl_error, "dri2_create_image_khr_texture"); 2408bf215546Sopenharmony_ci} 2409bf215546Sopenharmony_ci 2410bf215546Sopenharmony_cistatic _EGLImage * 2411bf215546Sopenharmony_cidri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx, 2412bf215546Sopenharmony_ci EGLenum target, 2413bf215546Sopenharmony_ci EGLClientBuffer buffer, 2414bf215546Sopenharmony_ci const EGLint *attr_list) 2415bf215546Sopenharmony_ci{ 2416bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2417bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 2418bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img; 2419bf215546Sopenharmony_ci GLuint texture = (GLuint) (uintptr_t) buffer; 2420bf215546Sopenharmony_ci _EGLImageAttribs attrs; 2421bf215546Sopenharmony_ci GLuint depth; 2422bf215546Sopenharmony_ci GLenum gl_target; 2423bf215546Sopenharmony_ci unsigned error; 2424bf215546Sopenharmony_ci 2425bf215546Sopenharmony_ci if (texture == 0) { 2426bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 2427bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2428bf215546Sopenharmony_ci } 2429bf215546Sopenharmony_ci 2430bf215546Sopenharmony_ci if (!_eglParseImageAttribList(&attrs, disp, attr_list)) 2431bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2432bf215546Sopenharmony_ci 2433bf215546Sopenharmony_ci switch (target) { 2434bf215546Sopenharmony_ci case EGL_GL_TEXTURE_2D_KHR: 2435bf215546Sopenharmony_ci if (!disp->Extensions.KHR_gl_texture_2D_image) { 2436bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 2437bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2438bf215546Sopenharmony_ci } 2439bf215546Sopenharmony_ci depth = 0; 2440bf215546Sopenharmony_ci gl_target = GL_TEXTURE_2D; 2441bf215546Sopenharmony_ci break; 2442bf215546Sopenharmony_ci case EGL_GL_TEXTURE_3D_KHR: 2443bf215546Sopenharmony_ci if (!disp->Extensions.KHR_gl_texture_3D_image) { 2444bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 2445bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2446bf215546Sopenharmony_ci } 2447bf215546Sopenharmony_ci 2448bf215546Sopenharmony_ci depth = attrs.GLTextureZOffset; 2449bf215546Sopenharmony_ci gl_target = GL_TEXTURE_3D; 2450bf215546Sopenharmony_ci break; 2451bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: 2452bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: 2453bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: 2454bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: 2455bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: 2456bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: 2457bf215546Sopenharmony_ci if (!disp->Extensions.KHR_gl_texture_cubemap_image) { 2458bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 2459bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2460bf215546Sopenharmony_ci } 2461bf215546Sopenharmony_ci 2462bf215546Sopenharmony_ci depth = target - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR; 2463bf215546Sopenharmony_ci gl_target = GL_TEXTURE_CUBE_MAP; 2464bf215546Sopenharmony_ci break; 2465bf215546Sopenharmony_ci default: 2466bf215546Sopenharmony_ci unreachable("Unexpected target in dri2_create_image_khr_texture()"); 2467bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2468bf215546Sopenharmony_ci } 2469bf215546Sopenharmony_ci 2470bf215546Sopenharmony_ci dri2_img = malloc(sizeof *dri2_img); 2471bf215546Sopenharmony_ci if (!dri2_img) { 2472bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); 2473bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2474bf215546Sopenharmony_ci } 2475bf215546Sopenharmony_ci 2476bf215546Sopenharmony_ci _eglInitImage(&dri2_img->base, disp); 2477bf215546Sopenharmony_ci 2478bf215546Sopenharmony_ci dri2_img->dri_image = 2479bf215546Sopenharmony_ci dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context, 2480bf215546Sopenharmony_ci gl_target, 2481bf215546Sopenharmony_ci texture, 2482bf215546Sopenharmony_ci depth, 2483bf215546Sopenharmony_ci attrs.GLTextureLevel, 2484bf215546Sopenharmony_ci &error, 2485bf215546Sopenharmony_ci NULL); 2486bf215546Sopenharmony_ci dri2_create_image_khr_texture_error(error); 2487bf215546Sopenharmony_ci 2488bf215546Sopenharmony_ci if (!dri2_img->dri_image) { 2489bf215546Sopenharmony_ci free(dri2_img); 2490bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2491bf215546Sopenharmony_ci } 2492bf215546Sopenharmony_ci return &dri2_img->base; 2493bf215546Sopenharmony_ci} 2494bf215546Sopenharmony_ci 2495bf215546Sopenharmony_cistatic EGLBoolean 2496bf215546Sopenharmony_cidri2_query_surface(_EGLDisplay *disp, _EGLSurface *surf, 2497bf215546Sopenharmony_ci EGLint attribute, EGLint *value) 2498bf215546Sopenharmony_ci{ 2499bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2500bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->query_surface) 2501bf215546Sopenharmony_ci return _eglQuerySurface(disp, surf, attribute, value); 2502bf215546Sopenharmony_ci return dri2_dpy->vtbl->query_surface(disp, surf, attribute, value); 2503bf215546Sopenharmony_ci} 2504bf215546Sopenharmony_ci 2505bf215546Sopenharmony_cistatic struct wl_buffer* 2506bf215546Sopenharmony_cidri2_create_wayland_buffer_from_image(_EGLDisplay *disp, _EGLImage *img) 2507bf215546Sopenharmony_ci{ 2508bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2509bf215546Sopenharmony_ci if (!dri2_dpy->vtbl->create_wayland_buffer_from_image) 2510bf215546Sopenharmony_ci return NULL; 2511bf215546Sopenharmony_ci return dri2_dpy->vtbl->create_wayland_buffer_from_image(disp, img); 2512bf215546Sopenharmony_ci} 2513bf215546Sopenharmony_ci 2514bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 2515bf215546Sopenharmony_cistatic _EGLImage * 2516bf215546Sopenharmony_cidri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, 2517bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 2518bf215546Sopenharmony_ci{ 2519bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2520bf215546Sopenharmony_ci EGLint format, name, pitch; 2521bf215546Sopenharmony_ci _EGLImageAttribs attrs; 2522bf215546Sopenharmony_ci __DRIimage *dri_image; 2523bf215546Sopenharmony_ci 2524bf215546Sopenharmony_ci name = (EGLint) (uintptr_t) buffer; 2525bf215546Sopenharmony_ci 2526bf215546Sopenharmony_ci if (!_eglParseImageAttribList(&attrs, disp, attr_list)) 2527bf215546Sopenharmony_ci return NULL; 2528bf215546Sopenharmony_ci 2529bf215546Sopenharmony_ci if (attrs.Width <= 0 || attrs.Height <= 0 || 2530bf215546Sopenharmony_ci attrs.DRMBufferStrideMESA <= 0) { 2531bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, 2532bf215546Sopenharmony_ci "bad width, height or stride"); 2533bf215546Sopenharmony_ci return NULL; 2534bf215546Sopenharmony_ci } 2535bf215546Sopenharmony_ci 2536bf215546Sopenharmony_ci switch (attrs.DRMBufferFormatMESA) { 2537bf215546Sopenharmony_ci case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: 2538bf215546Sopenharmony_ci format = __DRI_IMAGE_FORMAT_ARGB8888; 2539bf215546Sopenharmony_ci pitch = attrs.DRMBufferStrideMESA; 2540bf215546Sopenharmony_ci break; 2541bf215546Sopenharmony_ci default: 2542bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, 2543bf215546Sopenharmony_ci "dri2_create_image_khr: unsupported pixmap depth"); 2544bf215546Sopenharmony_ci return NULL; 2545bf215546Sopenharmony_ci } 2546bf215546Sopenharmony_ci 2547bf215546Sopenharmony_ci dri_image = 2548bf215546Sopenharmony_ci dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, 2549bf215546Sopenharmony_ci attrs.Width, 2550bf215546Sopenharmony_ci attrs.Height, 2551bf215546Sopenharmony_ci format, 2552bf215546Sopenharmony_ci name, 2553bf215546Sopenharmony_ci pitch, 2554bf215546Sopenharmony_ci NULL); 2555bf215546Sopenharmony_ci 2556bf215546Sopenharmony_ci return dri2_create_image_from_dri(disp, dri_image); 2557bf215546Sopenharmony_ci} 2558bf215546Sopenharmony_ci 2559bf215546Sopenharmony_cistatic EGLBoolean 2560bf215546Sopenharmony_cidri2_check_dma_buf_attribs(const _EGLImageAttribs *attrs) 2561bf215546Sopenharmony_ci{ 2562bf215546Sopenharmony_ci /** 2563bf215546Sopenharmony_ci * The spec says: 2564bf215546Sopenharmony_ci * 2565bf215546Sopenharmony_ci * "Required attributes and their values are as follows: 2566bf215546Sopenharmony_ci * 2567bf215546Sopenharmony_ci * * EGL_WIDTH & EGL_HEIGHT: The logical dimensions of the buffer in pixels 2568bf215546Sopenharmony_ci * 2569bf215546Sopenharmony_ci * * EGL_LINUX_DRM_FOURCC_EXT: The pixel format of the buffer, as specified 2570bf215546Sopenharmony_ci * by drm_fourcc.h and used as the pixel_format parameter of the 2571bf215546Sopenharmony_ci * drm_mode_fb_cmd2 ioctl." 2572bf215546Sopenharmony_ci * 2573bf215546Sopenharmony_ci * and 2574bf215546Sopenharmony_ci * 2575bf215546Sopenharmony_ci * "* If <target> is EGL_LINUX_DMA_BUF_EXT, and the list of attributes is 2576bf215546Sopenharmony_ci * incomplete, EGL_BAD_PARAMETER is generated." 2577bf215546Sopenharmony_ci */ 2578bf215546Sopenharmony_ci if (attrs->Width <= 0 || attrs->Height <= 0 || 2579bf215546Sopenharmony_ci !attrs->DMABufFourCC.IsPresent) 2580bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "attribute(s) missing"); 2581bf215546Sopenharmony_ci 2582bf215546Sopenharmony_ci /** 2583bf215546Sopenharmony_ci * Also: 2584bf215546Sopenharmony_ci * 2585bf215546Sopenharmony_ci * "If <target> is EGL_LINUX_DMA_BUF_EXT and one or more of the values 2586bf215546Sopenharmony_ci * specified for a plane's pitch or offset isn't supported by EGL, 2587bf215546Sopenharmony_ci * EGL_BAD_ACCESS is generated." 2588bf215546Sopenharmony_ci */ 2589bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(attrs->DMABufPlanePitches); ++i) { 2590bf215546Sopenharmony_ci if (attrs->DMABufPlanePitches[i].IsPresent && 2591bf215546Sopenharmony_ci attrs->DMABufPlanePitches[i].Value <= 0) 2592bf215546Sopenharmony_ci return _eglError(EGL_BAD_ACCESS, "invalid pitch"); 2593bf215546Sopenharmony_ci } 2594bf215546Sopenharmony_ci 2595bf215546Sopenharmony_ci /** 2596bf215546Sopenharmony_ci * If <target> is EGL_LINUX_DMA_BUF_EXT, both or neither of the following 2597bf215546Sopenharmony_ci * attribute values may be given. 2598bf215546Sopenharmony_ci * 2599bf215546Sopenharmony_ci * This is referring to EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT and 2600bf215546Sopenharmony_ci * EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, and the same for other planes. 2601bf215546Sopenharmony_ci */ 2602bf215546Sopenharmony_ci for (unsigned i = 0; i < DMA_BUF_MAX_PLANES; ++i) { 2603bf215546Sopenharmony_ci if (attrs->DMABufPlaneModifiersLo[i].IsPresent != 2604bf215546Sopenharmony_ci attrs->DMABufPlaneModifiersHi[i].IsPresent) 2605bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "modifier attribute lo or hi missing"); 2606bf215546Sopenharmony_ci } 2607bf215546Sopenharmony_ci 2608bf215546Sopenharmony_ci /* Although the EGL_EXT_image_dma_buf_import_modifiers spec doesn't 2609bf215546Sopenharmony_ci * mandate it, we only accept the same modifier across all planes. */ 2610bf215546Sopenharmony_ci for (unsigned i = 1; i < DMA_BUF_MAX_PLANES; ++i) { 2611bf215546Sopenharmony_ci if (attrs->DMABufPlaneFds[i].IsPresent) { 2612bf215546Sopenharmony_ci if ((attrs->DMABufPlaneModifiersLo[0].IsPresent != 2613bf215546Sopenharmony_ci attrs->DMABufPlaneModifiersLo[i].IsPresent) || 2614bf215546Sopenharmony_ci (attrs->DMABufPlaneModifiersLo[0].Value != 2615bf215546Sopenharmony_ci attrs->DMABufPlaneModifiersLo[i].Value) || 2616bf215546Sopenharmony_ci (attrs->DMABufPlaneModifiersHi[0].Value != 2617bf215546Sopenharmony_ci attrs->DMABufPlaneModifiersHi[i].Value)) 2618bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "modifier attributes not equal"); 2619bf215546Sopenharmony_ci } 2620bf215546Sopenharmony_ci } 2621bf215546Sopenharmony_ci 2622bf215546Sopenharmony_ci return EGL_TRUE; 2623bf215546Sopenharmony_ci} 2624bf215546Sopenharmony_ci 2625bf215546Sopenharmony_ci/* Returns the total number of planes for the format or zero if it isn't a 2626bf215546Sopenharmony_ci * valid fourcc format. 2627bf215546Sopenharmony_ci */ 2628bf215546Sopenharmony_cistatic unsigned 2629bf215546Sopenharmony_cidri2_num_fourcc_format_planes(EGLint format) 2630bf215546Sopenharmony_ci{ 2631bf215546Sopenharmony_ci switch (format) { 2632bf215546Sopenharmony_ci case DRM_FORMAT_R8: 2633bf215546Sopenharmony_ci case DRM_FORMAT_RG88: 2634bf215546Sopenharmony_ci case DRM_FORMAT_GR88: 2635bf215546Sopenharmony_ci case DRM_FORMAT_R16: 2636bf215546Sopenharmony_ci case DRM_FORMAT_GR1616: 2637bf215546Sopenharmony_ci case DRM_FORMAT_RGB332: 2638bf215546Sopenharmony_ci case DRM_FORMAT_BGR233: 2639bf215546Sopenharmony_ci case DRM_FORMAT_XRGB4444: 2640bf215546Sopenharmony_ci case DRM_FORMAT_XBGR4444: 2641bf215546Sopenharmony_ci case DRM_FORMAT_RGBX4444: 2642bf215546Sopenharmony_ci case DRM_FORMAT_BGRX4444: 2643bf215546Sopenharmony_ci case DRM_FORMAT_ARGB4444: 2644bf215546Sopenharmony_ci case DRM_FORMAT_ABGR4444: 2645bf215546Sopenharmony_ci case DRM_FORMAT_RGBA4444: 2646bf215546Sopenharmony_ci case DRM_FORMAT_BGRA4444: 2647bf215546Sopenharmony_ci case DRM_FORMAT_XRGB1555: 2648bf215546Sopenharmony_ci case DRM_FORMAT_XBGR1555: 2649bf215546Sopenharmony_ci case DRM_FORMAT_RGBX5551: 2650bf215546Sopenharmony_ci case DRM_FORMAT_BGRX5551: 2651bf215546Sopenharmony_ci case DRM_FORMAT_ARGB1555: 2652bf215546Sopenharmony_ci case DRM_FORMAT_ABGR1555: 2653bf215546Sopenharmony_ci case DRM_FORMAT_RGBA5551: 2654bf215546Sopenharmony_ci case DRM_FORMAT_BGRA5551: 2655bf215546Sopenharmony_ci case DRM_FORMAT_RGB565: 2656bf215546Sopenharmony_ci case DRM_FORMAT_BGR565: 2657bf215546Sopenharmony_ci case DRM_FORMAT_RGB888: 2658bf215546Sopenharmony_ci case DRM_FORMAT_BGR888: 2659bf215546Sopenharmony_ci case DRM_FORMAT_XRGB8888: 2660bf215546Sopenharmony_ci case DRM_FORMAT_XBGR8888: 2661bf215546Sopenharmony_ci case DRM_FORMAT_RGBX8888: 2662bf215546Sopenharmony_ci case DRM_FORMAT_BGRX8888: 2663bf215546Sopenharmony_ci case DRM_FORMAT_ARGB8888: 2664bf215546Sopenharmony_ci case DRM_FORMAT_ABGR8888: 2665bf215546Sopenharmony_ci case DRM_FORMAT_RGBA8888: 2666bf215546Sopenharmony_ci case DRM_FORMAT_BGRA8888: 2667bf215546Sopenharmony_ci case DRM_FORMAT_XRGB2101010: 2668bf215546Sopenharmony_ci case DRM_FORMAT_XBGR2101010: 2669bf215546Sopenharmony_ci case DRM_FORMAT_RGBX1010102: 2670bf215546Sopenharmony_ci case DRM_FORMAT_BGRX1010102: 2671bf215546Sopenharmony_ci case DRM_FORMAT_ARGB2101010: 2672bf215546Sopenharmony_ci case DRM_FORMAT_ABGR2101010: 2673bf215546Sopenharmony_ci case DRM_FORMAT_RGBA1010102: 2674bf215546Sopenharmony_ci case DRM_FORMAT_BGRA1010102: 2675bf215546Sopenharmony_ci case DRM_FORMAT_ABGR16161616: 2676bf215546Sopenharmony_ci case DRM_FORMAT_XBGR16161616: 2677bf215546Sopenharmony_ci case DRM_FORMAT_XBGR16161616F: 2678bf215546Sopenharmony_ci case DRM_FORMAT_ABGR16161616F: 2679bf215546Sopenharmony_ci case DRM_FORMAT_YUYV: 2680bf215546Sopenharmony_ci case DRM_FORMAT_YVYU: 2681bf215546Sopenharmony_ci case DRM_FORMAT_UYVY: 2682bf215546Sopenharmony_ci case DRM_FORMAT_VYUY: 2683bf215546Sopenharmony_ci case DRM_FORMAT_AYUV: 2684bf215546Sopenharmony_ci case DRM_FORMAT_XYUV8888: 2685bf215546Sopenharmony_ci case DRM_FORMAT_Y210: 2686bf215546Sopenharmony_ci case DRM_FORMAT_Y212: 2687bf215546Sopenharmony_ci case DRM_FORMAT_Y216: 2688bf215546Sopenharmony_ci case DRM_FORMAT_Y410: 2689bf215546Sopenharmony_ci case DRM_FORMAT_Y412: 2690bf215546Sopenharmony_ci case DRM_FORMAT_Y416: 2691bf215546Sopenharmony_ci return 1; 2692bf215546Sopenharmony_ci 2693bf215546Sopenharmony_ci case DRM_FORMAT_NV12: 2694bf215546Sopenharmony_ci case DRM_FORMAT_NV21: 2695bf215546Sopenharmony_ci case DRM_FORMAT_NV16: 2696bf215546Sopenharmony_ci case DRM_FORMAT_NV61: 2697bf215546Sopenharmony_ci case DRM_FORMAT_P010: 2698bf215546Sopenharmony_ci case DRM_FORMAT_P012: 2699bf215546Sopenharmony_ci case DRM_FORMAT_P016: 2700bf215546Sopenharmony_ci return 2; 2701bf215546Sopenharmony_ci 2702bf215546Sopenharmony_ci case DRM_FORMAT_YUV410: 2703bf215546Sopenharmony_ci case DRM_FORMAT_YVU410: 2704bf215546Sopenharmony_ci case DRM_FORMAT_YUV411: 2705bf215546Sopenharmony_ci case DRM_FORMAT_YVU411: 2706bf215546Sopenharmony_ci case DRM_FORMAT_YUV420: 2707bf215546Sopenharmony_ci case DRM_FORMAT_YVU420: 2708bf215546Sopenharmony_ci case DRM_FORMAT_YUV422: 2709bf215546Sopenharmony_ci case DRM_FORMAT_YVU422: 2710bf215546Sopenharmony_ci case DRM_FORMAT_YUV444: 2711bf215546Sopenharmony_ci case DRM_FORMAT_YVU444: 2712bf215546Sopenharmony_ci return 3; 2713bf215546Sopenharmony_ci 2714bf215546Sopenharmony_ci default: 2715bf215546Sopenharmony_ci return 0; 2716bf215546Sopenharmony_ci } 2717bf215546Sopenharmony_ci} 2718bf215546Sopenharmony_ci 2719bf215546Sopenharmony_ci/* Returns the total number of file descriptors. Zero indicates an error. */ 2720bf215546Sopenharmony_cistatic unsigned 2721bf215546Sopenharmony_cidri2_check_dma_buf_format(const _EGLImageAttribs *attrs) 2722bf215546Sopenharmony_ci{ 2723bf215546Sopenharmony_ci unsigned plane_n = dri2_num_fourcc_format_planes(attrs->DMABufFourCC.Value); 2724bf215546Sopenharmony_ci if (plane_n == 0) { 2725bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "unknown drm fourcc format"); 2726bf215546Sopenharmony_ci return 0; 2727bf215546Sopenharmony_ci } 2728bf215546Sopenharmony_ci 2729bf215546Sopenharmony_ci for (unsigned i = plane_n; i < DMA_BUF_MAX_PLANES; i++) { 2730bf215546Sopenharmony_ci /** 2731bf215546Sopenharmony_ci * The modifiers extension spec says: 2732bf215546Sopenharmony_ci * 2733bf215546Sopenharmony_ci * "Modifiers may modify any attribute of a buffer import, including 2734bf215546Sopenharmony_ci * but not limited to adding extra planes to a format which 2735bf215546Sopenharmony_ci * otherwise does not have those planes. As an example, a modifier 2736bf215546Sopenharmony_ci * may add a plane for an external compression buffer to a 2737bf215546Sopenharmony_ci * single-plane format. The exact meaning and effect of any 2738bf215546Sopenharmony_ci * modifier is canonically defined by drm_fourcc.h, not as part of 2739bf215546Sopenharmony_ci * this extension." 2740bf215546Sopenharmony_ci */ 2741bf215546Sopenharmony_ci if (attrs->DMABufPlaneModifiersLo[i].IsPresent && 2742bf215546Sopenharmony_ci attrs->DMABufPlaneModifiersHi[i].IsPresent) { 2743bf215546Sopenharmony_ci plane_n = i + 1; 2744bf215546Sopenharmony_ci } 2745bf215546Sopenharmony_ci } 2746bf215546Sopenharmony_ci 2747bf215546Sopenharmony_ci /** 2748bf215546Sopenharmony_ci * The spec says: 2749bf215546Sopenharmony_ci * 2750bf215546Sopenharmony_ci * "* If <target> is EGL_LINUX_DMA_BUF_EXT, and the list of attributes is 2751bf215546Sopenharmony_ci * incomplete, EGL_BAD_PARAMETER is generated." 2752bf215546Sopenharmony_ci */ 2753bf215546Sopenharmony_ci for (unsigned i = 0; i < plane_n; ++i) { 2754bf215546Sopenharmony_ci if (!attrs->DMABufPlaneFds[i].IsPresent || 2755bf215546Sopenharmony_ci !attrs->DMABufPlaneOffsets[i].IsPresent || 2756bf215546Sopenharmony_ci !attrs->DMABufPlanePitches[i].IsPresent) { 2757bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "plane attribute(s) missing"); 2758bf215546Sopenharmony_ci return 0; 2759bf215546Sopenharmony_ci } 2760bf215546Sopenharmony_ci } 2761bf215546Sopenharmony_ci 2762bf215546Sopenharmony_ci /** 2763bf215546Sopenharmony_ci * The spec also says: 2764bf215546Sopenharmony_ci * 2765bf215546Sopenharmony_ci * "If <target> is EGL_LINUX_DMA_BUF_EXT, and the EGL_LINUX_DRM_FOURCC_EXT 2766bf215546Sopenharmony_ci * attribute indicates a single-plane format, EGL_BAD_ATTRIBUTE is 2767bf215546Sopenharmony_ci * generated if any of the EGL_DMA_BUF_PLANE1_* or EGL_DMA_BUF_PLANE2_* 2768bf215546Sopenharmony_ci * or EGL_DMA_BUF_PLANE3_* attributes are specified." 2769bf215546Sopenharmony_ci */ 2770bf215546Sopenharmony_ci for (unsigned i = plane_n; i < DMA_BUF_MAX_PLANES; ++i) { 2771bf215546Sopenharmony_ci if (attrs->DMABufPlaneFds[i].IsPresent || 2772bf215546Sopenharmony_ci attrs->DMABufPlaneOffsets[i].IsPresent || 2773bf215546Sopenharmony_ci attrs->DMABufPlanePitches[i].IsPresent) { 2774bf215546Sopenharmony_ci _eglError(EGL_BAD_ATTRIBUTE, "too many plane attributes"); 2775bf215546Sopenharmony_ci return 0; 2776bf215546Sopenharmony_ci } 2777bf215546Sopenharmony_ci } 2778bf215546Sopenharmony_ci 2779bf215546Sopenharmony_ci return plane_n; 2780bf215546Sopenharmony_ci} 2781bf215546Sopenharmony_ci 2782bf215546Sopenharmony_cistatic EGLBoolean 2783bf215546Sopenharmony_cidri2_query_dma_buf_formats(_EGLDisplay *disp, EGLint max, 2784bf215546Sopenharmony_ci EGLint *formats, EGLint *count) 2785bf215546Sopenharmony_ci{ 2786bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2787bf215546Sopenharmony_ci if (max < 0 || (max > 0 && formats == NULL)) 2788bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "invalid value for max count of formats"); 2789bf215546Sopenharmony_ci 2790bf215546Sopenharmony_ci if (dri2_dpy->image->base.version < 15 || 2791bf215546Sopenharmony_ci dri2_dpy->image->queryDmaBufFormats == NULL) 2792bf215546Sopenharmony_ci return EGL_FALSE; 2793bf215546Sopenharmony_ci 2794bf215546Sopenharmony_ci if (!dri2_dpy->image->queryDmaBufFormats(dri2_dpy->dri_screen, max, 2795bf215546Sopenharmony_ci formats, count)) 2796bf215546Sopenharmony_ci return EGL_FALSE; 2797bf215546Sopenharmony_ci 2798bf215546Sopenharmony_ci if (max > 0) { 2799bf215546Sopenharmony_ci /* Assert that all of the formats returned are actually fourcc formats. 2800bf215546Sopenharmony_ci * Some day, if we want the internal interface function to be able to 2801bf215546Sopenharmony_ci * return the fake fourcc formats defined in dri_interface.h, we'll have 2802bf215546Sopenharmony_ci * to do something more clever here to pair the list down to just real 2803bf215546Sopenharmony_ci * fourcc formats so that we don't leak the fake internal ones. 2804bf215546Sopenharmony_ci */ 2805bf215546Sopenharmony_ci for (int i = 0; i < *count; i++) { 2806bf215546Sopenharmony_ci assert(dri2_num_fourcc_format_planes(formats[i]) > 0); 2807bf215546Sopenharmony_ci } 2808bf215546Sopenharmony_ci } 2809bf215546Sopenharmony_ci 2810bf215546Sopenharmony_ci return EGL_TRUE; 2811bf215546Sopenharmony_ci} 2812bf215546Sopenharmony_ci 2813bf215546Sopenharmony_cistatic EGLBoolean 2814bf215546Sopenharmony_cidri2_query_dma_buf_modifiers(_EGLDisplay *disp, EGLint format, 2815bf215546Sopenharmony_ci EGLint max, EGLuint64KHR *modifiers, 2816bf215546Sopenharmony_ci EGLBoolean *external_only, EGLint *count) 2817bf215546Sopenharmony_ci{ 2818bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2819bf215546Sopenharmony_ci 2820bf215546Sopenharmony_ci if (dri2_num_fourcc_format_planes(format) == 0) 2821bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "invalid fourcc format"); 2822bf215546Sopenharmony_ci 2823bf215546Sopenharmony_ci if (max < 0) 2824bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "invalid value for max count of formats"); 2825bf215546Sopenharmony_ci 2826bf215546Sopenharmony_ci if (max > 0 && modifiers == NULL) 2827bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "invalid modifiers array"); 2828bf215546Sopenharmony_ci 2829bf215546Sopenharmony_ci if (dri2_dpy->image->base.version < 15 || 2830bf215546Sopenharmony_ci dri2_dpy->image->queryDmaBufModifiers == NULL) 2831bf215546Sopenharmony_ci return EGL_FALSE; 2832bf215546Sopenharmony_ci 2833bf215546Sopenharmony_ci if (dri2_dpy->image->queryDmaBufModifiers(dri2_dpy->dri_screen, format, 2834bf215546Sopenharmony_ci max, modifiers, 2835bf215546Sopenharmony_ci (unsigned int *) external_only, 2836bf215546Sopenharmony_ci count) == false) 2837bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "invalid format"); 2838bf215546Sopenharmony_ci 2839bf215546Sopenharmony_ci return EGL_TRUE; 2840bf215546Sopenharmony_ci} 2841bf215546Sopenharmony_ci 2842bf215546Sopenharmony_ci/** 2843bf215546Sopenharmony_ci * The spec says: 2844bf215546Sopenharmony_ci * 2845bf215546Sopenharmony_ci * "If eglCreateImageKHR is successful for a EGL_LINUX_DMA_BUF_EXT target, the 2846bf215546Sopenharmony_ci * EGL will take a reference to the dma_buf(s) which it will release at any 2847bf215546Sopenharmony_ci * time while the EGLDisplay is initialized. It is the responsibility of the 2848bf215546Sopenharmony_ci * application to close the dma_buf file descriptors." 2849bf215546Sopenharmony_ci * 2850bf215546Sopenharmony_ci * Therefore we must never close or otherwise modify the file descriptors. 2851bf215546Sopenharmony_ci */ 2852bf215546Sopenharmony_ci_EGLImage * 2853bf215546Sopenharmony_cidri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx, 2854bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 2855bf215546Sopenharmony_ci{ 2856bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2857bf215546Sopenharmony_ci _EGLImage *res; 2858bf215546Sopenharmony_ci _EGLImageAttribs attrs; 2859bf215546Sopenharmony_ci __DRIimage *dri_image; 2860bf215546Sopenharmony_ci unsigned num_fds; 2861bf215546Sopenharmony_ci int fds[DMA_BUF_MAX_PLANES]; 2862bf215546Sopenharmony_ci int pitches[DMA_BUF_MAX_PLANES]; 2863bf215546Sopenharmony_ci int offsets[DMA_BUF_MAX_PLANES]; 2864bf215546Sopenharmony_ci uint64_t modifier; 2865bf215546Sopenharmony_ci bool has_modifier = false; 2866bf215546Sopenharmony_ci unsigned error; 2867bf215546Sopenharmony_ci 2868bf215546Sopenharmony_ci /** 2869bf215546Sopenharmony_ci * The spec says: 2870bf215546Sopenharmony_ci * 2871bf215546Sopenharmony_ci * ""* If <target> is EGL_LINUX_DMA_BUF_EXT and <buffer> is not NULL, the 2872bf215546Sopenharmony_ci * error EGL_BAD_PARAMETER is generated." 2873bf215546Sopenharmony_ci */ 2874bf215546Sopenharmony_ci if (buffer != NULL) { 2875bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "buffer not NULL"); 2876bf215546Sopenharmony_ci return NULL; 2877bf215546Sopenharmony_ci } 2878bf215546Sopenharmony_ci 2879bf215546Sopenharmony_ci if (!_eglParseImageAttribList(&attrs, disp, attr_list)) 2880bf215546Sopenharmony_ci return NULL; 2881bf215546Sopenharmony_ci 2882bf215546Sopenharmony_ci if (!dri2_check_dma_buf_attribs(&attrs)) 2883bf215546Sopenharmony_ci return NULL; 2884bf215546Sopenharmony_ci 2885bf215546Sopenharmony_ci num_fds = dri2_check_dma_buf_format(&attrs); 2886bf215546Sopenharmony_ci if (!num_fds) 2887bf215546Sopenharmony_ci return NULL; 2888bf215546Sopenharmony_ci 2889bf215546Sopenharmony_ci for (unsigned i = 0; i < num_fds; ++i) { 2890bf215546Sopenharmony_ci fds[i] = attrs.DMABufPlaneFds[i].Value; 2891bf215546Sopenharmony_ci pitches[i] = attrs.DMABufPlanePitches[i].Value; 2892bf215546Sopenharmony_ci offsets[i] = attrs.DMABufPlaneOffsets[i].Value; 2893bf215546Sopenharmony_ci } 2894bf215546Sopenharmony_ci 2895bf215546Sopenharmony_ci /* dri2_check_dma_buf_attribs ensures that the modifier, if available, 2896bf215546Sopenharmony_ci * will be present in attrs.DMABufPlaneModifiersLo[0] and 2897bf215546Sopenharmony_ci * attrs.DMABufPlaneModifiersHi[0] */ 2898bf215546Sopenharmony_ci if (attrs.DMABufPlaneModifiersLo[0].IsPresent) { 2899bf215546Sopenharmony_ci modifier = combine_u32_into_u64(attrs.DMABufPlaneModifiersHi[0].Value, 2900bf215546Sopenharmony_ci attrs.DMABufPlaneModifiersLo[0].Value); 2901bf215546Sopenharmony_ci has_modifier = true; 2902bf215546Sopenharmony_ci } 2903bf215546Sopenharmony_ci 2904bf215546Sopenharmony_ci if (attrs.ProtectedContent) { 2905bf215546Sopenharmony_ci if (dri2_dpy->image->base.version < 18 || 2906bf215546Sopenharmony_ci dri2_dpy->image->createImageFromDmaBufs3 == NULL) { 2907bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "unsupported protected_content attribute"); 2908bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2909bf215546Sopenharmony_ci } 2910bf215546Sopenharmony_ci if (!has_modifier) 2911bf215546Sopenharmony_ci modifier = DRM_FORMAT_MOD_INVALID; 2912bf215546Sopenharmony_ci 2913bf215546Sopenharmony_ci dri_image = 2914bf215546Sopenharmony_ci dri2_dpy->image->createImageFromDmaBufs3(dri2_dpy->dri_screen, 2915bf215546Sopenharmony_ci attrs.Width, attrs.Height, attrs.DMABufFourCC.Value, 2916bf215546Sopenharmony_ci modifier, fds, num_fds, pitches, offsets, 2917bf215546Sopenharmony_ci attrs.DMABufYuvColorSpaceHint.Value, 2918bf215546Sopenharmony_ci attrs.DMABufSampleRangeHint.Value, 2919bf215546Sopenharmony_ci attrs.DMABufChromaHorizontalSiting.Value, 2920bf215546Sopenharmony_ci attrs.DMABufChromaVerticalSiting.Value, 2921bf215546Sopenharmony_ci attrs.ProtectedContent ? __DRI_IMAGE_PROTECTED_CONTENT_FLAG : 0, 2922bf215546Sopenharmony_ci &error, 2923bf215546Sopenharmony_ci NULL); 2924bf215546Sopenharmony_ci } 2925bf215546Sopenharmony_ci else if (has_modifier) { 2926bf215546Sopenharmony_ci if (dri2_dpy->image->base.version < 15 || 2927bf215546Sopenharmony_ci dri2_dpy->image->createImageFromDmaBufs2 == NULL) { 2928bf215546Sopenharmony_ci _eglError(EGL_BAD_MATCH, "unsupported dma_buf format modifier"); 2929bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2930bf215546Sopenharmony_ci } 2931bf215546Sopenharmony_ci dri_image = 2932bf215546Sopenharmony_ci dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen, 2933bf215546Sopenharmony_ci attrs.Width, attrs.Height, attrs.DMABufFourCC.Value, 2934bf215546Sopenharmony_ci modifier, fds, num_fds, pitches, offsets, 2935bf215546Sopenharmony_ci attrs.DMABufYuvColorSpaceHint.Value, 2936bf215546Sopenharmony_ci attrs.DMABufSampleRangeHint.Value, 2937bf215546Sopenharmony_ci attrs.DMABufChromaHorizontalSiting.Value, 2938bf215546Sopenharmony_ci attrs.DMABufChromaVerticalSiting.Value, 2939bf215546Sopenharmony_ci &error, 2940bf215546Sopenharmony_ci NULL); 2941bf215546Sopenharmony_ci } 2942bf215546Sopenharmony_ci else { 2943bf215546Sopenharmony_ci dri_image = 2944bf215546Sopenharmony_ci dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen, 2945bf215546Sopenharmony_ci attrs.Width, attrs.Height, attrs.DMABufFourCC.Value, 2946bf215546Sopenharmony_ci fds, num_fds, pitches, offsets, 2947bf215546Sopenharmony_ci attrs.DMABufYuvColorSpaceHint.Value, 2948bf215546Sopenharmony_ci attrs.DMABufSampleRangeHint.Value, 2949bf215546Sopenharmony_ci attrs.DMABufChromaHorizontalSiting.Value, 2950bf215546Sopenharmony_ci attrs.DMABufChromaVerticalSiting.Value, 2951bf215546Sopenharmony_ci &error, 2952bf215546Sopenharmony_ci NULL); 2953bf215546Sopenharmony_ci } 2954bf215546Sopenharmony_ci dri2_create_image_khr_texture_error(error); 2955bf215546Sopenharmony_ci 2956bf215546Sopenharmony_ci if (!dri_image) 2957bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2958bf215546Sopenharmony_ci 2959bf215546Sopenharmony_ci res = dri2_create_image_from_dri(disp, dri_image); 2960bf215546Sopenharmony_ci 2961bf215546Sopenharmony_ci return res; 2962bf215546Sopenharmony_ci} 2963bf215546Sopenharmony_cistatic _EGLImage * 2964bf215546Sopenharmony_cidri2_create_drm_image_mesa(_EGLDisplay *disp, const EGLint *attr_list) 2965bf215546Sopenharmony_ci{ 2966bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 2967bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img; 2968bf215546Sopenharmony_ci _EGLImageAttribs attrs; 2969bf215546Sopenharmony_ci unsigned int dri_use, valid_mask; 2970bf215546Sopenharmony_ci int format; 2971bf215546Sopenharmony_ci 2972bf215546Sopenharmony_ci if (!attr_list) { 2973bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, __func__); 2974bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2975bf215546Sopenharmony_ci } 2976bf215546Sopenharmony_ci 2977bf215546Sopenharmony_ci if (!_eglParseImageAttribList(&attrs, disp, attr_list)) 2978bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2979bf215546Sopenharmony_ci 2980bf215546Sopenharmony_ci if (attrs.Width <= 0 || attrs.Height <= 0) { 2981bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, __func__); 2982bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2983bf215546Sopenharmony_ci } 2984bf215546Sopenharmony_ci 2985bf215546Sopenharmony_ci switch (attrs.DRMBufferFormatMESA) { 2986bf215546Sopenharmony_ci case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: 2987bf215546Sopenharmony_ci format = __DRI_IMAGE_FORMAT_ARGB8888; 2988bf215546Sopenharmony_ci break; 2989bf215546Sopenharmony_ci default: 2990bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, __func__); 2991bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 2992bf215546Sopenharmony_ci } 2993bf215546Sopenharmony_ci 2994bf215546Sopenharmony_ci valid_mask = 2995bf215546Sopenharmony_ci EGL_DRM_BUFFER_USE_SCANOUT_MESA | 2996bf215546Sopenharmony_ci EGL_DRM_BUFFER_USE_SHARE_MESA | 2997bf215546Sopenharmony_ci EGL_DRM_BUFFER_USE_CURSOR_MESA; 2998bf215546Sopenharmony_ci if (attrs.DRMBufferUseMESA & ~valid_mask) { 2999bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, __func__); 3000bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 3001bf215546Sopenharmony_ci } 3002bf215546Sopenharmony_ci 3003bf215546Sopenharmony_ci dri_use = 0; 3004bf215546Sopenharmony_ci if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA) 3005bf215546Sopenharmony_ci dri_use |= __DRI_IMAGE_USE_SHARE; 3006bf215546Sopenharmony_ci if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SCANOUT_MESA) 3007bf215546Sopenharmony_ci dri_use |= __DRI_IMAGE_USE_SCANOUT; 3008bf215546Sopenharmony_ci if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_CURSOR_MESA) 3009bf215546Sopenharmony_ci dri_use |= __DRI_IMAGE_USE_CURSOR; 3010bf215546Sopenharmony_ci 3011bf215546Sopenharmony_ci dri2_img = malloc(sizeof *dri2_img); 3012bf215546Sopenharmony_ci if (!dri2_img) { 3013bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); 3014bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 3015bf215546Sopenharmony_ci } 3016bf215546Sopenharmony_ci 3017bf215546Sopenharmony_ci _eglInitImage(&dri2_img->base, disp); 3018bf215546Sopenharmony_ci 3019bf215546Sopenharmony_ci dri2_img->dri_image = 3020bf215546Sopenharmony_ci dri2_dpy->image->createImage(dri2_dpy->dri_screen, 3021bf215546Sopenharmony_ci attrs.Width, attrs.Height, 3022bf215546Sopenharmony_ci format, dri_use, dri2_img); 3023bf215546Sopenharmony_ci if (dri2_img->dri_image == NULL) { 3024bf215546Sopenharmony_ci free(dri2_img); 3025bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "dri2_create_drm_image_mesa"); 3026bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 3027bf215546Sopenharmony_ci } 3028bf215546Sopenharmony_ci 3029bf215546Sopenharmony_ci return &dri2_img->base; 3030bf215546Sopenharmony_ci} 3031bf215546Sopenharmony_ci 3032bf215546Sopenharmony_cistatic EGLBoolean 3033bf215546Sopenharmony_cidri2_export_drm_image_mesa(_EGLDisplay *disp, _EGLImage *img, 3034bf215546Sopenharmony_ci EGLint *name, EGLint *handle, EGLint *stride) 3035bf215546Sopenharmony_ci{ 3036bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3037bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img = dri2_egl_image(img); 3038bf215546Sopenharmony_ci 3039bf215546Sopenharmony_ci if (name && !dri2_dpy->image->queryImage(dri2_img->dri_image, 3040bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_NAME, name)) 3041bf215546Sopenharmony_ci return _eglError(EGL_BAD_ALLOC, "dri2_export_drm_image_mesa"); 3042bf215546Sopenharmony_ci 3043bf215546Sopenharmony_ci if (handle) 3044bf215546Sopenharmony_ci dri2_dpy->image->queryImage(dri2_img->dri_image, 3045bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_HANDLE, handle); 3046bf215546Sopenharmony_ci 3047bf215546Sopenharmony_ci if (stride) 3048bf215546Sopenharmony_ci dri2_dpy->image->queryImage(dri2_img->dri_image, 3049bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_STRIDE, stride); 3050bf215546Sopenharmony_ci 3051bf215546Sopenharmony_ci return EGL_TRUE; 3052bf215546Sopenharmony_ci} 3053bf215546Sopenharmony_ci 3054bf215546Sopenharmony_ci/** 3055bf215546Sopenharmony_ci * Checks if we can support EGL_MESA_image_dma_buf_export on this image. 3056bf215546Sopenharmony_ci 3057bf215546Sopenharmony_ci * The spec provides a boolean return for the driver to reject exporting for 3058bf215546Sopenharmony_ci * basically any reason, but doesn't specify any particular error cases. For 3059bf215546Sopenharmony_ci * now, we just fail if we don't have a DRM fourcc for the format. 3060bf215546Sopenharmony_ci */ 3061bf215546Sopenharmony_cistatic bool 3062bf215546Sopenharmony_cidri2_can_export_dma_buf_image(_EGLDisplay *disp, _EGLImage *img) 3063bf215546Sopenharmony_ci{ 3064bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3065bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img = dri2_egl_image(img); 3066bf215546Sopenharmony_ci EGLint fourcc; 3067bf215546Sopenharmony_ci 3068bf215546Sopenharmony_ci if (!dri2_dpy->image->queryImage(dri2_img->dri_image, 3069bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_FOURCC, &fourcc)) { 3070bf215546Sopenharmony_ci return false; 3071bf215546Sopenharmony_ci } 3072bf215546Sopenharmony_ci 3073bf215546Sopenharmony_ci return true; 3074bf215546Sopenharmony_ci} 3075bf215546Sopenharmony_ci 3076bf215546Sopenharmony_cistatic EGLBoolean 3077bf215546Sopenharmony_cidri2_export_dma_buf_image_query_mesa(_EGLDisplay *disp, _EGLImage *img, 3078bf215546Sopenharmony_ci EGLint *fourcc, EGLint *nplanes, 3079bf215546Sopenharmony_ci EGLuint64KHR *modifiers) 3080bf215546Sopenharmony_ci{ 3081bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3082bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img = dri2_egl_image(img); 3083bf215546Sopenharmony_ci int num_planes; 3084bf215546Sopenharmony_ci 3085bf215546Sopenharmony_ci if (!dri2_can_export_dma_buf_image(disp, img)) 3086bf215546Sopenharmony_ci return EGL_FALSE; 3087bf215546Sopenharmony_ci 3088bf215546Sopenharmony_ci dri2_dpy->image->queryImage(dri2_img->dri_image, 3089bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_NUM_PLANES, &num_planes); 3090bf215546Sopenharmony_ci if (nplanes) 3091bf215546Sopenharmony_ci *nplanes = num_planes; 3092bf215546Sopenharmony_ci 3093bf215546Sopenharmony_ci if (fourcc) 3094bf215546Sopenharmony_ci dri2_dpy->image->queryImage(dri2_img->dri_image, 3095bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_FOURCC, fourcc); 3096bf215546Sopenharmony_ci 3097bf215546Sopenharmony_ci if (modifiers) { 3098bf215546Sopenharmony_ci int mod_hi, mod_lo; 3099bf215546Sopenharmony_ci uint64_t modifier = DRM_FORMAT_MOD_INVALID; 3100bf215546Sopenharmony_ci bool query; 3101bf215546Sopenharmony_ci 3102bf215546Sopenharmony_ci query = dri2_dpy->image->queryImage(dri2_img->dri_image, 3103bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, 3104bf215546Sopenharmony_ci &mod_hi); 3105bf215546Sopenharmony_ci query &= dri2_dpy->image->queryImage(dri2_img->dri_image, 3106bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, 3107bf215546Sopenharmony_ci &mod_lo); 3108bf215546Sopenharmony_ci if (query) 3109bf215546Sopenharmony_ci modifier = combine_u32_into_u64 (mod_hi, mod_lo); 3110bf215546Sopenharmony_ci 3111bf215546Sopenharmony_ci for (int i = 0; i < num_planes; i++) 3112bf215546Sopenharmony_ci modifiers[i] = modifier; 3113bf215546Sopenharmony_ci } 3114bf215546Sopenharmony_ci 3115bf215546Sopenharmony_ci return EGL_TRUE; 3116bf215546Sopenharmony_ci} 3117bf215546Sopenharmony_ci 3118bf215546Sopenharmony_cistatic EGLBoolean 3119bf215546Sopenharmony_cidri2_export_dma_buf_image_mesa(_EGLDisplay *disp, _EGLImage *img, 3120bf215546Sopenharmony_ci int *fds, EGLint *strides, EGLint *offsets) 3121bf215546Sopenharmony_ci{ 3122bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3123bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img = dri2_egl_image(img); 3124bf215546Sopenharmony_ci EGLint nplanes; 3125bf215546Sopenharmony_ci 3126bf215546Sopenharmony_ci if (!dri2_can_export_dma_buf_image(disp, img)) 3127bf215546Sopenharmony_ci return EGL_FALSE; 3128bf215546Sopenharmony_ci 3129bf215546Sopenharmony_ci /* EGL_MESA_image_dma_buf_export spec says: 3130bf215546Sopenharmony_ci * "If the number of fds is less than the number of planes, then 3131bf215546Sopenharmony_ci * subsequent fd slots should contain -1." 3132bf215546Sopenharmony_ci */ 3133bf215546Sopenharmony_ci if (fds) { 3134bf215546Sopenharmony_ci /* Query nplanes so that we know how big the given array is. */ 3135bf215546Sopenharmony_ci dri2_dpy->image->queryImage(dri2_img->dri_image, 3136bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_NUM_PLANES, &nplanes); 3137bf215546Sopenharmony_ci memset(fds, -1, nplanes * sizeof(int)); 3138bf215546Sopenharmony_ci } 3139bf215546Sopenharmony_ci 3140bf215546Sopenharmony_ci /* rework later to provide multiple fds/strides/offsets */ 3141bf215546Sopenharmony_ci if (fds) 3142bf215546Sopenharmony_ci dri2_dpy->image->queryImage(dri2_img->dri_image, 3143bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_FD, fds); 3144bf215546Sopenharmony_ci 3145bf215546Sopenharmony_ci if (strides) 3146bf215546Sopenharmony_ci dri2_dpy->image->queryImage(dri2_img->dri_image, 3147bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_STRIDE, strides); 3148bf215546Sopenharmony_ci 3149bf215546Sopenharmony_ci if (offsets) { 3150bf215546Sopenharmony_ci int img_offset; 3151bf215546Sopenharmony_ci bool ret = dri2_dpy->image->queryImage(dri2_img->dri_image, 3152bf215546Sopenharmony_ci __DRI_IMAGE_ATTRIB_OFFSET, &img_offset); 3153bf215546Sopenharmony_ci if (ret) 3154bf215546Sopenharmony_ci offsets[0] = img_offset; 3155bf215546Sopenharmony_ci else 3156bf215546Sopenharmony_ci offsets[0] = 0; 3157bf215546Sopenharmony_ci } 3158bf215546Sopenharmony_ci 3159bf215546Sopenharmony_ci return EGL_TRUE; 3160bf215546Sopenharmony_ci} 3161bf215546Sopenharmony_ci 3162bf215546Sopenharmony_ci#endif 3163bf215546Sopenharmony_ci 3164bf215546Sopenharmony_ci_EGLImage * 3165bf215546Sopenharmony_cidri2_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target, 3166bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 3167bf215546Sopenharmony_ci{ 3168bf215546Sopenharmony_ci switch (target) { 3169bf215546Sopenharmony_ci case EGL_GL_TEXTURE_2D_KHR: 3170bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: 3171bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: 3172bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: 3173bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: 3174bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: 3175bf215546Sopenharmony_ci case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: 3176bf215546Sopenharmony_ci case EGL_GL_TEXTURE_3D_KHR: 3177bf215546Sopenharmony_ci return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list); 3178bf215546Sopenharmony_ci case EGL_GL_RENDERBUFFER_KHR: 3179bf215546Sopenharmony_ci return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list); 3180bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 3181bf215546Sopenharmony_ci case EGL_DRM_BUFFER_MESA: 3182bf215546Sopenharmony_ci return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list); 3183bf215546Sopenharmony_ci case EGL_LINUX_DMA_BUF_EXT: 3184bf215546Sopenharmony_ci return dri2_create_image_dma_buf(disp, ctx, buffer, attr_list); 3185bf215546Sopenharmony_ci#endif 3186bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 3187bf215546Sopenharmony_ci case EGL_WAYLAND_BUFFER_WL: 3188bf215546Sopenharmony_ci return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list); 3189bf215546Sopenharmony_ci#endif 3190bf215546Sopenharmony_ci default: 3191bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 3192bf215546Sopenharmony_ci return EGL_NO_IMAGE_KHR; 3193bf215546Sopenharmony_ci } 3194bf215546Sopenharmony_ci} 3195bf215546Sopenharmony_ci 3196bf215546Sopenharmony_cistatic EGLBoolean 3197bf215546Sopenharmony_cidri2_destroy_image_khr(_EGLDisplay *disp, _EGLImage *image) 3198bf215546Sopenharmony_ci{ 3199bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3200bf215546Sopenharmony_ci struct dri2_egl_image *dri2_img = dri2_egl_image(image); 3201bf215546Sopenharmony_ci 3202bf215546Sopenharmony_ci dri2_dpy->image->destroyImage(dri2_img->dri_image); 3203bf215546Sopenharmony_ci free(dri2_img); 3204bf215546Sopenharmony_ci 3205bf215546Sopenharmony_ci return EGL_TRUE; 3206bf215546Sopenharmony_ci} 3207bf215546Sopenharmony_ci 3208bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 3209bf215546Sopenharmony_ci 3210bf215546Sopenharmony_cistatic void 3211bf215546Sopenharmony_cidri2_wl_reference_buffer(void *user_data, uint32_t name, int fd, 3212bf215546Sopenharmony_ci struct wl_drm_buffer *buffer) 3213bf215546Sopenharmony_ci{ 3214bf215546Sopenharmony_ci _EGLDisplay *disp = user_data; 3215bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3216bf215546Sopenharmony_ci __DRIimage *img; 3217bf215546Sopenharmony_ci int dri_components = 0; 3218bf215546Sopenharmony_ci 3219bf215546Sopenharmony_ci if (fd == -1) 3220bf215546Sopenharmony_ci img = dri2_dpy->image->createImageFromNames(dri2_dpy->dri_screen, 3221bf215546Sopenharmony_ci buffer->width, 3222bf215546Sopenharmony_ci buffer->height, 3223bf215546Sopenharmony_ci buffer->format, 3224bf215546Sopenharmony_ci (int*)&name, 1, 3225bf215546Sopenharmony_ci buffer->stride, 3226bf215546Sopenharmony_ci buffer->offset, 3227bf215546Sopenharmony_ci NULL); 3228bf215546Sopenharmony_ci else 3229bf215546Sopenharmony_ci img = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, 3230bf215546Sopenharmony_ci buffer->width, 3231bf215546Sopenharmony_ci buffer->height, 3232bf215546Sopenharmony_ci buffer->format, 3233bf215546Sopenharmony_ci &fd, 1, 3234bf215546Sopenharmony_ci buffer->stride, 3235bf215546Sopenharmony_ci buffer->offset, 3236bf215546Sopenharmony_ci NULL); 3237bf215546Sopenharmony_ci 3238bf215546Sopenharmony_ci if (img == NULL) 3239bf215546Sopenharmony_ci return; 3240bf215546Sopenharmony_ci 3241bf215546Sopenharmony_ci dri2_dpy->image->queryImage(img, __DRI_IMAGE_ATTRIB_COMPONENTS, &dri_components); 3242bf215546Sopenharmony_ci 3243bf215546Sopenharmony_ci buffer->driver_format = NULL; 3244bf215546Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(wl_drm_components); i++) 3245bf215546Sopenharmony_ci if (wl_drm_components[i].dri_components == dri_components) 3246bf215546Sopenharmony_ci buffer->driver_format = &wl_drm_components[i]; 3247bf215546Sopenharmony_ci 3248bf215546Sopenharmony_ci if (buffer->driver_format == NULL) 3249bf215546Sopenharmony_ci dri2_dpy->image->destroyImage(img); 3250bf215546Sopenharmony_ci else 3251bf215546Sopenharmony_ci buffer->driver_buffer = img; 3252bf215546Sopenharmony_ci} 3253bf215546Sopenharmony_ci 3254bf215546Sopenharmony_cistatic void 3255bf215546Sopenharmony_cidri2_wl_release_buffer(void *user_data, struct wl_drm_buffer *buffer) 3256bf215546Sopenharmony_ci{ 3257bf215546Sopenharmony_ci _EGLDisplay *disp = user_data; 3258bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3259bf215546Sopenharmony_ci 3260bf215546Sopenharmony_ci dri2_dpy->image->destroyImage(buffer->driver_buffer); 3261bf215546Sopenharmony_ci} 3262bf215546Sopenharmony_ci 3263bf215546Sopenharmony_cistatic EGLBoolean 3264bf215546Sopenharmony_cidri2_bind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy) 3265bf215546Sopenharmony_ci{ 3266bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3267bf215546Sopenharmony_ci const struct wayland_drm_callbacks wl_drm_callbacks = { 3268bf215546Sopenharmony_ci .authenticate = (int(*)(void *, uint32_t)) dri2_dpy->vtbl->authenticate, 3269bf215546Sopenharmony_ci .reference_buffer = dri2_wl_reference_buffer, 3270bf215546Sopenharmony_ci .release_buffer = dri2_wl_release_buffer, 3271bf215546Sopenharmony_ci .is_format_supported = dri2_wl_is_format_supported 3272bf215546Sopenharmony_ci }; 3273bf215546Sopenharmony_ci int flags = 0; 3274bf215546Sopenharmony_ci char *device_name; 3275bf215546Sopenharmony_ci uint64_t cap; 3276bf215546Sopenharmony_ci 3277bf215546Sopenharmony_ci if (dri2_dpy->wl_server_drm) 3278bf215546Sopenharmony_ci return EGL_FALSE; 3279bf215546Sopenharmony_ci 3280bf215546Sopenharmony_ci device_name = drmGetRenderDeviceNameFromFd(dri2_dpy->fd); 3281bf215546Sopenharmony_ci if (!device_name) 3282bf215546Sopenharmony_ci device_name = strdup(dri2_dpy->device_name); 3283bf215546Sopenharmony_ci if (!device_name) 3284bf215546Sopenharmony_ci return EGL_FALSE; 3285bf215546Sopenharmony_ci 3286bf215546Sopenharmony_ci if (drmGetCap(dri2_dpy->fd, DRM_CAP_PRIME, &cap) == 0 && 3287bf215546Sopenharmony_ci cap == (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT) && 3288bf215546Sopenharmony_ci dri2_dpy->image->base.version >= 7 && 3289bf215546Sopenharmony_ci dri2_dpy->image->createImageFromFds != NULL) 3290bf215546Sopenharmony_ci flags |= WAYLAND_DRM_PRIME; 3291bf215546Sopenharmony_ci 3292bf215546Sopenharmony_ci dri2_dpy->wl_server_drm = 3293bf215546Sopenharmony_ci wayland_drm_init(wl_dpy, device_name, 3294bf215546Sopenharmony_ci &wl_drm_callbacks, disp, flags); 3295bf215546Sopenharmony_ci 3296bf215546Sopenharmony_ci free(device_name); 3297bf215546Sopenharmony_ci 3298bf215546Sopenharmony_ci if (!dri2_dpy->wl_server_drm) 3299bf215546Sopenharmony_ci return EGL_FALSE; 3300bf215546Sopenharmony_ci 3301bf215546Sopenharmony_ci#ifdef HAVE_DRM_PLATFORM 3302bf215546Sopenharmony_ci /* We have to share the wl_drm instance with gbm, so gbm can convert 3303bf215546Sopenharmony_ci * wl_buffers to gbm bos. */ 3304bf215546Sopenharmony_ci if (dri2_dpy->gbm_dri) 3305bf215546Sopenharmony_ci dri2_dpy->gbm_dri->wl_drm = dri2_dpy->wl_server_drm; 3306bf215546Sopenharmony_ci#endif 3307bf215546Sopenharmony_ci 3308bf215546Sopenharmony_ci return EGL_TRUE; 3309bf215546Sopenharmony_ci} 3310bf215546Sopenharmony_ci 3311bf215546Sopenharmony_cistatic EGLBoolean 3312bf215546Sopenharmony_cidri2_unbind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy) 3313bf215546Sopenharmony_ci{ 3314bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3315bf215546Sopenharmony_ci 3316bf215546Sopenharmony_ci if (!dri2_dpy->wl_server_drm) 3317bf215546Sopenharmony_ci return EGL_FALSE; 3318bf215546Sopenharmony_ci 3319bf215546Sopenharmony_ci wayland_drm_uninit(dri2_dpy->wl_server_drm); 3320bf215546Sopenharmony_ci dri2_dpy->wl_server_drm = NULL; 3321bf215546Sopenharmony_ci 3322bf215546Sopenharmony_ci return EGL_TRUE; 3323bf215546Sopenharmony_ci} 3324bf215546Sopenharmony_ci 3325bf215546Sopenharmony_cistatic EGLBoolean 3326bf215546Sopenharmony_cidri2_query_wayland_buffer_wl(_EGLDisplay *disp, struct wl_resource *buffer_resource, 3327bf215546Sopenharmony_ci EGLint attribute, EGLint *value) 3328bf215546Sopenharmony_ci{ 3329bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3330bf215546Sopenharmony_ci struct wl_drm_buffer *buffer; 3331bf215546Sopenharmony_ci const struct wl_drm_components_descriptor *format; 3332bf215546Sopenharmony_ci 3333bf215546Sopenharmony_ci buffer = wayland_drm_buffer_get(dri2_dpy->wl_server_drm, buffer_resource); 3334bf215546Sopenharmony_ci if (!buffer) 3335bf215546Sopenharmony_ci return EGL_FALSE; 3336bf215546Sopenharmony_ci 3337bf215546Sopenharmony_ci format = buffer->driver_format; 3338bf215546Sopenharmony_ci switch (attribute) { 3339bf215546Sopenharmony_ci case EGL_TEXTURE_FORMAT: 3340bf215546Sopenharmony_ci *value = format->components; 3341bf215546Sopenharmony_ci return EGL_TRUE; 3342bf215546Sopenharmony_ci case EGL_WIDTH: 3343bf215546Sopenharmony_ci *value = buffer->width; 3344bf215546Sopenharmony_ci return EGL_TRUE; 3345bf215546Sopenharmony_ci case EGL_HEIGHT: 3346bf215546Sopenharmony_ci *value = buffer->height; 3347bf215546Sopenharmony_ci return EGL_TRUE; 3348bf215546Sopenharmony_ci } 3349bf215546Sopenharmony_ci 3350bf215546Sopenharmony_ci return EGL_FALSE; 3351bf215546Sopenharmony_ci} 3352bf215546Sopenharmony_ci#endif 3353bf215546Sopenharmony_ci 3354bf215546Sopenharmony_cistatic void 3355bf215546Sopenharmony_cidri2_egl_ref_sync(struct dri2_egl_sync *sync) 3356bf215546Sopenharmony_ci{ 3357bf215546Sopenharmony_ci p_atomic_inc(&sync->refcount); 3358bf215546Sopenharmony_ci} 3359bf215546Sopenharmony_ci 3360bf215546Sopenharmony_cistatic void 3361bf215546Sopenharmony_cidri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy, 3362bf215546Sopenharmony_ci struct dri2_egl_sync *dri2_sync) 3363bf215546Sopenharmony_ci{ 3364bf215546Sopenharmony_ci if (p_atomic_dec_zero(&dri2_sync->refcount)) { 3365bf215546Sopenharmony_ci switch (dri2_sync->base.Type) { 3366bf215546Sopenharmony_ci case EGL_SYNC_REUSABLE_KHR: 3367bf215546Sopenharmony_ci cnd_destroy(&dri2_sync->cond); 3368bf215546Sopenharmony_ci break; 3369bf215546Sopenharmony_ci case EGL_SYNC_NATIVE_FENCE_ANDROID: 3370bf215546Sopenharmony_ci if (dri2_sync->base.SyncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID) 3371bf215546Sopenharmony_ci close(dri2_sync->base.SyncFd); 3372bf215546Sopenharmony_ci break; 3373bf215546Sopenharmony_ci default: 3374bf215546Sopenharmony_ci break; 3375bf215546Sopenharmony_ci } 3376bf215546Sopenharmony_ci 3377bf215546Sopenharmony_ci if (dri2_sync->fence) 3378bf215546Sopenharmony_ci dri2_dpy->fence->destroy_fence(dri2_dpy->dri_screen, dri2_sync->fence); 3379bf215546Sopenharmony_ci 3380bf215546Sopenharmony_ci free(dri2_sync); 3381bf215546Sopenharmony_ci } 3382bf215546Sopenharmony_ci} 3383bf215546Sopenharmony_ci 3384bf215546Sopenharmony_cistatic _EGLSync * 3385bf215546Sopenharmony_cidri2_create_sync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list) 3386bf215546Sopenharmony_ci{ 3387bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 3388bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3389bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 3390bf215546Sopenharmony_ci struct dri2_egl_sync *dri2_sync; 3391bf215546Sopenharmony_ci EGLint ret; 3392bf215546Sopenharmony_ci pthread_condattr_t attr; 3393bf215546Sopenharmony_ci 3394bf215546Sopenharmony_ci dri2_sync = calloc(1, sizeof(struct dri2_egl_sync)); 3395bf215546Sopenharmony_ci if (!dri2_sync) { 3396bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "eglCreateSyncKHR"); 3397bf215546Sopenharmony_ci return NULL; 3398bf215546Sopenharmony_ci } 3399bf215546Sopenharmony_ci 3400bf215546Sopenharmony_ci if (!_eglInitSync(&dri2_sync->base, disp, type, attrib_list)) { 3401bf215546Sopenharmony_ci free(dri2_sync); 3402bf215546Sopenharmony_ci return NULL; 3403bf215546Sopenharmony_ci } 3404bf215546Sopenharmony_ci 3405bf215546Sopenharmony_ci switch (type) { 3406bf215546Sopenharmony_ci case EGL_SYNC_FENCE_KHR: 3407bf215546Sopenharmony_ci dri2_sync->fence = dri2_dpy->fence->create_fence(dri2_ctx->dri_context); 3408bf215546Sopenharmony_ci if (!dri2_sync->fence) { 3409bf215546Sopenharmony_ci /* Why did it fail? DRI doesn't return an error code, so we emit 3410bf215546Sopenharmony_ci * a generic EGL error that doesn't communicate user error. 3411bf215546Sopenharmony_ci */ 3412bf215546Sopenharmony_ci _eglError(EGL_BAD_ALLOC, "eglCreateSyncKHR"); 3413bf215546Sopenharmony_ci free(dri2_sync); 3414bf215546Sopenharmony_ci return NULL; 3415bf215546Sopenharmony_ci } 3416bf215546Sopenharmony_ci break; 3417bf215546Sopenharmony_ci 3418bf215546Sopenharmony_ci case EGL_SYNC_CL_EVENT_KHR: 3419bf215546Sopenharmony_ci dri2_sync->fence = dri2_dpy->fence->get_fence_from_cl_event( 3420bf215546Sopenharmony_ci dri2_dpy->dri_screen, 3421bf215546Sopenharmony_ci dri2_sync->base.CLEvent); 3422bf215546Sopenharmony_ci /* this can only happen if the cl_event passed in is invalid. */ 3423bf215546Sopenharmony_ci if (!dri2_sync->fence) { 3424bf215546Sopenharmony_ci _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); 3425bf215546Sopenharmony_ci free(dri2_sync); 3426bf215546Sopenharmony_ci return NULL; 3427bf215546Sopenharmony_ci } 3428bf215546Sopenharmony_ci 3429bf215546Sopenharmony_ci /* the initial status must be "signaled" if the cl_event is signaled */ 3430bf215546Sopenharmony_ci if (dri2_dpy->fence->client_wait_sync(dri2_ctx->dri_context, 3431bf215546Sopenharmony_ci dri2_sync->fence, 0, 0)) 3432bf215546Sopenharmony_ci dri2_sync->base.SyncStatus = EGL_SIGNALED_KHR; 3433bf215546Sopenharmony_ci break; 3434bf215546Sopenharmony_ci 3435bf215546Sopenharmony_ci case EGL_SYNC_REUSABLE_KHR: 3436bf215546Sopenharmony_ci /* intialize attr */ 3437bf215546Sopenharmony_ci ret = pthread_condattr_init(&attr); 3438bf215546Sopenharmony_ci 3439bf215546Sopenharmony_ci if (ret) { 3440bf215546Sopenharmony_ci _eglError(EGL_BAD_ACCESS, "eglCreateSyncKHR"); 3441bf215546Sopenharmony_ci free(dri2_sync); 3442bf215546Sopenharmony_ci return NULL; 3443bf215546Sopenharmony_ci } 3444bf215546Sopenharmony_ci 3445bf215546Sopenharmony_ci /* change clock attribute to CLOCK_MONOTONIC */ 3446bf215546Sopenharmony_ci ret = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 3447bf215546Sopenharmony_ci 3448bf215546Sopenharmony_ci if (ret) { 3449bf215546Sopenharmony_ci _eglError(EGL_BAD_ACCESS, "eglCreateSyncKHR"); 3450bf215546Sopenharmony_ci free(dri2_sync); 3451bf215546Sopenharmony_ci return NULL; 3452bf215546Sopenharmony_ci } 3453bf215546Sopenharmony_ci 3454bf215546Sopenharmony_ci ret = pthread_cond_init(&dri2_sync->cond, &attr); 3455bf215546Sopenharmony_ci 3456bf215546Sopenharmony_ci if (ret) { 3457bf215546Sopenharmony_ci _eglError(EGL_BAD_ACCESS, "eglCreateSyncKHR"); 3458bf215546Sopenharmony_ci free(dri2_sync); 3459bf215546Sopenharmony_ci return NULL; 3460bf215546Sopenharmony_ci } 3461bf215546Sopenharmony_ci 3462bf215546Sopenharmony_ci /* initial status of reusable sync must be "unsignaled" */ 3463bf215546Sopenharmony_ci dri2_sync->base.SyncStatus = EGL_UNSIGNALED_KHR; 3464bf215546Sopenharmony_ci break; 3465bf215546Sopenharmony_ci 3466bf215546Sopenharmony_ci case EGL_SYNC_NATIVE_FENCE_ANDROID: 3467bf215546Sopenharmony_ci if (dri2_dpy->fence->create_fence_fd) { 3468bf215546Sopenharmony_ci dri2_sync->fence = dri2_dpy->fence->create_fence_fd( 3469bf215546Sopenharmony_ci dri2_ctx->dri_context, 3470bf215546Sopenharmony_ci dri2_sync->base.SyncFd); 3471bf215546Sopenharmony_ci } 3472bf215546Sopenharmony_ci if (!dri2_sync->fence) { 3473bf215546Sopenharmony_ci _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); 3474bf215546Sopenharmony_ci free(dri2_sync); 3475bf215546Sopenharmony_ci return NULL; 3476bf215546Sopenharmony_ci } 3477bf215546Sopenharmony_ci break; 3478bf215546Sopenharmony_ci } 3479bf215546Sopenharmony_ci 3480bf215546Sopenharmony_ci p_atomic_set(&dri2_sync->refcount, 1); 3481bf215546Sopenharmony_ci return &dri2_sync->base; 3482bf215546Sopenharmony_ci} 3483bf215546Sopenharmony_ci 3484bf215546Sopenharmony_cistatic EGLBoolean 3485bf215546Sopenharmony_cidri2_destroy_sync(_EGLDisplay *disp, _EGLSync *sync) 3486bf215546Sopenharmony_ci{ 3487bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3488bf215546Sopenharmony_ci struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); 3489bf215546Sopenharmony_ci EGLint ret = EGL_TRUE; 3490bf215546Sopenharmony_ci EGLint err; 3491bf215546Sopenharmony_ci 3492bf215546Sopenharmony_ci /* if type of sync is EGL_SYNC_REUSABLE_KHR and it is not signaled yet, 3493bf215546Sopenharmony_ci * then unlock all threads possibly blocked by the reusable sync before 3494bf215546Sopenharmony_ci * destroying it. 3495bf215546Sopenharmony_ci */ 3496bf215546Sopenharmony_ci if (dri2_sync->base.Type == EGL_SYNC_REUSABLE_KHR && 3497bf215546Sopenharmony_ci dri2_sync->base.SyncStatus == EGL_UNSIGNALED_KHR) { 3498bf215546Sopenharmony_ci dri2_sync->base.SyncStatus = EGL_SIGNALED_KHR; 3499bf215546Sopenharmony_ci /* unblock all threads currently blocked by sync */ 3500bf215546Sopenharmony_ci err = cnd_broadcast(&dri2_sync->cond); 3501bf215546Sopenharmony_ci 3502bf215546Sopenharmony_ci if (err) { 3503bf215546Sopenharmony_ci _eglError(EGL_BAD_ACCESS, "eglDestroySyncKHR"); 3504bf215546Sopenharmony_ci ret = EGL_FALSE; 3505bf215546Sopenharmony_ci } 3506bf215546Sopenharmony_ci } 3507bf215546Sopenharmony_ci 3508bf215546Sopenharmony_ci dri2_egl_unref_sync(dri2_dpy, dri2_sync); 3509bf215546Sopenharmony_ci 3510bf215546Sopenharmony_ci return ret; 3511bf215546Sopenharmony_ci} 3512bf215546Sopenharmony_ci 3513bf215546Sopenharmony_cistatic EGLint 3514bf215546Sopenharmony_cidri2_dup_native_fence_fd(_EGLDisplay *disp, _EGLSync *sync) 3515bf215546Sopenharmony_ci{ 3516bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3517bf215546Sopenharmony_ci struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); 3518bf215546Sopenharmony_ci 3519bf215546Sopenharmony_ci assert(sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID); 3520bf215546Sopenharmony_ci 3521bf215546Sopenharmony_ci if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3522bf215546Sopenharmony_ci /* try to retrieve the actual native fence fd.. if rendering is 3523bf215546Sopenharmony_ci * not flushed this will just return -1, aka NO_NATIVE_FENCE_FD: 3524bf215546Sopenharmony_ci */ 3525bf215546Sopenharmony_ci sync->SyncFd = dri2_dpy->fence->get_fence_fd(dri2_dpy->dri_screen, 3526bf215546Sopenharmony_ci dri2_sync->fence); 3527bf215546Sopenharmony_ci } 3528bf215546Sopenharmony_ci 3529bf215546Sopenharmony_ci if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 3530bf215546Sopenharmony_ci /* if native fence fd still not created, return an error: */ 3531bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, "eglDupNativeFenceFDANDROID"); 3532bf215546Sopenharmony_ci return EGL_NO_NATIVE_FENCE_FD_ANDROID; 3533bf215546Sopenharmony_ci } 3534bf215546Sopenharmony_ci 3535bf215546Sopenharmony_ci assert(sync_valid_fd(sync->SyncFd)); 3536bf215546Sopenharmony_ci 3537bf215546Sopenharmony_ci return os_dupfd_cloexec(sync->SyncFd); 3538bf215546Sopenharmony_ci} 3539bf215546Sopenharmony_ci 3540bf215546Sopenharmony_cistatic void 3541bf215546Sopenharmony_cidri2_set_blob_cache_funcs(_EGLDisplay *disp, 3542bf215546Sopenharmony_ci EGLSetBlobFuncANDROID set, 3543bf215546Sopenharmony_ci EGLGetBlobFuncANDROID get) 3544bf215546Sopenharmony_ci{ 3545bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3546bf215546Sopenharmony_ci dri2_dpy->blob->set_cache_funcs(dri2_dpy->dri_screen, 3547bf215546Sopenharmony_ci disp->BlobCacheSet, 3548bf215546Sopenharmony_ci disp->BlobCacheGet); 3549bf215546Sopenharmony_ci} 3550bf215546Sopenharmony_ci 3551bf215546Sopenharmony_cistatic EGLint 3552bf215546Sopenharmony_cidri2_client_wait_sync(_EGLDisplay *disp, _EGLSync *sync, 3553bf215546Sopenharmony_ci EGLint flags, EGLTime timeout) 3554bf215546Sopenharmony_ci{ 3555bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 3556bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3557bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 3558bf215546Sopenharmony_ci struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); 3559bf215546Sopenharmony_ci unsigned wait_flags = 0; 3560bf215546Sopenharmony_ci 3561bf215546Sopenharmony_ci EGLint ret = EGL_CONDITION_SATISFIED_KHR; 3562bf215546Sopenharmony_ci 3563bf215546Sopenharmony_ci /* The EGL_KHR_fence_sync spec states: 3564bf215546Sopenharmony_ci * 3565bf215546Sopenharmony_ci * "If no context is current for the bound API, 3566bf215546Sopenharmony_ci * the EGL_SYNC_FLUSH_COMMANDS_BIT_KHR bit is ignored. 3567bf215546Sopenharmony_ci */ 3568bf215546Sopenharmony_ci if (dri2_ctx && flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) 3569bf215546Sopenharmony_ci wait_flags |= __DRI2_FENCE_FLAG_FLUSH_COMMANDS; 3570bf215546Sopenharmony_ci 3571bf215546Sopenharmony_ci /* the sync object should take a reference while waiting */ 3572bf215546Sopenharmony_ci dri2_egl_ref_sync(dri2_sync); 3573bf215546Sopenharmony_ci 3574bf215546Sopenharmony_ci switch (sync->Type) { 3575bf215546Sopenharmony_ci case EGL_SYNC_FENCE_KHR: 3576bf215546Sopenharmony_ci case EGL_SYNC_NATIVE_FENCE_ANDROID: 3577bf215546Sopenharmony_ci case EGL_SYNC_CL_EVENT_KHR: 3578bf215546Sopenharmony_ci if (dri2_dpy->fence->client_wait_sync(dri2_ctx ? dri2_ctx->dri_context : NULL, 3579bf215546Sopenharmony_ci dri2_sync->fence, wait_flags, 3580bf215546Sopenharmony_ci timeout)) 3581bf215546Sopenharmony_ci dri2_sync->base.SyncStatus = EGL_SIGNALED_KHR; 3582bf215546Sopenharmony_ci else 3583bf215546Sopenharmony_ci ret = EGL_TIMEOUT_EXPIRED_KHR; 3584bf215546Sopenharmony_ci break; 3585bf215546Sopenharmony_ci 3586bf215546Sopenharmony_ci case EGL_SYNC_REUSABLE_KHR: 3587bf215546Sopenharmony_ci if (dri2_ctx && dri2_sync->base.SyncStatus == EGL_UNSIGNALED_KHR && 3588bf215546Sopenharmony_ci (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR)) { 3589bf215546Sopenharmony_ci /* flush context if EGL_SYNC_FLUSH_COMMANDS_BIT_KHR is set */ 3590bf215546Sopenharmony_ci dri2_gl_flush(); 3591bf215546Sopenharmony_ci } 3592bf215546Sopenharmony_ci 3593bf215546Sopenharmony_ci /* if timeout is EGL_FOREVER_KHR, it should wait without any timeout.*/ 3594bf215546Sopenharmony_ci if (timeout == EGL_FOREVER_KHR) { 3595bf215546Sopenharmony_ci mtx_lock(&dri2_sync->mutex); 3596bf215546Sopenharmony_ci cnd_wait(&dri2_sync->cond, &dri2_sync->mutex); 3597bf215546Sopenharmony_ci mtx_unlock(&dri2_sync->mutex); 3598bf215546Sopenharmony_ci } else { 3599bf215546Sopenharmony_ci /* if reusable sync has not been yet signaled */ 3600bf215546Sopenharmony_ci if (dri2_sync->base.SyncStatus != EGL_SIGNALED_KHR) { 3601bf215546Sopenharmony_ci /* timespecs for cnd_timedwait */ 3602bf215546Sopenharmony_ci struct timespec current; 3603bf215546Sopenharmony_ci struct timespec expire; 3604bf215546Sopenharmony_ci 3605bf215546Sopenharmony_ci /* We override the clock to monotonic when creating the condition 3606bf215546Sopenharmony_ci * variable. */ 3607bf215546Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, ¤t); 3608bf215546Sopenharmony_ci 3609bf215546Sopenharmony_ci /* calculating when to expire */ 3610bf215546Sopenharmony_ci expire.tv_nsec = timeout % 1000000000L; 3611bf215546Sopenharmony_ci expire.tv_sec = timeout / 1000000000L; 3612bf215546Sopenharmony_ci 3613bf215546Sopenharmony_ci expire.tv_nsec += current.tv_nsec; 3614bf215546Sopenharmony_ci expire.tv_sec += current.tv_sec; 3615bf215546Sopenharmony_ci 3616bf215546Sopenharmony_ci /* expire.nsec now is a number between 0 and 1999999998 */ 3617bf215546Sopenharmony_ci if (expire.tv_nsec > 999999999L) { 3618bf215546Sopenharmony_ci expire.tv_sec++; 3619bf215546Sopenharmony_ci expire.tv_nsec -= 1000000000L; 3620bf215546Sopenharmony_ci } 3621bf215546Sopenharmony_ci 3622bf215546Sopenharmony_ci mtx_lock(&dri2_sync->mutex); 3623bf215546Sopenharmony_ci ret = cnd_timedwait(&dri2_sync->cond, &dri2_sync->mutex, &expire); 3624bf215546Sopenharmony_ci mtx_unlock(&dri2_sync->mutex); 3625bf215546Sopenharmony_ci 3626bf215546Sopenharmony_ci if (ret == thrd_timedout) { 3627bf215546Sopenharmony_ci if (dri2_sync->base.SyncStatus == EGL_UNSIGNALED_KHR) { 3628bf215546Sopenharmony_ci ret = EGL_TIMEOUT_EXPIRED_KHR; 3629bf215546Sopenharmony_ci } else { 3630bf215546Sopenharmony_ci _eglError(EGL_BAD_ACCESS, "eglClientWaitSyncKHR"); 3631bf215546Sopenharmony_ci ret = EGL_FALSE; 3632bf215546Sopenharmony_ci } 3633bf215546Sopenharmony_ci } 3634bf215546Sopenharmony_ci } 3635bf215546Sopenharmony_ci } 3636bf215546Sopenharmony_ci break; 3637bf215546Sopenharmony_ci } 3638bf215546Sopenharmony_ci dri2_egl_unref_sync(dri2_dpy, dri2_sync); 3639bf215546Sopenharmony_ci 3640bf215546Sopenharmony_ci return ret; 3641bf215546Sopenharmony_ci} 3642bf215546Sopenharmony_ci 3643bf215546Sopenharmony_cistatic EGLBoolean 3644bf215546Sopenharmony_cidri2_signal_sync(_EGLDisplay *disp, _EGLSync *sync, EGLenum mode) 3645bf215546Sopenharmony_ci{ 3646bf215546Sopenharmony_ci struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); 3647bf215546Sopenharmony_ci EGLint ret; 3648bf215546Sopenharmony_ci 3649bf215546Sopenharmony_ci if (sync->Type != EGL_SYNC_REUSABLE_KHR) 3650bf215546Sopenharmony_ci return _eglError(EGL_BAD_MATCH, "eglSignalSyncKHR"); 3651bf215546Sopenharmony_ci 3652bf215546Sopenharmony_ci if (mode != EGL_SIGNALED_KHR && mode != EGL_UNSIGNALED_KHR) 3653bf215546Sopenharmony_ci return _eglError(EGL_BAD_ATTRIBUTE, "eglSignalSyncKHR"); 3654bf215546Sopenharmony_ci 3655bf215546Sopenharmony_ci dri2_sync->base.SyncStatus = mode; 3656bf215546Sopenharmony_ci 3657bf215546Sopenharmony_ci if (mode == EGL_SIGNALED_KHR) { 3658bf215546Sopenharmony_ci ret = cnd_broadcast(&dri2_sync->cond); 3659bf215546Sopenharmony_ci 3660bf215546Sopenharmony_ci /* fail to broadcast */ 3661bf215546Sopenharmony_ci if (ret) 3662bf215546Sopenharmony_ci return _eglError(EGL_BAD_ACCESS, "eglSignalSyncKHR"); 3663bf215546Sopenharmony_ci } 3664bf215546Sopenharmony_ci 3665bf215546Sopenharmony_ci return EGL_TRUE; 3666bf215546Sopenharmony_ci} 3667bf215546Sopenharmony_ci 3668bf215546Sopenharmony_cistatic EGLint 3669bf215546Sopenharmony_cidri2_server_wait_sync(_EGLDisplay *disp, _EGLSync *sync) 3670bf215546Sopenharmony_ci{ 3671bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 3672bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3673bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 3674bf215546Sopenharmony_ci struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); 3675bf215546Sopenharmony_ci 3676bf215546Sopenharmony_ci dri2_dpy->fence->server_wait_sync(dri2_ctx->dri_context, 3677bf215546Sopenharmony_ci dri2_sync->fence, 0); 3678bf215546Sopenharmony_ci return EGL_TRUE; 3679bf215546Sopenharmony_ci} 3680bf215546Sopenharmony_ci 3681bf215546Sopenharmony_cistatic int 3682bf215546Sopenharmony_cidri2_interop_query_device_info(_EGLDisplay *disp, _EGLContext *ctx, 3683bf215546Sopenharmony_ci struct mesa_glinterop_device_info *out) 3684bf215546Sopenharmony_ci{ 3685bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3686bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 3687bf215546Sopenharmony_ci 3688bf215546Sopenharmony_ci if (!dri2_dpy->interop) 3689bf215546Sopenharmony_ci return MESA_GLINTEROP_UNSUPPORTED; 3690bf215546Sopenharmony_ci 3691bf215546Sopenharmony_ci return dri2_dpy->interop->query_device_info(dri2_ctx->dri_context, out); 3692bf215546Sopenharmony_ci} 3693bf215546Sopenharmony_ci 3694bf215546Sopenharmony_cistatic int 3695bf215546Sopenharmony_cidri2_interop_export_object(_EGLDisplay *disp, _EGLContext *ctx, 3696bf215546Sopenharmony_ci struct mesa_glinterop_export_in *in, 3697bf215546Sopenharmony_ci struct mesa_glinterop_export_out *out) 3698bf215546Sopenharmony_ci{ 3699bf215546Sopenharmony_ci struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 3700bf215546Sopenharmony_ci struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 3701bf215546Sopenharmony_ci 3702bf215546Sopenharmony_ci if (!dri2_dpy->interop) 3703bf215546Sopenharmony_ci return MESA_GLINTEROP_UNSUPPORTED; 3704bf215546Sopenharmony_ci 3705bf215546Sopenharmony_ci return dri2_dpy->interop->export_object(dri2_ctx->dri_context, in, out); 3706bf215546Sopenharmony_ci} 3707bf215546Sopenharmony_ci 3708bf215546Sopenharmony_ciconst _EGLDriver _eglDriver = { 3709bf215546Sopenharmony_ci .Initialize = dri2_initialize, 3710bf215546Sopenharmony_ci .Terminate = dri2_terminate, 3711bf215546Sopenharmony_ci .CreateContext = dri2_create_context, 3712bf215546Sopenharmony_ci .DestroyContext = dri2_destroy_context, 3713bf215546Sopenharmony_ci .MakeCurrent = dri2_make_current, 3714bf215546Sopenharmony_ci .CreateWindowSurface = dri2_create_window_surface, 3715bf215546Sopenharmony_ci .CreatePixmapSurface = dri2_create_pixmap_surface, 3716bf215546Sopenharmony_ci .CreatePbufferSurface = dri2_create_pbuffer_surface, 3717bf215546Sopenharmony_ci .DestroySurface = dri2_destroy_surface, 3718bf215546Sopenharmony_ci .GetProcAddress = dri2_get_proc_address, 3719bf215546Sopenharmony_ci .WaitClient = dri2_wait_client, 3720bf215546Sopenharmony_ci .WaitNative = dri2_wait_native, 3721bf215546Sopenharmony_ci .BindTexImage = dri2_bind_tex_image, 3722bf215546Sopenharmony_ci .ReleaseTexImage = dri2_release_tex_image, 3723bf215546Sopenharmony_ci .SwapInterval = dri2_swap_interval, 3724bf215546Sopenharmony_ci .SwapBuffers = dri2_swap_buffers, 3725bf215546Sopenharmony_ci .SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage, 3726bf215546Sopenharmony_ci .SwapBuffersRegionNOK = dri2_swap_buffers_region, 3727bf215546Sopenharmony_ci .SetDamageRegion = dri2_set_damage_region, 3728bf215546Sopenharmony_ci .PostSubBufferNV = dri2_post_sub_buffer, 3729bf215546Sopenharmony_ci .CopyBuffers = dri2_copy_buffers, 3730bf215546Sopenharmony_ci .QueryBufferAge = dri2_query_buffer_age, 3731bf215546Sopenharmony_ci .CreateImageKHR = dri2_create_image, 3732bf215546Sopenharmony_ci .DestroyImageKHR = dri2_destroy_image_khr, 3733bf215546Sopenharmony_ci .CreateWaylandBufferFromImageWL = dri2_create_wayland_buffer_from_image, 3734bf215546Sopenharmony_ci .QuerySurface = dri2_query_surface, 3735bf215546Sopenharmony_ci .QueryDriverName = dri2_query_driver_name, 3736bf215546Sopenharmony_ci .QueryDriverConfig = dri2_query_driver_config, 3737bf215546Sopenharmony_ci#ifdef HAVE_LIBDRM 3738bf215546Sopenharmony_ci .CreateDRMImageMESA = dri2_create_drm_image_mesa, 3739bf215546Sopenharmony_ci .ExportDRMImageMESA = dri2_export_drm_image_mesa, 3740bf215546Sopenharmony_ci .ExportDMABUFImageQueryMESA = dri2_export_dma_buf_image_query_mesa, 3741bf215546Sopenharmony_ci .ExportDMABUFImageMESA = dri2_export_dma_buf_image_mesa, 3742bf215546Sopenharmony_ci .QueryDmaBufFormatsEXT = dri2_query_dma_buf_formats, 3743bf215546Sopenharmony_ci .QueryDmaBufModifiersEXT = dri2_query_dma_buf_modifiers, 3744bf215546Sopenharmony_ci#endif 3745bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 3746bf215546Sopenharmony_ci .BindWaylandDisplayWL = dri2_bind_wayland_display_wl, 3747bf215546Sopenharmony_ci .UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl, 3748bf215546Sopenharmony_ci .QueryWaylandBufferWL = dri2_query_wayland_buffer_wl, 3749bf215546Sopenharmony_ci#endif 3750bf215546Sopenharmony_ci .GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium, 3751bf215546Sopenharmony_ci .CreateSyncKHR = dri2_create_sync, 3752bf215546Sopenharmony_ci .ClientWaitSyncKHR = dri2_client_wait_sync, 3753bf215546Sopenharmony_ci .SignalSyncKHR = dri2_signal_sync, 3754bf215546Sopenharmony_ci .WaitSyncKHR = dri2_server_wait_sync, 3755bf215546Sopenharmony_ci .DestroySyncKHR = dri2_destroy_sync, 3756bf215546Sopenharmony_ci .GLInteropQueryDeviceInfo = dri2_interop_query_device_info, 3757bf215546Sopenharmony_ci .GLInteropExportObject = dri2_interop_export_object, 3758bf215546Sopenharmony_ci .DupNativeFenceFDANDROID = dri2_dup_native_fence_fd, 3759bf215546Sopenharmony_ci .SetBlobCacheFuncsANDROID = dri2_set_blob_cache_funcs, 3760bf215546Sopenharmony_ci}; 3761