egl_dri2.c revision 00978098794f723230a33cab1c1152686f1c4fa5
1b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek/* 277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Copyright © 2010 Intel Corporation 377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * 477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Permission is hereby granted, free of charge, to any person obtaining a 577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * copy of this software and associated documentation files (the "Software"), 677349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * to deal in the Software without restriction, including without limitation 777349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * the rights to use, copy, modify, merge, publish, distribute, sublicense, 877349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * and/or sell copies of the Software, and to permit persons to whom the 977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Software is furnished to do so, subject to the following conditions: 10b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek * 11b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek * The above copyright notice and this permission notice (including the next 12b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek * paragraph) shall be included in all copies or substantial portions of the 1377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Software. 1477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * 1577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 1977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * DEALINGS IN THE SOFTWARE. 2377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * 24b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek * Authors: 2577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Kristian Høgsberg <krh@bitplanet.net> 2699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek */ 2799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 28b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek#include <stdlib.h> 29b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek#include <string.h> 30b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek#include <stdio.h> 31e5f4dcb6bd73a10df6eb6c3cfe057c88cb2362ccTed Kremenek#include <limits.h> 32b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek#include <dlfcn.h> 33aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek#include <fcntl.h> 34b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek#include <errno.h> 35b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek#include <unistd.h> 36f116bd654bcdb5d7c22656f224deeb7a67f7d0cdTed Kremenek#include <xf86drm.h> 37aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek#include <GL/gl.h> 38aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek#include <GL/internal/dri_interface.h> 39aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek#include <sys/types.h> 40330dddd19406f9cc227e59e0bb0a36ecdc52915eTed Kremenek#include <sys/stat.h> 4199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 4277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek#include "egl_dri2.h" 43b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 44b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekconst __DRIuseInvalidateExtension use_invalidate = { 45b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek { __DRI_USE_INVALIDATE, 1 } 46b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek}; 47b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 48b387a3f23e423d62c053be86294b703da1d1a222Ted KremenekEGLint dri2_to_egl_attribute_map[] = { 49b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, 50b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */ 51b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_LEVEL, /* __DRI_ATTRIB_LEVEL */ 52b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_RED_SIZE, /* __DRI_ATTRIB_RED_SIZE */ 53b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_GREEN_SIZE, /* __DRI_ATTRIB_GREEN_SIZE */ 54b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_BLUE_SIZE, /* __DRI_ATTRIB_BLUE_SIZE */ 55b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_LUMINANCE_SIZE, /* __DRI_ATTRIB_LUMINANCE_SIZE */ 56b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_ALPHA_SIZE, /* __DRI_ATTRIB_ALPHA_SIZE */ 57b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_ALPHA_MASK_SIZE */ 58aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek EGL_DEPTH_SIZE, /* __DRI_ATTRIB_DEPTH_SIZE */ 59240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek EGL_STENCIL_SIZE, /* __DRI_ATTRIB_STENCIL_SIZE */ 60b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_ACCUM_RED_SIZE */ 61b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_ACCUM_GREEN_SIZE */ 62aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 0, /* __DRI_ATTRIB_ACCUM_BLUE_SIZE */ 63b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_ACCUM_ALPHA_SIZE */ 64b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_SAMPLE_BUFFERS, /* __DRI_ATTRIB_SAMPLE_BUFFERS */ 65b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek EGL_SAMPLES, /* __DRI_ATTRIB_SAMPLES */ 66b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_RENDER_TYPE, */ 67b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_CONFIG_CAVEAT */ 68b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_CONFORMANT */ 69b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_DOUBLE_BUFFER */ 70b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_STEREO */ 710d093d3005dd583675a45a85bd688063572cc8afTed Kremenek 0, /* __DRI_ATTRIB_AUX_BUFFERS */ 720d093d3005dd583675a45a85bd688063572cc8afTed Kremenek 0, /* __DRI_ATTRIB_TRANSPARENT_TYPE */ 730d093d3005dd583675a45a85bd688063572cc8afTed Kremenek 0, /* __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE */ 740d093d3005dd583675a45a85bd688063572cc8afTed Kremenek 0, /* __DRI_ATTRIB_TRANSPARENT_RED_VALUE */ 75b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE */ 76b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 0, /* __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE */ 7799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 0, /* __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE */ 7899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 0, /* __DRI_ATTRIB_FLOAT_MODE */ 7999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 0, /* __DRI_ATTRIB_RED_MASK */ 8099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 0, /* __DRI_ATTRIB_GREEN_MASK */ 8199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 0, /* __DRI_ATTRIB_BLUE_MASK */ 8299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 0, /* __DRI_ATTRIB_ALPHA_MASK */ 83affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek EGL_MAX_PBUFFER_WIDTH, /* __DRI_ATTRIB_MAX_PBUFFER_WIDTH */ 844a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek EGL_MAX_PBUFFER_HEIGHT, /* __DRI_ATTRIB_MAX_PBUFFER_HEIGHT */ 854a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek EGL_MAX_PBUFFER_PIXELS, /* __DRI_ATTRIB_MAX_PBUFFER_PIXELS */ 86affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH */ 875e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT */ 8823a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek 0, /* __DRI_ATTRIB_VISUAL_SELECT_GROUP */ 891e80aa49ec689d1937e54fb353d6626e0a58f0dbTed Kremenek 0, /* __DRI_ATTRIB_SWAP_METHOD */ 90affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek EGL_MAX_SWAP_INTERVAL, /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */ 91affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek EGL_MIN_SWAP_INTERVAL, /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */ 9202737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */ 9302737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */ 948cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek 0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */ 9502737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */ 9602737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */ 9702737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek 0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */ 98b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek}; 994a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek 1004a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenekstatic EGLBoolean 1014a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenekdri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) 102b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek{ 1034a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (_eglCompareConfigs(conf, criteria, NULL, EGL_FALSE) != 0) 1044a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek return EGL_FALSE; 1054a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek 1069dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek if (!_eglMatchConfig(conf, criteria)) 107affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek return EGL_FALSE; 108affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek 109affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek return EGL_TRUE; 110affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek} 111b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 11207d83aa220567bef263ef76cfc9b0159320bb640Ted Kremenekstruct dri2_egl_config * 113b5339121f63f2754d4f26e8f3a092caf9f7d9290Ted Kremenekdri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, 11407d83aa220567bef263ef76cfc9b0159320bb640Ted Kremenek int depth, EGLint surface_type, const EGLint *attr_list, 11507d83aa220567bef263ef76cfc9b0159320bb640Ted Kremenek const unsigned int *rgba_masks) 11607d83aa220567bef263ef76cfc9b0159320bb640Ted Kremenek{ 117b5339121f63f2754d4f26e8f3a092caf9f7d9290Ted Kremenek struct dri2_egl_config *conf; 11807d83aa220567bef263ef76cfc9b0159320bb640Ted Kremenek struct dri2_egl_display *dri2_dpy; 11907d83aa220567bef263ef76cfc9b0159320bb640Ted Kremenek _EGLConfig base; 1204a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek unsigned int attrib, value, double_buffer; 1214a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; 12207d83aa220567bef263ef76cfc9b0159320bb640Ted Kremenek unsigned int dri_masks[4] = { 0, 0, 0, 0 }; 1234d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek _EGLConfig *matching_config; 1244d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek EGLint num_configs = 0; 1254d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek EGLint config_id; 1264d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek int i; 1274d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 1284d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek dri2_dpy = disp->DriverData; 1294d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek _eglInitConfig(&base, disp, id); 1304d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 1314d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek i = 0; 132b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek double_buffer = 0; 1338cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek bind_to_texture_rgb = 0; 1348cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek bind_to_texture_rgba = 0; 1358cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek 1368cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { 1375e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek switch (attrib) { 1385e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek case __DRI_ATTRIB_RENDER_TYPE: 1395e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek if (value & __DRI_ATTRIB_RGBA_BIT) 1405e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek value = EGL_RGB_BUFFER; 14123a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek else if (value & __DRI_ATTRIB_LUMINANCE_BIT) 14223a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek value = EGL_LUMINANCE_BUFFER; 14323a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek else 14423a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek /* not valid */; 1452ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value); 1462ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek break; 1472ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek 1482ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek case __DRI_ATTRIB_CONFIG_CAVEAT: 14923a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) 15023a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek value = EGL_NON_CONFORMANT_CONFIG; 15123a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek else if (value & __DRI_ATTRIB_SLOW_BIT) 15223a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek value = EGL_SLOW_CONFIG; 15323a4f917cd8d1090be7c96c4eda8643086f64d36Ted Kremenek else 154b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek value = EGL_NONE; 155b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value); 1567cb15939e08ea31f0fadcd24c974dbc9e4b61c01Ted Kremenek break; 1570d093d3005dd583675a45a85bd688063572cc8afTed Kremenek 1580d093d3005dd583675a45a85bd688063572cc8afTed Kremenek case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: 1590d093d3005dd583675a45a85bd688063572cc8afTed Kremenek bind_to_texture_rgb = value; 1600d093d3005dd583675a45a85bd688063572cc8afTed Kremenek break; 1610d093d3005dd583675a45a85bd688063572cc8afTed Kremenek 1620d093d3005dd583675a45a85bd688063572cc8afTed Kremenek case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: 163b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek bind_to_texture_rgba = value; 164b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek break; 165b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 166b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek case __DRI_ATTRIB_DOUBLE_BUFFER: 167b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek double_buffer = value; 168b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek break; 169b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 170b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek case __DRI_ATTRIB_RED_MASK: 171b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek dri_masks[0] = value; 172b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek break; 173b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 174b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek case __DRI_ATTRIB_GREEN_MASK: 175b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek dri_masks[1] = value; 176b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek break; 177b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 178b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek case __DRI_ATTRIB_BLUE_MASK: 179e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek dri_masks[2] = value; 180e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek break; 181ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek 182e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek case __DRI_ATTRIB_ALPHA_MASK: 183493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek dri_masks[3] = value; 184493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek break; 185b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 186b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek default: 187aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek key = dri2_to_egl_attribute_map[attrib]; 188b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (key != 0) 18902737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek _eglSetConfigKey(&base, key, value); 19002737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek break; 19102737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek } 19202737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek } 1934a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek 1944a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (attr_list) 195b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek for (i = 0; attr_list[i] != EGL_NONE; i += 2) 196b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]); 1974a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek 1984a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (depth > 0 && depth != base.BufferSize) 1999dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek return NULL; 2009dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek 201b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (rgba_masks && memcmp(rgba_masks, dri_masks, sizeof(dri_masks))) 202b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek return NULL; 203b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 204b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek base.NativeRenderable = EGL_TRUE; 205b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 206b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek base.SurfaceType = surface_type; 207b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (surface_type & (EGL_PBUFFER_BIT | 208b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) { 2094a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek base.BindToTextureRGB = bind_to_texture_rgb; 2104a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (base.AlphaSize > 0) 211b5339121f63f2754d4f26e8f3a092caf9f7d9290Ted Kremenek base.BindToTextureRGBA = bind_to_texture_rgba; 212b5339121f63f2754d4f26e8f3a092caf9f7d9290Ted Kremenek } 2134d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 2144d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek base.RenderableType = disp->ClientAPIs; 2154d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek base.Conformant = disp->ClientAPIs; 2164d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 2174d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek if (!_eglValidateConfig(&base, EGL_FALSE)) { 2184d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); 219d763eb91aab5bdecd11825fadb35d6d8cc905f63Ted Kremenek return NULL; 220d763eb91aab5bdecd11825fadb35d6d8cc905f63Ted Kremenek } 221affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek 222affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek config_id = base.ConfigID; 223affb2159712b2373a18a89ed205c1a309d3aec12Ted Kremenek base.ConfigID = EGL_DONT_CARE; 2248cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek base.SurfaceType = EGL_DONT_CARE; 2258cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1, 2268cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek (_EGLArrayForEach) dri2_match_config, &base); 2278cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek 2288cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (num_configs == 1) { 2295e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek conf = (struct dri2_egl_config *) matching_config; 2305e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek 2315e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek if (double_buffer && !conf->dri_double_config) 2325e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek conf->dri_double_config = dri_config; 2332ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek else if (!double_buffer && !conf->dri_single_config) 2341e80aa49ec689d1937e54fb353d6626e0a58f0dbTed Kremenek conf->dri_single_config = dri_config; 235dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek else 236dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek /* a similar config type is already added (unlikely) => discard */ 237dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek return NULL; 238dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek } 239dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek else if (num_configs == 0) { 240dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek conf = malloc(sizeof *conf); 2412ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek if (conf == NULL) 2422ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek return NULL; 24302737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek 24402737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek memcpy(&conf->base, &base, sizeof base); 24502737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek if (double_buffer) { 24602737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek conf->dri_double_config = dri_config; 2471b9df4c307b650526344ba0a28534268f6920745Ted Kremenek conf->dri_single_config = NULL; 2481b9df4c307b650526344ba0a28534268f6920745Ted Kremenek } else { 2491b9df4c307b650526344ba0a28534268f6920745Ted Kremenek conf->dri_single_config = dri_config; 2501b9df4c307b650526344ba0a28534268f6920745Ted Kremenek conf->dri_double_config = NULL; 251d87a321a3c3902f7acfc6539b8946a00da6e45ccTed Kremenek } 252d87a321a3c3902f7acfc6539b8946a00da6e45ccTed Kremenek conf->base.SurfaceType = 0; 253d87a321a3c3902f7acfc6539b8946a00da6e45ccTed Kremenek conf->base.ConfigID = config_id; 254d87a321a3c3902f7acfc6539b8946a00da6e45ccTed Kremenek 2554a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek _eglLinkConfig(&conf->base); 2564a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek } 2574a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek else { 258d87a321a3c3902f7acfc6539b8946a00da6e45ccTed Kremenek assert(0); 259d87a321a3c3902f7acfc6539b8946a00da6e45ccTed Kremenek return NULL; 2604d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek } 2614d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 2624d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek if (double_buffer) { 2634d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek surface_type &= ~EGL_PIXMAP_BIT; 2644d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 2654d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek if (dri2_dpy->swap_available) { 2664d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek conf->base.MinSwapInterval = 0; 2674d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek conf->base.MaxSwapInterval = 1000; /* XXX arbitrary value */ 2684d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek } 2694d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek } 2704d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 2714d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek conf->base.SurfaceType |= surface_type; 2724d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 2734d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek return conf; 2744d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek} 2754d839b4949efe9e2b16eeab679c25b28e31ea742Ted Kremenek 276b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek__DRIimage * 2778cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenekdri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) 2788cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek{ 2798cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek _EGLDisplay *disp = data; 2805e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek struct dri2_egl_image *dri2_img; 2815e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek _EGLImage *img; 2825e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek 2835e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek (void) screen; 2848cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek 2852ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek img = _eglLookupImage(image, disp); 2862ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek if (img == NULL) { 2872ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek _eglError(EGL_BAD_PARAMETER, "dri2_lookup_egl_image"); 2882ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek return NULL; 289dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek } 290dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek 291dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek dri2_img = dri2_egl_image(image); 292dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek 293dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek return dri2_img->dri_image; 294dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek} 295dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek 296dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenekconst __DRIimageLookupExtension image_lookup_extension = { 297dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek { __DRI_IMAGE_LOOKUP, 1 }, 298dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek dri2_lookup_egl_image 299dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek}; 300dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek 301dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenekstatic const char dri_driver_path[] = DEFAULT_DRIVER_DIR; 302dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek 303dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenekstruct dri2_extension_match { 304dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek const char *name; 305dbfe41acda3078f8fe566318c0097f7ae683c6bbTed Kremenek int version; 30699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek int offset; 30799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek}; 30899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 30999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekstatic struct dri2_extension_match dri2_driver_extensions[] = { 31099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, 31199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { __DRI_DRI2, 2, offsetof(struct dri2_egl_display, dri2) }, 31299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { NULL, 0, 0 } 31399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek}; 31499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 31599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekstatic struct dri2_extension_match dri2_core_extensions[] = { 31699c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) }, 31799c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, 31899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) }, 31999c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { NULL, 0, 0 } 32099c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek}; 32199c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek 32299c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenekstatic struct dri2_extension_match swrast_driver_extensions[] = { 32399c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, 32499c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { __DRI_SWRAST, 2, offsetof(struct dri2_egl_display, swrast) }, 32599c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek { NULL, 0, 0 } 326b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek}; 3276a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenek 328b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekstatic struct dri2_extension_match swrast_core_extensions[] = { 329b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, 3306a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenek { NULL, 0, 0 } 3316a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenek}; 3326a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenek 3336a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenekstatic EGLBoolean 3346a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenekdri2_bind_extensions(struct dri2_egl_display *dri2_dpy, 335b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek struct dri2_extension_match *matches, 336b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek const __DRIextension **extensions) 337b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek{ 338b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek int i, j, ret = EGL_TRUE; 339b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek void *field; 340b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 341b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek for (i = 0; extensions[i]; i++) { 342b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name); 343b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek for (j = 0; matches[j].name; j++) { 344b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (strcmp(extensions[i]->name, matches[j].name) == 0 && 34505a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek extensions[i]->version >= matches[j].version) { 34605a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek field = ((char *) dri2_dpy + matches[j].offset); 34700a3a5f024ac54088ab887712b292171188064f0Ted Kremenek *(const __DRIextension **) field = extensions[i]; 34800a3a5f024ac54088ab887712b292171188064f0Ted Kremenek _eglLog(_EGL_INFO, "DRI2: found extension %s version %d", 34900a3a5f024ac54088ab887712b292171188064f0Ted Kremenek extensions[i]->name, extensions[i]->version); 35000a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 35100a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 35200a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 35300a3a5f024ac54088ab887712b292171188064f0Ted Kremenek 35400a3a5f024ac54088ab887712b292171188064f0Ted Kremenek for (j = 0; matches[j].name; j++) { 35500a3a5f024ac54088ab887712b292171188064f0Ted Kremenek field = ((char *) dri2_dpy + matches[j].offset); 35600a3a5f024ac54088ab887712b292171188064f0Ted Kremenek if (*(const __DRIextension **) field == NULL) { 35705a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek _eglLog(_EGL_FATAL, "DRI2: did not find extension %s version %d", 358b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek matches[j].name, matches[j].version); 3590d093d3005dd583675a45a85bd688063572cc8afTed Kremenek ret = EGL_FALSE; 3600d093d3005dd583675a45a85bd688063572cc8afTed Kremenek } 361512c913a6f93d225faacdb8e20308f5c4065c3ebTed Kremenek } 362b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 363aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek return ret; 364b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek} 365aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek 366aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekstatic const __DRIextension ** 367b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekdri2_open_driver(_EGLDisplay *disp) 36805a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek{ 3690d093d3005dd583675a45a85bd688063572cc8afTed Kremenek struct dri2_egl_display *dri2_dpy = disp->DriverData; 3700d093d3005dd583675a45a85bd688063572cc8afTed Kremenek const __DRIextension **extensions; 3710d093d3005dd583675a45a85bd688063572cc8afTed Kremenek char path[PATH_MAX], *search_paths, *p, *next, *end; 372b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 3730d093d3005dd583675a45a85bd688063572cc8afTed Kremenek search_paths = NULL; 3740d093d3005dd583675a45a85bd688063572cc8afTed Kremenek if (geteuid() == getuid()) { 3750d093d3005dd583675a45a85bd688063572cc8afTed Kremenek /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ 376b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek search_paths = getenv("LIBGL_DRIVERS_PATH"); 377aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek } 378aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek if (search_paths == NULL) 379b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek search_paths = DEFAULT_DRIVER_DIR; 38005a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek 381aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek dri2_dpy->driver = NULL; 382aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek end = search_paths + strlen(search_paths); 383b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) { 384b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek int len; 385aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek next = strchr(p, ':'); 38605a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek if (next == NULL) 38705a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek next = end; 38877349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek 389aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek len = next - p; 390aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek#if GLX_USE_TLS 391b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek snprintf(path, sizeof path, 392b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek "%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name); 393aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); 394aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek#endif 395b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (dri2_dpy->driver == NULL) { 396b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek snprintf(path, sizeof path, 397aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek "%.*s/%s_dri.so", len, p, dri2_dpy->driver_name); 398240f1f00dda1d481276ea872fe8f8851581a7e6bTed Kremenek dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); 399b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (dri2_dpy->driver == NULL) 400b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror()); 401b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek } 402b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek } 403aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek 404aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek if (dri2_dpy->driver == NULL) { 405aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek _eglLog(_EGL_WARNING, 406aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek "DRI2: failed to open %s (search paths %s)", 407aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek dri2_dpy->driver_name, search_paths); 408aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return NULL; 409aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 410aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 411aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); 412aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS); 413b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (extensions == NULL) { 414aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek _eglLog(_EGL_WARNING, 415b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek "DRI2: driver exports no extensions (%s)", dlerror()); 416b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek dlclose(dri2_dpy->driver); 417aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek } 418aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek 419aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek return extensions; 420aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek} 421aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek 422b387a3f23e423d62c053be86294b703da1d1a222Ted KremenekEGLBoolean 423aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenekdri2_load_driver(_EGLDisplay *disp) 424aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek{ 425b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek struct dri2_egl_display *dri2_dpy = disp->DriverData; 426aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek const __DRIextension **extensions; 427aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek 428b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek extensions = dri2_open_driver(disp); 429aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek if (!extensions) 430aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek return EGL_FALSE; 431b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 4320e561a3e6755c4f248a8bb05d49071ddf4f2ef7bTed Kremenek if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) { 4335c684c4be01fb98077a9b5e07ca1fdc01d8d97cbTed Kremenek dlclose(dri2_dpy->driver); 4340e561a3e6755c4f248a8bb05d49071ddf4f2ef7bTed Kremenek return EGL_FALSE; 4355c684c4be01fb98077a9b5e07ca1fdc01d8d97cbTed Kremenek } 436b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 4374a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek return EGL_TRUE; 4384a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek} 4394a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek 4409dca062461a6244cf0f733346657fa3eee853f9bTed KremenekEGLBoolean 441b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekdri2_load_driver_swrast(_EGLDisplay *disp) 442b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek{ 443b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek struct dri2_egl_display *dri2_dpy = disp->DriverData; 444b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek const __DRIextension **extensions; 445ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek 446ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek dri2_dpy->driver_name = "swrast"; 447ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek extensions = dri2_open_driver(disp); 448ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek 449ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek if (!extensions) 450ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek return EGL_FALSE; 451ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek 452ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions)) { 453ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek dlclose(dri2_dpy->driver); 454ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek return EGL_FALSE; 455ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek } 456ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek 457ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek return EGL_TRUE; 458b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek} 459b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 460b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekvoid 461aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekdri2_setup_screen(_EGLDisplay *disp) 462b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek{ 463de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 464de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek unsigned int api_mask; 465aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 466de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek if (dri2_dpy->dri2) { 467de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen); 46855deb97341819080d6d127d29e25b9502e4f2e3cTed Kremenek } else { 46955deb97341819080d6d127d29e25b9502e4f2e3cTed Kremenek assert(dri2_dpy->swrast); 47055deb97341819080d6d127d29e25b9502e4f2e3cTed Kremenek api_mask = 1 << __DRI_API_OPENGL | 1 << __DRI_API_GLES | 1 << __DRI_API_GLES2; 471b9308372e0d40c85cb573c4982fdf5089d89ab6dTed Kremenek } 472b9308372e0d40c85cb573c4982fdf5089d89ab6dTed Kremenek 473b9308372e0d40c85cb573c4982fdf5089d89ab6dTed Kremenek disp->ClientAPIs = 0; 474b9308372e0d40c85cb573c4982fdf5089d89ab6dTed Kremenek if (api_mask & (1 <<__DRI_API_OPENGL)) 475b9308372e0d40c85cb573c4982fdf5089d89ab6dTed Kremenek disp->ClientAPIs |= EGL_OPENGL_BIT; 476b9308372e0d40c85cb573c4982fdf5089d89ab6dTed Kremenek if (api_mask & (1 <<__DRI_API_GLES)) 477b9308372e0d40c85cb573c4982fdf5089d89ab6dTed Kremenek disp->ClientAPIs |= EGL_OPENGL_ES_BIT; 47855deb97341819080d6d127d29e25b9502e4f2e3cTed Kremenek if (api_mask & (1 << __DRI_API_GLES2)) 479b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek disp->ClientAPIs |= EGL_OPENGL_ES2_BIT; 480aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 481b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek assert(dri2_dpy->dri2 || dri2_dpy->swrast); 482b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek disp->Extensions.KHR_surfaceless_context = EGL_TRUE; 483b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 484b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) { 485b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek disp->Extensions.KHR_create_context = EGL_TRUE; 486b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 487b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (dri2_dpy->robustness) 488b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek disp->Extensions.EXT_create_context_robustness = EGL_TRUE; 489aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 490b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 491b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (dri2_dpy->image) { 492b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek disp->Extensions.MESA_drm_image = EGL_TRUE; 493b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek disp->Extensions.KHR_image_base = EGL_TRUE; 49402737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; 49502737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek } 49602737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek} 497b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 498aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted KremenekEGLBoolean 499b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekdri2_create_screen(_EGLDisplay *disp) 500b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek{ 501aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const __DRIextension **extensions; 502aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek struct dri2_egl_display *dri2_dpy; 503aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 504b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek dri2_dpy = disp->DriverData; 505b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 506b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek if (dri2_dpy->dri2) { 507ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek dri2_dpy->dri_screen = 508ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, 509d8e9f0dc737133d4e8342f39389064620f5a7f8fTed Kremenek &dri2_dpy->driver_configs, disp); 5109ef1ec98a8fc17e7560e07641184bc4daee39b46Ted Kremenek } else { 5114a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek assert(dri2_dpy->swrast); 5129ef1ec98a8fc17e7560e07641184bc4daee39b46Ted Kremenek dri2_dpy->dri_screen = 5139ef1ec98a8fc17e7560e07641184bc4daee39b46Ted Kremenek dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, 5149ef1ec98a8fc17e7560e07641184bc4daee39b46Ted Kremenek &dri2_dpy->driver_configs, disp); 51500a3a5f024ac54088ab887712b292171188064f0Ted Kremenek } 5169ef1ec98a8fc17e7560e07641184bc4daee39b46Ted Kremenek 51700a3a5f024ac54088ab887712b292171188064f0Ted Kremenek if (dri2_dpy->dri_screen == NULL) { 518b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); 519b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek return EGL_FALSE; 520aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 52100a3a5f024ac54088ab887712b292171188064f0Ted Kremenek 522b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek dri2_dpy->own_dri_screen = 1; 523b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 524aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); 52500a3a5f024ac54088ab887712b292171188064f0Ted Kremenek 52690e420321f60860f4c4e7a68ca9f7567824b46ecTed Kremenek if (dri2_dpy->dri2) { 52710c16657eec144def180ee53d1e0249c9ed2b3b5Ted Kremenek unsigned i; 528aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 52900a3a5f024ac54088ab887712b292171188064f0Ted Kremenek if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) 530b640b3b5dfccaf259967cb2cb6755c9aa20d4423Ted Kremenek goto cleanup_dri_screen; 53150d0ac299c641bee9024f3fbae2ea0640898a040Ted Kremenek 532c3055ab39ac3535ffd581d33e21b72133099a6ebTed Kremenek for (i = 0; extensions[i]; i++) { 53300a3a5f024ac54088ab887712b292171188064f0Ted Kremenek if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { 534c3055ab39ac3535ffd581d33e21b72133099a6ebTed Kremenek dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; 535c3055ab39ac3535ffd581d33e21b72133099a6ebTed Kremenek } 536aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 537692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek } else { 5384a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek assert(dri2_dpy->swrast); 5394a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) 540692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek goto cleanup_dri_screen; 541aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 542692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek 543aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek dri2_setup_screen(disp); 544aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 545aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return EGL_TRUE; 54600a3a5f024ac54088ab887712b292171188064f0Ted Kremenek 547aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek cleanup_dri_screen: 54800a3a5f024ac54088ab887712b292171188064f0Ted Kremenek dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); 549aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 550692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek return EGL_FALSE; 5513f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenek} 5523f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenek 5533f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenek/** 5543f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenek * Called via eglInitialize(), GLX_drv->API.Initialize(). 5553f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenek */ 5563f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenekstatic EGLBoolean 5573f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenekdri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) 55800a3a5f024ac54088ab887712b292171188064f0Ted Kremenek{ 5593f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenek /* not until swrast_dri is supported */ 5603f916501c91d3f6f37b1d43276c440343f9454f6Ted Kremenek if (disp->Options.UseFallback) 56100a3a5f024ac54088ab887712b292171188064f0Ted Kremenek return EGL_FALSE; 56250d0ac299c641bee9024f3fbae2ea0640898a040Ted Kremenek 563de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek switch (disp->Platform) { 564330dddd19406f9cc227e59e0bb0a36ecdc52915eTed Kremenek#ifdef HAVE_X11_PLATFORM 565330dddd19406f9cc227e59e0bb0a36ecdc52915eTed Kremenek case _EGL_PLATFORM_X11: 56600a3a5f024ac54088ab887712b292171188064f0Ted Kremenek if (disp->Options.TestOnly) 567de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek return EGL_TRUE; 56805a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek return dri2_initialize_x11(drv, disp); 569aed9b6ac2ed0013133e4d4aebf2fad2ccd27f3e6Ted Kremenek#endif 570b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 57172fc3b30d775a6b720dd0dd87aa853226f0625ddChris Lattner#ifdef HAVE_LIBUDEV 57272fc3b30d775a6b720dd0dd87aa853226f0625ddChris Lattner#ifdef HAVE_DRM_PLATFORM 573d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek case _EGL_PLATFORM_DRM: 574 if (disp->Options.TestOnly) 575 return EGL_TRUE; 576 return dri2_initialize_drm(drv, disp); 577#endif 578#ifdef HAVE_WAYLAND_PLATFORM 579 case _EGL_PLATFORM_WAYLAND: 580 if (disp->Options.TestOnly) 581 return EGL_TRUE; 582 return dri2_initialize_wayland(drv, disp); 583#endif 584#endif 585#ifdef HAVE_ANDROID_PLATFORM 586 case _EGL_PLATFORM_ANDROID: 587 if (disp->Options.TestOnly) 588 return EGL_TRUE; 589 return dri2_initialize_android(drv, disp); 590#endif 591 592 default: 593 return EGL_FALSE; 594 } 595} 596 597/** 598 * Called via eglTerminate(), drv->API.Terminate(). 599 */ 600static EGLBoolean 601dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) 602{ 603 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 604 605 _eglReleaseDisplayResources(drv, disp); 606 _eglCleanupDisplay(disp); 607 608 if (dri2_dpy->own_dri_screen) 609 dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); 610 if (dri2_dpy->fd) 611 close(dri2_dpy->fd); 612 if (dri2_dpy->driver) 613 dlclose(dri2_dpy->driver); 614 if (dri2_dpy->device_name) 615 free(dri2_dpy->device_name); 616 617 if (disp->PlatformDisplay == NULL) { 618 switch (disp->Platform) { 619#ifdef HAVE_X11_PLATFORM 620 case _EGL_PLATFORM_X11: 621 xcb_disconnect(dri2_dpy->conn); 622 break; 623#endif 624#ifdef HAVE_DRM_PLATFORM 625 case _EGL_PLATFORM_DRM: 626 if (dri2_dpy->own_device) { 627 gbm_device_destroy(&dri2_dpy->gbm_dri->base.base); 628 } 629 break; 630#endif 631 default: 632 break; 633 } 634 } 635 636 free(dri2_dpy); 637 disp->DriverData = NULL; 638 639 return EGL_TRUE; 640} 641 642 643/** 644 * Called via eglCreateContext(), drv->API.CreateContext(). 645 */ 646static _EGLContext * 647dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, 648 _EGLContext *share_list, const EGLint *attrib_list) 649{ 650 struct dri2_egl_context *dri2_ctx; 651 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 652 struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list); 653 __DRIcontext *shared = 654 dri2_ctx_shared ? dri2_ctx_shared->dri_context : NULL; 655 struct dri2_egl_config *dri2_config = dri2_egl_config(conf); 656 const __DRIconfig *dri_config; 657 int api; 658 659 (void) drv; 660 661 dri2_ctx = malloc(sizeof *dri2_ctx); 662 if (!dri2_ctx) { 663 _eglError(EGL_BAD_ALLOC, "eglCreateContext"); 664 return NULL; 665 } 666 667 if (!_eglInitContext(&dri2_ctx->base, disp, conf, attrib_list)) 668 goto cleanup; 669 670 switch (dri2_ctx->base.ClientAPI) { 671 case EGL_OPENGL_ES_API: 672 switch (dri2_ctx->base.ClientMajorVersion) { 673 case 1: 674 api = __DRI_API_GLES; 675 break; 676 case 2: 677 case 3: 678 api = __DRI_API_GLES2; 679 break; 680 default: 681 _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); 682 return NULL; 683 } 684 break; 685 case EGL_OPENGL_API: 686 if ((dri2_ctx->base.ClientMajorVersion >= 4 687 || (dri2_ctx->base.ClientMajorVersion == 3 688 && dri2_ctx->base.ClientMinorVersion >= 2)) 689 && dri2_ctx->base.Profile == EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) 690 api = __DRI_API_OPENGL_CORE; 691 else 692 api = __DRI_API_OPENGL; 693 break; 694 default: 695 _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); 696 return NULL; 697 } 698 699 if (conf != NULL) { 700 /* The config chosen here isn't necessarily 701 * used for surfaces later. 702 * A pixmap surface will use the single config. 703 * This opportunity depends on disabling the 704 * doubleBufferMode check in 705 * src/mesa/main/context.c:check_compatible() 706 */ 707 if (dri2_config->dri_double_config) 708 dri_config = dri2_config->dri_double_config; 709 else 710 dri_config = dri2_config->dri_single_config; 711 712 /* EGL_WINDOW_BIT is set only when there is a dri_double_config. This 713 * makes sure the back buffer will always be used. 714 */ 715 if (conf->SurfaceType & EGL_WINDOW_BIT) 716 dri2_ctx->base.WindowRenderBuffer = EGL_BACK_BUFFER; 717 } 718 else 719 dri_config = NULL; 720 721 if (dri2_dpy->dri2) { 722 if (dri2_dpy->dri2->base.version >= 3) { 723 unsigned error; 724 unsigned num_attribs = 0; 725 uint32_t ctx_attribs[8]; 726 727 ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; 728 ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMajorVersion; 729 ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION; 730 ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMinorVersion; 731 732 if (dri2_ctx->base.Flags != 0) { 733 /* If the implementation doesn't support the __DRI2_ROBUSTNESS 734 * extension, don't even try to send it the robust-access flag. 735 * It may explode. Instead, generate the required EGL error here. 736 */ 737 if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0 738 && !dri2_dpy->robustness) { 739 _eglError(EGL_BAD_MATCH, "eglCreateContext"); 740 goto cleanup; 741 } 742 743 ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_FLAGS; 744 ctx_attribs[num_attribs++] = dri2_ctx->base.Flags; 745 } 746 747 if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) { 748 /* If the implementation doesn't support the __DRI2_ROBUSTNESS 749 * extension, don't even try to send it a reset strategy. It may 750 * explode. Instead, generate the required EGL error here. 751 */ 752 if (!dri2_dpy->robustness) { 753 _eglError(EGL_BAD_CONFIG, "eglCreateContext"); 754 goto cleanup; 755 } 756 757 ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY; 758 ctx_attribs[num_attribs++] = __DRI_CTX_RESET_LOSE_CONTEXT; 759 } 760 761 assert(num_attribs <= ARRAY_SIZE(ctx_attribs)); 762 763 dri2_ctx->dri_context = 764 dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen, 765 api, 766 dri_config, 767 shared, 768 num_attribs / 2, 769 ctx_attribs, 770 & error, 771 dri2_ctx); 772 } else { 773 dri2_ctx->dri_context = 774 dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen, 775 api, 776 dri_config, 777 shared, 778 dri2_ctx); 779 } 780 } else { 781 assert(dri2_dpy->swrast); 782 dri2_ctx->dri_context = 783 dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen, 784 api, 785 dri_config, 786 shared, 787 dri2_ctx); 788 } 789 790 if (!dri2_ctx->dri_context) 791 goto cleanup; 792 793 return &dri2_ctx->base; 794 795 cleanup: 796 free(dri2_ctx); 797 return NULL; 798} 799 800/** 801 * Called via eglDestroyContext(), drv->API.DestroyContext(). 802 */ 803static EGLBoolean 804dri2_destroy_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) 805{ 806 struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 807 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 808 809 if (_eglPutContext(ctx)) { 810 dri2_dpy->core->destroyContext(dri2_ctx->dri_context); 811 free(dri2_ctx); 812 } 813 814 return EGL_TRUE; 815} 816 817/** 818 * Called via eglMakeCurrent(), drv->API.MakeCurrent(). 819 */ 820static EGLBoolean 821dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, 822 _EGLSurface *rsurf, _EGLContext *ctx) 823{ 824 struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); 825 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 826 struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf); 827 struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf); 828 struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 829 _EGLContext *old_ctx; 830 _EGLSurface *old_dsurf, *old_rsurf; 831 __DRIdrawable *ddraw, *rdraw; 832 __DRIcontext *cctx; 833 834 /* make new bindings */ 835 if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) 836 return EGL_FALSE; 837 838 /* flush before context switch */ 839 if (old_ctx && dri2_drv->glFlush) 840 dri2_drv->glFlush(); 841 842 ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL; 843 rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL; 844 cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; 845 846 if (old_ctx) { 847 __DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context; 848 dri2_dpy->core->unbindContext(old_cctx); 849 } 850 851 if ((cctx == NULL && ddraw == NULL && rdraw == NULL) || 852 dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { 853 if (old_dsurf) 854 drv->API.DestroySurface(drv, disp, old_dsurf); 855 if (old_rsurf) 856 drv->API.DestroySurface(drv, disp, old_rsurf); 857 if (old_ctx) 858 drv->API.DestroyContext(drv, disp, old_ctx); 859 860 return EGL_TRUE; 861 } else { 862 /* undo the previous _eglBindContext */ 863 _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf); 864 assert(&dri2_ctx->base == ctx && 865 &dri2_dsurf->base == dsurf && 866 &dri2_rsurf->base == rsurf); 867 868 _eglPutSurface(dsurf); 869 _eglPutSurface(rsurf); 870 _eglPutContext(ctx); 871 872 _eglPutSurface(old_dsurf); 873 _eglPutSurface(old_rsurf); 874 _eglPutContext(old_ctx); 875 876 return EGL_FALSE; 877 } 878} 879 880/* 881 * Called from eglGetProcAddress() via drv->API.GetProcAddress(). 882 */ 883static _EGLProc 884dri2_get_proc_address(_EGLDriver *drv, const char *procname) 885{ 886 struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); 887 888 return dri2_drv->get_proc_address(procname); 889} 890 891static EGLBoolean 892dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) 893{ 894 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 895 struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface); 896 897 (void) drv; 898 899 /* FIXME: If EGL allows frontbuffer rendering for window surfaces, 900 * we need to copy fake to real here.*/ 901 902 (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); 903 904 return EGL_TRUE; 905} 906 907static EGLBoolean 908dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine) 909{ 910 (void) drv; 911 (void) disp; 912 913 if (engine != EGL_CORE_NATIVE_ENGINE) 914 return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); 915 /* glXWaitX(); */ 916 917 return EGL_TRUE; 918} 919 920static EGLBoolean 921dri2_bind_tex_image(_EGLDriver *drv, 922 _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) 923{ 924 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 925 struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 926 struct dri2_egl_context *dri2_ctx; 927 _EGLContext *ctx; 928 GLint format, target; 929 930 ctx = _eglGetCurrentContext(); 931 dri2_ctx = dri2_egl_context(ctx); 932 933 if (!_eglBindTexImage(drv, disp, surf, buffer)) 934 return EGL_FALSE; 935 936 switch (dri2_surf->base.TextureFormat) { 937 case EGL_TEXTURE_RGB: 938 format = __DRI_TEXTURE_FORMAT_RGB; 939 break; 940 case EGL_TEXTURE_RGBA: 941 format = __DRI_TEXTURE_FORMAT_RGBA; 942 break; 943 default: 944 assert(0); 945 } 946 947 switch (dri2_surf->base.TextureTarget) { 948 case EGL_TEXTURE_2D: 949 target = GL_TEXTURE_2D; 950 break; 951 default: 952 assert(0); 953 } 954 955 (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context, 956 target, format, 957 dri2_surf->dri_drawable); 958 959 return EGL_TRUE; 960} 961 962static EGLBoolean 963dri2_release_tex_image(_EGLDriver *drv, 964 _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) 965{ 966#if __DRI_TEX_BUFFER_VERSION >= 3 967 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 968 struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); 969 struct dri2_egl_context *dri2_ctx; 970 _EGLContext *ctx; 971 GLint target; 972 973 ctx = _eglGetCurrentContext(); 974 dri2_ctx = dri2_egl_context(ctx); 975 976 if (!_eglReleaseTexImage(drv, disp, surf, buffer)) 977 return EGL_FALSE; 978 979 switch (dri2_surf->base.TextureTarget) { 980 case EGL_TEXTURE_2D: 981 target = GL_TEXTURE_2D; 982 break; 983 default: 984 assert(0); 985 } 986 if (dri2_dpy->tex_buffer->releaseTexBuffer!=NULL) 987 (*dri2_dpy->tex_buffer->releaseTexBuffer)(dri2_ctx->dri_context, 988 target, 989 dri2_surf->dri_drawable); 990#endif 991 992 return EGL_TRUE; 993} 994 995static _EGLImage * 996dri2_create_image(_EGLDisplay *disp, __DRIimage *dri_image) 997{ 998 struct dri2_egl_image *dri2_img; 999 1000 if (dri_image == NULL) { 1001 _eglError(EGL_BAD_ALLOC, "dri2_create_image"); 1002 return NULL; 1003 } 1004 1005 dri2_img = malloc(sizeof *dri2_img); 1006 if (!dri2_img) { 1007 _eglError(EGL_BAD_ALLOC, "dri2_create_image"); 1008 return NULL; 1009 } 1010 1011 if (!_eglInitImage(&dri2_img->base, disp)) { 1012 free(dri2_img); 1013 return NULL; 1014 } 1015 1016 dri2_img->dri_image = dri_image; 1017 1018 return &dri2_img->base; 1019} 1020 1021static _EGLImage * 1022dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, 1023 EGLClientBuffer buffer, 1024 const EGLint *attr_list) 1025{ 1026 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1027 struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); 1028 GLuint renderbuffer = (GLuint) (uintptr_t) buffer; 1029 __DRIimage *dri_image; 1030 1031 if (renderbuffer == 0) { 1032 _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 1033 return EGL_NO_IMAGE_KHR; 1034 } 1035 1036 dri_image = 1037 dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context, 1038 renderbuffer, NULL); 1039 1040 return dri2_create_image(disp, dri_image); 1041} 1042 1043static _EGLImage * 1044dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, 1045 EGLClientBuffer buffer, const EGLint *attr_list) 1046{ 1047 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1048 EGLint format, name, pitch, err; 1049 _EGLImageAttribs attrs; 1050 __DRIimage *dri_image; 1051 1052 name = (EGLint) (uintptr_t) buffer; 1053 1054 err = _eglParseImageAttribList(&attrs, disp, attr_list); 1055 if (err != EGL_SUCCESS) 1056 return NULL; 1057 1058 if (attrs.Width <= 0 || attrs.Height <= 0 || 1059 attrs.DRMBufferStrideMESA <= 0) { 1060 _eglError(EGL_BAD_PARAMETER, 1061 "bad width, height or stride"); 1062 return NULL; 1063 } 1064 1065 switch (attrs.DRMBufferFormatMESA) { 1066 case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: 1067 format = __DRI_IMAGE_FORMAT_ARGB8888; 1068 pitch = attrs.DRMBufferStrideMESA; 1069 break; 1070 default: 1071 _eglError(EGL_BAD_PARAMETER, 1072 "dri2_create_image_khr: unsupported pixmap depth"); 1073 return NULL; 1074 } 1075 1076 dri_image = 1077 dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, 1078 attrs.Width, 1079 attrs.Height, 1080 format, 1081 name, 1082 pitch, 1083 NULL); 1084 1085 return dri2_create_image(disp, dri_image); 1086} 1087 1088#ifdef HAVE_WAYLAND_PLATFORM 1089 1090/* This structure describes how a wl_buffer maps to one or more 1091 * __DRIimages. A wl_drm_buffer stores the wl_drm format code and the 1092 * offsets and strides of the planes in the buffer. This table maps a 1093 * wl_drm format code to a description of the planes in the buffer 1094 * that lets us create a __DRIimage for each of the planes. */ 1095 1096static const struct wl_drm_components_descriptor { 1097 uint32_t dri_components; 1098 EGLint components; 1099 int nplanes; 1100} wl_drm_components[] = { 1101 { __DRI_IMAGE_COMPONENTS_RGB, EGL_TEXTURE_RGB, 1 }, 1102 { __DRI_IMAGE_COMPONENTS_RGBA, EGL_TEXTURE_RGBA, 1 }, 1103 { __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 }, 1104 { __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 }, 1105 { __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 }, 1106}; 1107 1108static _EGLImage * 1109dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx, 1110 EGLClientBuffer _buffer, 1111 const EGLint *attr_list) 1112{ 1113 struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; 1114 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1115 const struct wl_drm_components_descriptor *f; 1116 __DRIimage *dri_image; 1117 _EGLImageAttribs attrs; 1118 EGLint err; 1119 int32_t plane; 1120 1121 if (!wayland_buffer_is_drm(&buffer->buffer)) 1122 return NULL; 1123 1124 err = _eglParseImageAttribList(&attrs, disp, attr_list); 1125 plane = attrs.PlaneWL; 1126 if (err != EGL_SUCCESS) { 1127 _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); 1128 return NULL; 1129 } 1130 1131 f = buffer->driver_format; 1132 if (plane < 0 || plane >= f->nplanes) { 1133 _eglError(EGL_BAD_PARAMETER, 1134 "dri2_create_image_wayland_wl_buffer (plane out of bounds)"); 1135 return NULL; 1136 } 1137 1138 dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL); 1139 1140 if (dri_image == NULL) { 1141 _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); 1142 return NULL; 1143 } 1144 1145 return dri2_create_image(disp, dri_image); 1146} 1147#endif 1148 1149_EGLImage * 1150dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, 1151 _EGLContext *ctx, EGLenum target, 1152 EGLClientBuffer buffer, const EGLint *attr_list) 1153{ 1154 (void) drv; 1155 1156 switch (target) { 1157 case EGL_GL_RENDERBUFFER_KHR: 1158 return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list); 1159 case EGL_DRM_BUFFER_MESA: 1160 return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list); 1161#ifdef HAVE_WAYLAND_PLATFORM 1162 case EGL_WAYLAND_BUFFER_WL: 1163 return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list); 1164#endif 1165 default: 1166 _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); 1167 return EGL_NO_IMAGE_KHR; 1168 } 1169} 1170 1171static EGLBoolean 1172dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image) 1173{ 1174 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1175 struct dri2_egl_image *dri2_img = dri2_egl_image(image); 1176 1177 (void) drv; 1178 1179 dri2_dpy->image->destroyImage(dri2_img->dri_image); 1180 free(dri2_img); 1181 1182 return EGL_TRUE; 1183} 1184 1185static _EGLImage * 1186dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, 1187 const EGLint *attr_list) 1188{ 1189 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1190 struct dri2_egl_image *dri2_img; 1191 _EGLImageAttribs attrs; 1192 unsigned int dri_use, valid_mask; 1193 int format; 1194 EGLint err = EGL_SUCCESS; 1195 1196 (void) drv; 1197 1198 dri2_img = malloc(sizeof *dri2_img); 1199 if (!dri2_img) { 1200 _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); 1201 return EGL_NO_IMAGE_KHR; 1202 } 1203 1204 if (!attr_list) { 1205 err = EGL_BAD_PARAMETER; 1206 goto cleanup_img; 1207 } 1208 1209 if (!_eglInitImage(&dri2_img->base, disp)) { 1210 err = EGL_BAD_PARAMETER; 1211 goto cleanup_img; 1212 } 1213 1214 err = _eglParseImageAttribList(&attrs, disp, attr_list); 1215 if (err != EGL_SUCCESS) 1216 goto cleanup_img; 1217 1218 if (attrs.Width <= 0 || attrs.Height <= 0) { 1219 _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", 1220 attrs.Width, attrs.Height); 1221 goto cleanup_img; 1222 } 1223 1224 switch (attrs.DRMBufferFormatMESA) { 1225 case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: 1226 format = __DRI_IMAGE_FORMAT_ARGB8888; 1227 break; 1228 default: 1229 _eglLog(_EGL_WARNING, "bad image format value 0x%04x", 1230 attrs.DRMBufferFormatMESA); 1231 goto cleanup_img; 1232 } 1233 1234 valid_mask = 1235 EGL_DRM_BUFFER_USE_SCANOUT_MESA | 1236 EGL_DRM_BUFFER_USE_SHARE_MESA | 1237 EGL_DRM_BUFFER_USE_CURSOR_MESA; 1238 if (attrs.DRMBufferUseMESA & ~valid_mask) { 1239 _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", 1240 attrs.DRMBufferUseMESA & ~valid_mask); 1241 goto cleanup_img; 1242 } 1243 1244 dri_use = 0; 1245 if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA) 1246 dri_use |= __DRI_IMAGE_USE_SHARE; 1247 if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SCANOUT_MESA) 1248 dri_use |= __DRI_IMAGE_USE_SCANOUT; 1249 if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_CURSOR_MESA) 1250 dri_use |= __DRI_IMAGE_USE_CURSOR; 1251 1252 dri2_img->dri_image = 1253 dri2_dpy->image->createImage(dri2_dpy->dri_screen, 1254 attrs.Width, attrs.Height, 1255 format, dri_use, dri2_img); 1256 if (dri2_img->dri_image == NULL) { 1257 err = EGL_BAD_ALLOC; 1258 goto cleanup_img; 1259 } 1260 1261 return &dri2_img->base; 1262 1263 cleanup_img: 1264 free(dri2_img); 1265 _eglError(err, "dri2_create_drm_image_mesa"); 1266 1267 return EGL_NO_IMAGE_KHR; 1268} 1269 1270static EGLBoolean 1271dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, 1272 EGLint *name, EGLint *handle, EGLint *stride) 1273{ 1274 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1275 struct dri2_egl_image *dri2_img = dri2_egl_image(img); 1276 1277 (void) drv; 1278 1279 if (name && !dri2_dpy->image->queryImage(dri2_img->dri_image, 1280 __DRI_IMAGE_ATTRIB_NAME, name)) { 1281 _eglError(EGL_BAD_ALLOC, "dri2_export_drm_image_mesa"); 1282 return EGL_FALSE; 1283 } 1284 1285 if (handle) 1286 dri2_dpy->image->queryImage(dri2_img->dri_image, 1287 __DRI_IMAGE_ATTRIB_HANDLE, handle); 1288 1289 if (stride) 1290 dri2_dpy->image->queryImage(dri2_img->dri_image, 1291 __DRI_IMAGE_ATTRIB_STRIDE, stride); 1292 1293 return EGL_TRUE; 1294} 1295 1296#ifdef HAVE_WAYLAND_PLATFORM 1297 1298static void 1299dri2_wl_reference_buffer(void *user_data, uint32_t name, 1300 struct wl_drm_buffer *buffer) 1301{ 1302 _EGLDisplay *disp = user_data; 1303 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1304 __DRIimage *img; 1305 int i, dri_components = 0; 1306 1307 img = dri2_dpy->image->createImageFromNames(dri2_dpy->dri_screen, 1308 buffer->buffer.width, 1309 buffer->buffer.height, 1310 buffer->format, (int*)&name, 1, 1311 buffer->stride, 1312 buffer->offset, 1313 NULL); 1314 1315 if (img == NULL) 1316 return; 1317 1318 dri2_dpy->image->queryImage(img, __DRI_IMAGE_ATTRIB_COMPONENTS, &dri_components); 1319 1320 buffer->driver_format = NULL; 1321 for (i = 0; i < ARRAY_SIZE(wl_drm_components); i++) 1322 if (wl_drm_components[i].dri_components == dri_components) 1323 buffer->driver_format = &wl_drm_components[i]; 1324 1325 if (buffer->driver_format == NULL) 1326 dri2_dpy->image->destroyImage(img); 1327 else 1328 buffer->driver_buffer = img; 1329} 1330 1331static void 1332dri2_wl_release_buffer(void *user_data, struct wl_drm_buffer *buffer) 1333{ 1334 _EGLDisplay *disp = user_data; 1335 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1336 1337 dri2_dpy->image->destroyImage(buffer->driver_buffer); 1338} 1339 1340static struct wayland_drm_callbacks wl_drm_callbacks = { 1341 .authenticate = NULL, 1342 .reference_buffer = dri2_wl_reference_buffer, 1343 .release_buffer = dri2_wl_release_buffer 1344}; 1345 1346static EGLBoolean 1347dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, 1348 struct wl_display *wl_dpy) 1349{ 1350 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1351 1352 (void) drv; 1353 1354 if (dri2_dpy->wl_server_drm) 1355 return EGL_FALSE; 1356 1357 wl_drm_callbacks.authenticate = 1358 (int(*)(void *, uint32_t)) dri2_dpy->authenticate; 1359 1360 dri2_dpy->wl_server_drm = 1361 wayland_drm_init(wl_dpy, dri2_dpy->device_name, 1362 &wl_drm_callbacks, disp); 1363 1364 if (!dri2_dpy->wl_server_drm) 1365 return EGL_FALSE; 1366 1367 return EGL_TRUE; 1368} 1369 1370static EGLBoolean 1371dri2_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, 1372 struct wl_display *wl_dpy) 1373{ 1374 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 1375 1376 (void) drv; 1377 1378 if (!dri2_dpy->wl_server_drm) 1379 return EGL_FALSE; 1380 1381 wayland_drm_uninit(dri2_dpy->wl_server_drm); 1382 dri2_dpy->wl_server_drm = NULL; 1383 1384 return EGL_TRUE; 1385} 1386 1387static EGLBoolean 1388dri2_query_wayland_buffer_wl(_EGLDriver *drv, _EGLDisplay *disp, 1389 struct wl_buffer *_buffer, 1390 EGLint attribute, EGLint *value) 1391{ 1392 struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; 1393 const struct wl_drm_components_descriptor *format; 1394 1395 if (!wayland_buffer_is_drm(&buffer->buffer)) 1396 return EGL_FALSE; 1397 1398 format = buffer->driver_format; 1399 switch (attribute) { 1400 case EGL_TEXTURE_FORMAT: 1401 *value = format->components; 1402 return EGL_TRUE; 1403 case EGL_WIDTH: 1404 *value = buffer->buffer.width; 1405 break; 1406 case EGL_HEIGHT: 1407 *value = buffer->buffer.height; 1408 break; 1409 } 1410 1411 return EGL_FALSE; 1412} 1413#endif 1414 1415static void 1416dri2_unload(_EGLDriver *drv) 1417{ 1418 struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); 1419 1420 if (dri2_drv->handle) 1421 dlclose(dri2_drv->handle); 1422 free(dri2_drv); 1423} 1424 1425static EGLBoolean 1426dri2_load(_EGLDriver *drv) 1427{ 1428 struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); 1429#ifdef HAVE_SHARED_GLAPI 1430#ifdef HAVE_ANDROID_PLATFORM 1431 const char *libname = "libglapi.so"; 1432#else 1433 const char *libname = "libglapi.so.0"; 1434#endif 1435#else 1436 /* 1437 * Both libGL.so and libglapi.so are glapi providers. There is no way to 1438 * tell which one to load. 1439 */ 1440 const char *libname = NULL; 1441#endif 1442 void *handle; 1443 1444 /* RTLD_GLOBAL to make sure glapi symbols are visible to DRI drivers */ 1445 handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL); 1446 if (handle) { 1447 dri2_drv->get_proc_address = (_EGLProc (*)(const char *)) 1448 dlsym(handle, "_glapi_get_proc_address"); 1449 if (!dri2_drv->get_proc_address || !libname) { 1450 /* no need to keep a reference */ 1451 dlclose(handle); 1452 handle = NULL; 1453 } 1454 } 1455 1456 /* if glapi is not available, loading DRI drivers will fail */ 1457 if (!dri2_drv->get_proc_address) { 1458 _eglLog(_EGL_WARNING, "DRI2: failed to find _glapi_get_proc_address"); 1459 return EGL_FALSE; 1460 } 1461 1462 dri2_drv->glFlush = (void (*)(void)) 1463 dri2_drv->get_proc_address("glFlush"); 1464 1465 dri2_drv->handle = handle; 1466 1467 return EGL_TRUE; 1468} 1469 1470/** 1471 * This is the main entrypoint into the driver, called by libEGL. 1472 * Create a new _EGLDriver object and init its dispatch table. 1473 */ 1474_EGLDriver * 1475_eglBuiltInDriverDRI2(const char *args) 1476{ 1477 struct dri2_egl_driver *dri2_drv; 1478 1479 (void) args; 1480 1481 dri2_drv = malloc(sizeof *dri2_drv); 1482 if (!dri2_drv) 1483 return NULL; 1484 1485 memset(dri2_drv, 0, sizeof *dri2_drv); 1486 1487 if (!dri2_load(&dri2_drv->base)) { 1488 free(dri2_drv); 1489 return NULL; 1490 } 1491 1492 _eglInitDriverFallbacks(&dri2_drv->base); 1493 dri2_drv->base.API.Initialize = dri2_initialize; 1494 dri2_drv->base.API.Terminate = dri2_terminate; 1495 dri2_drv->base.API.CreateContext = dri2_create_context; 1496 dri2_drv->base.API.DestroyContext = dri2_destroy_context; 1497 dri2_drv->base.API.MakeCurrent = dri2_make_current; 1498 dri2_drv->base.API.GetProcAddress = dri2_get_proc_address; 1499 dri2_drv->base.API.WaitClient = dri2_wait_client; 1500 dri2_drv->base.API.WaitNative = dri2_wait_native; 1501 dri2_drv->base.API.BindTexImage = dri2_bind_tex_image; 1502 dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image; 1503 dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr; 1504 dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr; 1505 dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa; 1506 dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa; 1507#ifdef HAVE_WAYLAND_PLATFORM 1508 dri2_drv->base.API.BindWaylandDisplayWL = dri2_bind_wayland_display_wl; 1509 dri2_drv->base.API.UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl; 1510 dri2_drv->base.API.QueryWaylandBufferWL = dri2_query_wayland_buffer_wl; 1511#endif 1512 1513 dri2_drv->base.Name = "DRI2"; 1514 dri2_drv->base.Unload = dri2_unload; 1515 1516 return &dri2_drv->base; 1517} 1518