Rev 4358 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4358 | Rev 4401 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright © 2010 Intel Corporation |
2 | * Copyright © 2010 Intel Corporation |
3 | * |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
10 | * |
11 | * The above copyright notice and this permission notice (including the next |
11 | * The above copyright notice and this permission notice (including the next |
12 | * paragraph) shall be included in all copies or substantial portions of the |
12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. |
13 | * Software. |
14 | * |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
19 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
19 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
20 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
20 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
22 | * DEALINGS IN THE SOFTWARE. |
22 | * DEALINGS IN THE SOFTWARE. |
23 | * |
23 | * |
24 | * Authors: |
24 | * Authors: |
25 | * Kristian Høgsberg |
25 | * Kristian Høgsberg |
26 | */ |
26 | */ |
27 | 27 | ||
28 | #include |
28 | #include |
29 | #include |
29 | #include |
30 | #include |
30 | #include |
31 | #include |
31 | #include |
32 | #include |
32 | #include |
33 | #include |
33 | #include |
34 | #include |
34 | #include |
35 | #include |
35 | #include |
36 | #include |
36 | #include |
37 | #include |
37 | #include |
38 | #include |
38 | #include |
39 | #include |
39 | #include |
40 | 40 | ||
41 | #define EGL_EGLEXT_PROTOTYPES |
41 | #define EGL_EGLEXT_PROTOTYPES |
42 | #include |
42 | #include |
43 | #include |
43 | #include |
44 | 44 | ||
45 | #include "eglmode.h" |
45 | #include "eglmode.h" |
46 | #include "eglscreen.h" |
46 | #include "eglscreen.h" |
47 | 47 | ||
48 | #include "egl_dri2.h" |
48 | #include "egl_dri2.h" |
49 | 49 | ||
50 | typedef unsigned int lib_handle; |
50 | typedef unsigned int lib_handle; |
51 | 51 | ||
52 | lib_handle load_library(const char *name); |
52 | lib_handle load_library(const char *name); |
53 | void *get_proc_address(lib_handle lib, char *proc_name); |
53 | void *get_proc_address(lib_handle lib, char *proc_name); |
54 | 54 | ||
55 | const __DRIuseInvalidateExtension use_invalidate = { |
55 | const __DRIuseInvalidateExtension use_invalidate = { |
56 | { __DRI_USE_INVALIDATE, 1 } |
56 | { __DRI_USE_INVALIDATE, 1 } |
57 | }; |
57 | }; |
58 | 58 | ||
59 | EGLint dri2_to_egl_attribute_map[] = { |
59 | EGLint dri2_to_egl_attribute_map[] = { |
60 | 0, |
60 | 0, |
61 | EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */ |
61 | EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */ |
62 | EGL_LEVEL, /* __DRI_ATTRIB_LEVEL */ |
62 | EGL_LEVEL, /* __DRI_ATTRIB_LEVEL */ |
63 | EGL_RED_SIZE, /* __DRI_ATTRIB_RED_SIZE */ |
63 | EGL_RED_SIZE, /* __DRI_ATTRIB_RED_SIZE */ |
64 | EGL_GREEN_SIZE, /* __DRI_ATTRIB_GREEN_SIZE */ |
64 | EGL_GREEN_SIZE, /* __DRI_ATTRIB_GREEN_SIZE */ |
65 | EGL_BLUE_SIZE, /* __DRI_ATTRIB_BLUE_SIZE */ |
65 | EGL_BLUE_SIZE, /* __DRI_ATTRIB_BLUE_SIZE */ |
66 | EGL_LUMINANCE_SIZE, /* __DRI_ATTRIB_LUMINANCE_SIZE */ |
66 | EGL_LUMINANCE_SIZE, /* __DRI_ATTRIB_LUMINANCE_SIZE */ |
67 | EGL_ALPHA_SIZE, /* __DRI_ATTRIB_ALPHA_SIZE */ |
67 | EGL_ALPHA_SIZE, /* __DRI_ATTRIB_ALPHA_SIZE */ |
68 | 0, /* __DRI_ATTRIB_ALPHA_MASK_SIZE */ |
68 | 0, /* __DRI_ATTRIB_ALPHA_MASK_SIZE */ |
69 | EGL_DEPTH_SIZE, /* __DRI_ATTRIB_DEPTH_SIZE */ |
69 | EGL_DEPTH_SIZE, /* __DRI_ATTRIB_DEPTH_SIZE */ |
70 | EGL_STENCIL_SIZE, /* __DRI_ATTRIB_STENCIL_SIZE */ |
70 | EGL_STENCIL_SIZE, /* __DRI_ATTRIB_STENCIL_SIZE */ |
71 | 0, /* __DRI_ATTRIB_ACCUM_RED_SIZE */ |
71 | 0, /* __DRI_ATTRIB_ACCUM_RED_SIZE */ |
72 | 0, /* __DRI_ATTRIB_ACCUM_GREEN_SIZE */ |
72 | 0, /* __DRI_ATTRIB_ACCUM_GREEN_SIZE */ |
73 | 0, /* __DRI_ATTRIB_ACCUM_BLUE_SIZE */ |
73 | 0, /* __DRI_ATTRIB_ACCUM_BLUE_SIZE */ |
74 | 0, /* __DRI_ATTRIB_ACCUM_ALPHA_SIZE */ |
74 | 0, /* __DRI_ATTRIB_ACCUM_ALPHA_SIZE */ |
75 | EGL_SAMPLE_BUFFERS, /* __DRI_ATTRIB_SAMPLE_BUFFERS */ |
75 | EGL_SAMPLE_BUFFERS, /* __DRI_ATTRIB_SAMPLE_BUFFERS */ |
76 | EGL_SAMPLES, /* __DRI_ATTRIB_SAMPLES */ |
76 | EGL_SAMPLES, /* __DRI_ATTRIB_SAMPLES */ |
77 | 0, /* __DRI_ATTRIB_RENDER_TYPE, */ |
77 | 0, /* __DRI_ATTRIB_RENDER_TYPE, */ |
78 | 0, /* __DRI_ATTRIB_CONFIG_CAVEAT */ |
78 | 0, /* __DRI_ATTRIB_CONFIG_CAVEAT */ |
79 | 0, /* __DRI_ATTRIB_CONFORMANT */ |
79 | 0, /* __DRI_ATTRIB_CONFORMANT */ |
80 | 0, /* __DRI_ATTRIB_DOUBLE_BUFFER */ |
80 | 0, /* __DRI_ATTRIB_DOUBLE_BUFFER */ |
81 | 0, /* __DRI_ATTRIB_STEREO */ |
81 | 0, /* __DRI_ATTRIB_STEREO */ |
82 | 0, /* __DRI_ATTRIB_AUX_BUFFERS */ |
82 | 0, /* __DRI_ATTRIB_AUX_BUFFERS */ |
83 | 0, /* __DRI_ATTRIB_TRANSPARENT_TYPE */ |
83 | 0, /* __DRI_ATTRIB_TRANSPARENT_TYPE */ |
84 | 0, /* __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE */ |
84 | 0, /* __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE */ |
85 | 0, /* __DRI_ATTRIB_TRANSPARENT_RED_VALUE */ |
85 | 0, /* __DRI_ATTRIB_TRANSPARENT_RED_VALUE */ |
86 | 0, /* __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE */ |
86 | 0, /* __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE */ |
87 | 0, /* __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE */ |
87 | 0, /* __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE */ |
88 | 0, /* __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE */ |
88 | 0, /* __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE */ |
89 | 0, /* __DRI_ATTRIB_FLOAT_MODE (deprecated) */ |
89 | 0, /* __DRI_ATTRIB_FLOAT_MODE (deprecated) */ |
90 | 0, /* __DRI_ATTRIB_RED_MASK */ |
90 | 0, /* __DRI_ATTRIB_RED_MASK */ |
91 | 0, /* __DRI_ATTRIB_GREEN_MASK */ |
91 | 0, /* __DRI_ATTRIB_GREEN_MASK */ |
92 | 0, /* __DRI_ATTRIB_BLUE_MASK */ |
92 | 0, /* __DRI_ATTRIB_BLUE_MASK */ |
93 | 0, /* __DRI_ATTRIB_ALPHA_MASK */ |
93 | 0, /* __DRI_ATTRIB_ALPHA_MASK */ |
94 | EGL_MAX_PBUFFER_WIDTH, /* __DRI_ATTRIB_MAX_PBUFFER_WIDTH */ |
94 | EGL_MAX_PBUFFER_WIDTH, /* __DRI_ATTRIB_MAX_PBUFFER_WIDTH */ |
95 | EGL_MAX_PBUFFER_HEIGHT, /* __DRI_ATTRIB_MAX_PBUFFER_HEIGHT */ |
95 | EGL_MAX_PBUFFER_HEIGHT, /* __DRI_ATTRIB_MAX_PBUFFER_HEIGHT */ |
96 | EGL_MAX_PBUFFER_PIXELS, /* __DRI_ATTRIB_MAX_PBUFFER_PIXELS */ |
96 | EGL_MAX_PBUFFER_PIXELS, /* __DRI_ATTRIB_MAX_PBUFFER_PIXELS */ |
97 | 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH */ |
97 | 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH */ |
98 | 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT */ |
98 | 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT */ |
99 | 0, /* __DRI_ATTRIB_VISUAL_SELECT_GROUP */ |
99 | 0, /* __DRI_ATTRIB_VISUAL_SELECT_GROUP */ |
100 | 0, /* __DRI_ATTRIB_SWAP_METHOD */ |
100 | 0, /* __DRI_ATTRIB_SWAP_METHOD */ |
101 | EGL_MAX_SWAP_INTERVAL, /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */ |
101 | EGL_MAX_SWAP_INTERVAL, /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */ |
102 | EGL_MIN_SWAP_INTERVAL, /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */ |
102 | EGL_MIN_SWAP_INTERVAL, /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */ |
103 | 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */ |
103 | 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */ |
104 | 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */ |
104 | 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */ |
105 | 0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */ |
105 | 0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */ |
106 | 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */ |
106 | 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */ |
107 | EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */ |
107 | EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */ |
108 | 0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */ |
108 | 0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */ |
109 | }; |
109 | }; |
110 | 110 | ||
111 | static EGLBoolean |
111 | static EGLBoolean |
112 | dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) |
112 | dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) |
113 | { |
113 | { |
114 | if (_eglCompareConfigs(conf, criteria, NULL, EGL_FALSE) != 0) |
114 | if (_eglCompareConfigs(conf, criteria, NULL, EGL_FALSE) != 0) |
115 | return EGL_FALSE; |
115 | return EGL_FALSE; |
116 | 116 | ||
117 | if (!_eglMatchConfig(conf, criteria)) |
117 | if (!_eglMatchConfig(conf, criteria)) |
118 | return EGL_FALSE; |
118 | return EGL_FALSE; |
119 | 119 | ||
120 | return EGL_TRUE; |
120 | return EGL_TRUE; |
121 | } |
121 | } |
122 | 122 | ||
123 | struct dri2_egl_config * |
123 | struct dri2_egl_config * |
124 | dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, |
124 | dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, |
125 | int depth, EGLint surface_type, const EGLint *attr_list, |
125 | int depth, EGLint surface_type, const EGLint *attr_list, |
126 | const unsigned int *rgba_masks) |
126 | const unsigned int *rgba_masks) |
127 | { |
127 | { |
128 | struct dri2_egl_config *conf; |
128 | struct dri2_egl_config *conf; |
129 | struct dri2_egl_display *dri2_dpy; |
129 | struct dri2_egl_display *dri2_dpy; |
130 | _EGLConfig base; |
130 | _EGLConfig base; |
131 | unsigned int attrib, value, double_buffer; |
131 | unsigned int attrib, value, double_buffer; |
132 | EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; |
132 | EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; |
133 | unsigned int dri_masks[4] = { 0, 0, 0, 0 }; |
133 | unsigned int dri_masks[4] = { 0, 0, 0, 0 }; |
134 | _EGLConfig *matching_config; |
134 | _EGLConfig *matching_config; |
135 | EGLint num_configs = 0; |
135 | EGLint num_configs = 0; |
136 | EGLint config_id; |
136 | EGLint config_id; |
137 | int i; |
137 | int i; |
138 | 138 | ||
139 | dri2_dpy = disp->DriverData; |
139 | dri2_dpy = disp->DriverData; |
140 | _eglInitConfig(&base, disp, id); |
140 | _eglInitConfig(&base, disp, id); |
141 | 141 | ||
142 | i = 0; |
142 | i = 0; |
143 | double_buffer = 0; |
143 | double_buffer = 0; |
144 | bind_to_texture_rgb = 0; |
144 | bind_to_texture_rgb = 0; |
145 | bind_to_texture_rgba = 0; |
145 | bind_to_texture_rgba = 0; |
146 | 146 | ||
147 | while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { |
147 | while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { |
148 | switch (attrib) { |
148 | switch (attrib) { |
149 | case __DRI_ATTRIB_RENDER_TYPE: |
149 | case __DRI_ATTRIB_RENDER_TYPE: |
150 | if (value & __DRI_ATTRIB_RGBA_BIT) |
150 | if (value & __DRI_ATTRIB_RGBA_BIT) |
151 | value = EGL_RGB_BUFFER; |
151 | value = EGL_RGB_BUFFER; |
152 | else if (value & __DRI_ATTRIB_LUMINANCE_BIT) |
152 | else if (value & __DRI_ATTRIB_LUMINANCE_BIT) |
153 | value = EGL_LUMINANCE_BUFFER; |
153 | value = EGL_LUMINANCE_BUFFER; |
154 | else |
154 | else |
155 | return NULL; |
155 | return NULL; |
156 | _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value); |
156 | _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value); |
157 | break; |
157 | break; |
158 | 158 | ||
159 | case __DRI_ATTRIB_CONFIG_CAVEAT: |
159 | case __DRI_ATTRIB_CONFIG_CAVEAT: |
160 | if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) |
160 | if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) |
161 | value = EGL_NON_CONFORMANT_CONFIG; |
161 | value = EGL_NON_CONFORMANT_CONFIG; |
162 | else if (value & __DRI_ATTRIB_SLOW_BIT) |
162 | else if (value & __DRI_ATTRIB_SLOW_BIT) |
163 | value = EGL_SLOW_CONFIG; |
163 | value = EGL_SLOW_CONFIG; |
164 | else |
164 | else |
165 | value = EGL_NONE; |
165 | value = EGL_NONE; |
166 | _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value); |
166 | _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value); |
167 | break; |
167 | break; |
168 | 168 | ||
169 | case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: |
169 | case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: |
170 | bind_to_texture_rgb = value; |
170 | bind_to_texture_rgb = value; |
171 | break; |
171 | break; |
172 | 172 | ||
173 | case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: |
173 | case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: |
174 | bind_to_texture_rgba = value; |
174 | bind_to_texture_rgba = value; |
175 | break; |
175 | break; |
176 | 176 | ||
177 | case __DRI_ATTRIB_DOUBLE_BUFFER: |
177 | case __DRI_ATTRIB_DOUBLE_BUFFER: |
178 | double_buffer = value; |
178 | double_buffer = value; |
179 | break; |
179 | break; |
180 | 180 | ||
181 | case __DRI_ATTRIB_RED_MASK: |
181 | case __DRI_ATTRIB_RED_MASK: |
182 | dri_masks[0] = value; |
182 | dri_masks[0] = value; |
183 | break; |
183 | break; |
184 | 184 | ||
185 | case __DRI_ATTRIB_GREEN_MASK: |
185 | case __DRI_ATTRIB_GREEN_MASK: |
186 | dri_masks[1] = value; |
186 | dri_masks[1] = value; |
187 | break; |
187 | break; |
188 | 188 | ||
189 | case __DRI_ATTRIB_BLUE_MASK: |
189 | case __DRI_ATTRIB_BLUE_MASK: |
190 | dri_masks[2] = value; |
190 | dri_masks[2] = value; |
191 | break; |
191 | break; |
192 | 192 | ||
193 | case __DRI_ATTRIB_ALPHA_MASK: |
193 | case __DRI_ATTRIB_ALPHA_MASK: |
194 | dri_masks[3] = value; |
194 | dri_masks[3] = value; |
195 | break; |
195 | break; |
196 | 196 | ||
197 | default: |
197 | default: |
198 | key = dri2_to_egl_attribute_map[attrib]; |
198 | key = dri2_to_egl_attribute_map[attrib]; |
199 | if (key != 0) |
199 | if (key != 0) |
200 | _eglSetConfigKey(&base, key, value); |
200 | _eglSetConfigKey(&base, key, value); |
201 | break; |
201 | break; |
202 | } |
202 | } |
203 | } |
203 | } |
204 | 204 | ||
205 | if (attr_list) |
205 | if (attr_list) |
206 | for (i = 0; attr_list[i] != EGL_NONE; i += 2) |
206 | for (i = 0; attr_list[i] != EGL_NONE; i += 2) |
207 | _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]); |
207 | _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]); |
208 | 208 | ||
209 | /* Allow a 24-bit RGB visual to match a 32-bit RGBA EGLConfig. Otherwise |
209 | /* Allow a 24-bit RGB visual to match a 32-bit RGBA EGLConfig. Otherwise |
210 | * it will only match a 32-bit RGBA visual. On a composited window manager |
210 | * it will only match a 32-bit RGBA visual. On a composited window manager |
211 | * on X11, this will make all of the EGLConfigs with destination alpha get |
211 | * on X11, this will make all of the EGLConfigs with destination alpha get |
212 | * blended by the compositor. This is probably not what the application |
212 | * blended by the compositor. This is probably not what the application |
213 | * wants... especially on drivers that only have 32-bit RGBA EGLConfigs! |
213 | * wants... especially on drivers that only have 32-bit RGBA EGLConfigs! |
214 | */ |
214 | */ |
215 | if (depth > 0 && depth != base.BufferSize |
215 | if (depth > 0 && depth != base.BufferSize |
216 | && !(depth == 24 && base.BufferSize == 32)) |
216 | && !(depth == 24 && base.BufferSize == 32)) |
217 | return NULL; |
217 | return NULL; |
218 | 218 | ||
219 | if (rgba_masks && memcmp(rgba_masks, dri_masks, sizeof(dri_masks))) |
219 | if (rgba_masks && memcmp(rgba_masks, dri_masks, sizeof(dri_masks))) |
220 | return NULL; |
220 | return NULL; |
221 | 221 | ||
222 | base.NativeRenderable = EGL_TRUE; |
222 | base.NativeRenderable = EGL_TRUE; |
223 | 223 | ||
224 | base.SurfaceType = surface_type; |
224 | base.SurfaceType = surface_type; |
225 | if (surface_type & (EGL_PBUFFER_BIT | |
225 | if (surface_type & (EGL_PBUFFER_BIT | |
226 | (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) { |
226 | (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) { |
227 | base.BindToTextureRGB = bind_to_texture_rgb; |
227 | base.BindToTextureRGB = bind_to_texture_rgb; |
228 | if (base.AlphaSize > 0) |
228 | if (base.AlphaSize > 0) |
229 | base.BindToTextureRGBA = bind_to_texture_rgba; |
229 | base.BindToTextureRGBA = bind_to_texture_rgba; |
230 | } |
230 | } |
231 | 231 | ||
232 | base.RenderableType = disp->ClientAPIs; |
232 | base.RenderableType = disp->ClientAPIs; |
233 | base.Conformant = disp->ClientAPIs; |
233 | base.Conformant = disp->ClientAPIs; |
234 | 234 | ||
235 | base.MinSwapInterval = dri2_dpy->min_swap_interval; |
235 | base.MinSwapInterval = dri2_dpy->min_swap_interval; |
236 | base.MaxSwapInterval = dri2_dpy->max_swap_interval; |
236 | base.MaxSwapInterval = dri2_dpy->max_swap_interval; |
237 | 237 | ||
238 | if (!_eglValidateConfig(&base, EGL_FALSE)) { |
238 | if (!_eglValidateConfig(&base, EGL_FALSE)) { |
239 | _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); |
239 | _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); |
240 | return NULL; |
240 | return NULL; |
241 | } |
241 | } |
242 | 242 | ||
243 | config_id = base.ConfigID; |
243 | config_id = base.ConfigID; |
244 | base.ConfigID = EGL_DONT_CARE; |
244 | base.ConfigID = EGL_DONT_CARE; |
245 | base.SurfaceType = EGL_DONT_CARE; |
245 | base.SurfaceType = EGL_DONT_CARE; |
246 | num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1, |
246 | num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1, |
247 | (_EGLArrayForEach) dri2_match_config, &base); |
247 | (_EGLArrayForEach) dri2_match_config, &base); |
248 | 248 | ||
249 | if (num_configs == 1) { |
249 | if (num_configs == 1) { |
250 | conf = (struct dri2_egl_config *) matching_config; |
250 | conf = (struct dri2_egl_config *) matching_config; |
251 | 251 | ||
252 | if (double_buffer && !conf->dri_double_config) |
252 | if (double_buffer && !conf->dri_double_config) |
253 | conf->dri_double_config = dri_config; |
253 | conf->dri_double_config = dri_config; |
254 | else if (!double_buffer && !conf->dri_single_config) |
254 | else if (!double_buffer && !conf->dri_single_config) |
255 | conf->dri_single_config = dri_config; |
255 | conf->dri_single_config = dri_config; |
256 | else |
256 | else |
257 | /* a similar config type is already added (unlikely) => discard */ |
257 | /* a similar config type is already added (unlikely) => discard */ |
258 | return NULL; |
258 | return NULL; |
259 | } |
259 | } |
260 | else if (num_configs == 0) { |
260 | else if (num_configs == 0) { |
261 | conf = malloc(sizeof *conf); |
261 | conf = malloc(sizeof *conf); |
262 | if (conf == NULL) |
262 | if (conf == NULL) |
263 | return NULL; |
263 | return NULL; |
264 | 264 | ||
265 | memcpy(&conf->base, &base, sizeof base); |
265 | memcpy(&conf->base, &base, sizeof base); |
266 | if (double_buffer) { |
266 | if (double_buffer) { |
267 | conf->dri_double_config = dri_config; |
267 | conf->dri_double_config = dri_config; |
268 | conf->dri_single_config = NULL; |
268 | conf->dri_single_config = NULL; |
269 | } else { |
269 | } else { |
270 | conf->dri_single_config = dri_config; |
270 | conf->dri_single_config = dri_config; |
271 | conf->dri_double_config = NULL; |
271 | conf->dri_double_config = NULL; |
272 | } |
272 | } |
273 | conf->base.SurfaceType = 0; |
273 | conf->base.SurfaceType = 0; |
274 | conf->base.ConfigID = config_id; |
274 | conf->base.ConfigID = config_id; |
275 | 275 | ||
276 | _eglLinkConfig(&conf->base); |
276 | _eglLinkConfig(&conf->base); |
277 | } |
277 | } |
278 | else { |
278 | else { |
279 | assert(0); |
279 | assert(0); |
280 | return NULL; |
280 | return NULL; |
281 | } |
281 | } |
282 | 282 | ||
283 | if (double_buffer) { |
283 | if (double_buffer) { |
284 | surface_type &= ~EGL_PIXMAP_BIT; |
284 | surface_type &= ~EGL_PIXMAP_BIT; |
285 | } |
285 | } |
286 | 286 | ||
287 | conf->base.SurfaceType |= surface_type; |
287 | conf->base.SurfaceType |= surface_type; |
288 | 288 | ||
289 | return conf; |
289 | return conf; |
290 | } |
290 | } |
291 | 291 | ||
292 | __DRIimage * |
292 | __DRIimage * |
293 | dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) |
293 | dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) |
294 | { |
294 | { |
295 | _EGLDisplay *disp = data; |
295 | _EGLDisplay *disp = data; |
296 | struct dri2_egl_image *dri2_img; |
296 | struct dri2_egl_image *dri2_img; |
297 | _EGLImage *img; |
297 | _EGLImage *img; |
298 | 298 | ||
299 | (void) screen; |
299 | (void) screen; |
300 | 300 | ||
301 | img = _eglLookupImage(image, disp); |
301 | img = _eglLookupImage(image, disp); |
302 | if (img == NULL) { |
302 | if (img == NULL) { |
303 | _eglError(EGL_BAD_PARAMETER, "dri2_lookup_egl_image"); |
303 | _eglError(EGL_BAD_PARAMETER, "dri2_lookup_egl_image"); |
304 | return NULL; |
304 | return NULL; |
305 | } |
305 | } |
306 | 306 | ||
307 | dri2_img = dri2_egl_image(image); |
307 | dri2_img = dri2_egl_image(image); |
308 | 308 | ||
309 | return dri2_img->dri_image; |
309 | return dri2_img->dri_image; |
310 | } |
310 | } |
311 | 311 | ||
312 | const __DRIimageLookupExtension image_lookup_extension = { |
312 | const __DRIimageLookupExtension image_lookup_extension = { |
313 | { __DRI_IMAGE_LOOKUP, 1 }, |
313 | { __DRI_IMAGE_LOOKUP, 1 }, |
314 | dri2_lookup_egl_image |
314 | dri2_lookup_egl_image |
315 | }; |
315 | }; |
316 | 316 | ||
317 | static const char dri_driver_path[] = "";//DEFAULT_DRIVER_DIR; |
317 | static const char dri_driver_path[] = "";//DEFAULT_DRIVER_DIR; |
318 | 318 | ||
319 | struct dri2_extension_match { |
319 | struct dri2_extension_match { |
320 | const char *name; |
320 | const char *name; |
321 | int version; |
321 | int version; |
322 | int offset; |
322 | int offset; |
323 | }; |
323 | }; |
324 | 324 | ||
325 | static struct dri2_extension_match dri2_driver_extensions[] = { |
325 | static struct dri2_extension_match dri2_driver_extensions[] = { |
326 | { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, |
326 | { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, |
327 | { __DRI_DRI2, 2, offsetof(struct dri2_egl_display, dri2) }, |
327 | { __DRI_DRI2, 2, offsetof(struct dri2_egl_display, dri2) }, |
328 | { NULL, 0, 0 } |
328 | { NULL, 0, 0 } |
329 | }; |
329 | }; |
330 | 330 | ||
331 | static struct dri2_extension_match dri2_core_extensions[] = { |
331 | static struct dri2_extension_match dri2_core_extensions[] = { |
332 | { __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) }, |
332 | { __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) }, |
333 | { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, |
333 | { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, |
334 | { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) }, |
334 | { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) }, |
335 | { NULL, 0, 0 } |
335 | { NULL, 0, 0 } |
336 | }; |
336 | }; |
337 | 337 | ||
338 | static struct dri2_extension_match swrast_driver_extensions[] = { |
338 | static struct dri2_extension_match swrast_driver_extensions[] = { |
339 | { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, |
339 | { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, |
340 | { __DRI_SWRAST, 2, offsetof(struct dri2_egl_display, swrast) }, |
340 | { __DRI_SWRAST, 2, offsetof(struct dri2_egl_display, swrast) }, |
341 | { NULL, 0, 0 } |
341 | { NULL, 0, 0 } |
342 | }; |
342 | }; |
343 | 343 | ||
344 | static struct dri2_extension_match swrast_core_extensions[] = { |
344 | static struct dri2_extension_match swrast_core_extensions[] = { |
345 | { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, |
345 | { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, |
346 | { NULL, 0, 0 } |
346 | { NULL, 0, 0 } |
347 | }; |
347 | }; |
348 | 348 | ||
349 | static EGLBoolean |
349 | static EGLBoolean |
350 | dri2_bind_extensions(struct dri2_egl_display *dri2_dpy, |
350 | dri2_bind_extensions(struct dri2_egl_display *dri2_dpy, |
351 | struct dri2_extension_match *matches, |
351 | struct dri2_extension_match *matches, |
352 | const __DRIextension **extensions) |
352 | const __DRIextension **extensions) |
353 | { |
353 | { |
354 | int i, j, ret = EGL_TRUE; |
354 | int i, j, ret = EGL_TRUE; |
355 | void *field; |
355 | void *field; |
356 | 356 | ||
357 | for (i = 0; extensions[i]; i++) { |
357 | for (i = 0; extensions[i]; i++) { |
358 | _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name); |
358 | _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name); |
359 | for (j = 0; matches[j].name; j++) { |
359 | for (j = 0; matches[j].name; j++) { |
360 | if (strcmp(extensions[i]->name, matches[j].name) == 0 && |
360 | if (strcmp(extensions[i]->name, matches[j].name) == 0 && |
361 | extensions[i]->version >= matches[j].version) { |
361 | extensions[i]->version >= matches[j].version) { |
362 | field = ((char *) dri2_dpy + matches[j].offset); |
362 | field = ((char *) dri2_dpy + matches[j].offset); |
363 | *(const __DRIextension **) field = extensions[i]; |
363 | *(const __DRIextension **) field = extensions[i]; |
364 | _eglLog(_EGL_INFO, "DRI2: found extension %s version %d", |
364 | _eglLog(_EGL_INFO, "DRI2: found extension %s version %d", |
365 | extensions[i]->name, extensions[i]->version); |
365 | extensions[i]->name, extensions[i]->version); |
366 | } |
366 | } |
367 | } |
367 | } |
368 | } |
368 | } |
369 | 369 | ||
370 | for (j = 0; matches[j].name; j++) { |
370 | for (j = 0; matches[j].name; j++) { |
371 | field = ((char *) dri2_dpy + matches[j].offset); |
371 | field = ((char *) dri2_dpy + matches[j].offset); |
372 | if (*(const __DRIextension **) field == NULL) { |
372 | if (*(const __DRIextension **) field == NULL) { |
373 | _eglLog(_EGL_FATAL, "DRI2: did not find extension %s version %d", |
373 | _eglLog(_EGL_FATAL, "DRI2: did not find extension %s version %d", |
374 | matches[j].name, matches[j].version); |
374 | matches[j].name, matches[j].version); |
375 | ret = EGL_FALSE; |
375 | ret = EGL_FALSE; |
376 | } |
376 | } |
377 | } |
377 | } |
378 | 378 | ||
379 | return ret; |
379 | return ret; |
380 | } |
380 | } |
381 | 381 | ||
382 | #if 0 |
382 | #if 0 |
383 | 383 | ||
384 | static const __DRIextension ** |
384 | static const __DRIextension ** |
385 | dri2_open_driver(_EGLDisplay *disp) |
385 | dri2_open_driver(_EGLDisplay *disp) |
386 | { |
386 | { |
387 | struct dri2_egl_display *dri2_dpy = disp->DriverData; |
387 | struct dri2_egl_display *dri2_dpy = disp->DriverData; |
388 | const __DRIextension **extensions; |
388 | const __DRIextension **extensions; |
389 | char path[PATH_MAX], *search_paths, *p, *next, *end; |
389 | char path[PATH_MAX], *search_paths, *p, *next, *end; |
390 | 390 | ||
391 | search_paths = NULL; |
391 | search_paths = NULL; |
392 | if (geteuid() == getuid()) { |
392 | if (geteuid() == getuid()) { |
393 | /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ |
393 | /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ |
394 | search_paths = getenv("LIBGL_DRIVERS_PATH"); |
394 | search_paths = getenv("LIBGL_DRIVERS_PATH"); |
395 | } |
395 | } |
396 | // if (search_paths == NULL) |
396 | // if (search_paths == NULL) |
397 | // search_paths = DEFAULT_DRIVER_DIR; |
397 | // search_paths = DEFAULT_DRIVER_DIR; |
398 | 398 | ||
399 | dri2_dpy->driver = NULL; |
399 | dri2_dpy->driver = NULL; |
400 | end = search_paths + strlen(search_paths); |
400 | end = search_paths + strlen(search_paths); |
401 | for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) { |
401 | for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) { |
402 | int len; |
402 | int len; |
403 | next = strchr(p, ':'); |
403 | next = strchr(p, ':'); |
404 | if (next == NULL) |
404 | if (next == NULL) |
405 | next = end; |
405 | next = end; |
406 | 406 | ||
407 | len = next - p; |
407 | len = next - p; |
408 | #if GLX_USE_TLS |
408 | #if GLX_USE_TLS |
409 | snprintf(path, sizeof path, |
409 | snprintf(path, sizeof path, |
410 | "%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name); |
410 | "%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name); |
411 | dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); |
411 | dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); |
412 | #endif |
412 | #endif |
413 | if (dri2_dpy->driver == NULL) { |
413 | if (dri2_dpy->driver == NULL) { |
414 | snprintf(path, sizeof path, |
414 | snprintf(path, sizeof path, |
415 | "%.*s/%s_dri.so", len, p, dri2_dpy->driver_name); |
415 | "%.*s/%s_dri.so", len, p, dri2_dpy->driver_name); |
416 | dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); |
416 | dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); |
417 | if (dri2_dpy->driver == NULL) |
417 | if (dri2_dpy->driver == NULL) |
418 | _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror()); |
418 | _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror()); |
419 | } |
419 | } |
420 | } |
420 | } |
421 | 421 | ||
422 | if (dri2_dpy->driver == NULL) { |
422 | if (dri2_dpy->driver == NULL) { |
423 | _eglLog(_EGL_WARNING, |
423 | _eglLog(_EGL_WARNING, |
424 | "DRI2: failed to open %s (search paths %s)", |
424 | "DRI2: failed to open %s (search paths %s)", |
425 | dri2_dpy->driver_name, search_paths); |
425 | dri2_dpy->driver_name, search_paths); |
426 | return NULL; |
426 | return NULL; |
427 | } |
427 | } |
428 | 428 | ||
429 | _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); |
429 | _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); |
430 | extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS); |
430 | extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS); |
431 | if (extensions == NULL) { |
431 | if (extensions == NULL) { |
432 | _eglLog(_EGL_WARNING, |
432 | _eglLog(_EGL_WARNING, |
433 | "DRI2: driver exports no extensions (%s)", dlerror()); |
433 | "DRI2: driver exports no extensions (%s)", dlerror()); |
434 | dlclose(dri2_dpy->driver); |
434 | dlclose(dri2_dpy->driver); |
435 | } |
435 | } |
436 | 436 | ||
437 | return extensions; |
437 | return extensions; |
438 | } |
438 | } |
439 | 439 | ||
440 | EGLBoolean |
440 | EGLBoolean |
441 | dri2_load_driver(_EGLDisplay *disp) |
441 | dri2_load_driver(_EGLDisplay *disp) |
442 | { |
442 | { |
443 | struct dri2_egl_display *dri2_dpy = disp->DriverData; |
443 | struct dri2_egl_display *dri2_dpy = disp->DriverData; |
444 | const __DRIextension **extensions; |
444 | const __DRIextension **extensions; |
445 | 445 | ||
446 | extensions = dri2_open_driver(disp); |
446 | extensions = dri2_open_driver(disp); |
447 | if (!extensions) |
447 | if (!extensions) |
448 | return EGL_FALSE; |
448 | return EGL_FALSE; |
449 | 449 | ||
450 | if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) { |
450 | if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) { |
451 | dlclose(dri2_dpy->driver); |
451 | dlclose(dri2_dpy->driver); |
452 | return EGL_FALSE; |
452 | return EGL_FALSE; |
453 | } |
453 | } |
454 | 454 | ||
455 | return EGL_TRUE; |
455 | return EGL_TRUE; |
456 | } |
456 | } |
457 | 457 | ||
458 | EGLBoolean |
458 | EGLBoolean |
459 | dri2_load_driver_swrast(_EGLDisplay *disp) |
459 | dri2_load_driver_swrast(_EGLDisplay *disp) |
460 | { |
460 | { |
461 | struct dri2_egl_display *dri2_dpy = disp->DriverData; |
461 | struct dri2_egl_display *dri2_dpy = disp->DriverData; |
462 | const __DRIextension **extensions; |
462 | const __DRIextension **extensions; |
463 | 463 | ||
464 | dri2_dpy->driver_name = "swrast"; |
464 | dri2_dpy->driver_name = "swrast"; |
465 | extensions = dri2_open_driver(disp); |
465 | extensions = dri2_open_driver(disp); |
466 | 466 | ||
467 | if (!extensions) |
467 | if (!extensions) |
468 | return EGL_FALSE; |
468 | return EGL_FALSE; |
469 | 469 | ||
470 | if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions)) { |
470 | if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions)) { |
471 | dlclose(dri2_dpy->driver); |
471 | dlclose(dri2_dpy->driver); |
472 | return EGL_FALSE; |
472 | return EGL_FALSE; |
473 | } |
473 | } |
474 | 474 | ||
475 | return EGL_TRUE; |
475 | return EGL_TRUE; |
476 | } |
476 | } |
477 | #endif |
477 | #endif |
478 | 478 | ||
479 | void |
479 | void |
480 | dri2_setup_screen(_EGLDisplay *disp) |
480 | dri2_setup_screen(_EGLDisplay *disp) |
481 | { |
481 | { |
482 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
482 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
483 | unsigned int api_mask; |
483 | unsigned int api_mask; |
484 | 484 | ||
485 | if (dri2_dpy->dri2) { |
485 | if (dri2_dpy->dri2) { |
486 | api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen); |
486 | api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen); |
487 | } else { |
487 | } else { |
488 | assert(dri2_dpy->swrast); |
488 | assert(dri2_dpy->swrast); |
489 | api_mask = 1 << __DRI_API_OPENGL | |
489 | api_mask = 1 << __DRI_API_OPENGL | |
490 | 1 << __DRI_API_GLES | |
490 | 1 << __DRI_API_GLES | |
491 | 1 << __DRI_API_GLES2 | |
491 | 1 << __DRI_API_GLES2 | |
492 | 1 << __DRI_API_GLES3; |
492 | 1 << __DRI_API_GLES3; |
493 | } |
493 | } |
494 | 494 | ||
495 | disp->ClientAPIs = 0; |
495 | disp->ClientAPIs = 0; |
496 | if (api_mask & (1 <<__DRI_API_OPENGL)) |
496 | if (api_mask & (1 <<__DRI_API_OPENGL)) |
497 | disp->ClientAPIs |= EGL_OPENGL_BIT; |
497 | disp->ClientAPIs |= EGL_OPENGL_BIT; |
498 | if (api_mask & (1 <<__DRI_API_GLES)) |
498 | if (api_mask & (1 <<__DRI_API_GLES)) |
499 | disp->ClientAPIs |= EGL_OPENGL_ES_BIT; |
499 | disp->ClientAPIs |= EGL_OPENGL_ES_BIT; |
500 | if (api_mask & (1 << __DRI_API_GLES2)) |
500 | if (api_mask & (1 << __DRI_API_GLES2)) |
501 | disp->ClientAPIs |= EGL_OPENGL_ES2_BIT; |
501 | disp->ClientAPIs |= EGL_OPENGL_ES2_BIT; |
502 | if (api_mask & (1 << __DRI_API_GLES3)) |
502 | if (api_mask & (1 << __DRI_API_GLES3)) |
503 | disp->ClientAPIs |= EGL_OPENGL_ES3_BIT_KHR; |
503 | disp->ClientAPIs |= EGL_OPENGL_ES3_BIT_KHR; |
504 | 504 | ||
505 | assert(dri2_dpy->dri2 || dri2_dpy->swrast); |
505 | assert(dri2_dpy->dri2 || dri2_dpy->swrast); |
506 | disp->Extensions.KHR_surfaceless_context = EGL_TRUE; |
506 | disp->Extensions.KHR_surfaceless_context = EGL_TRUE; |
507 | 507 | ||
508 | disp->Extensions.MESA_screen_surface = EGL_TRUE; |
508 | disp->Extensions.MESA_screen_surface = EGL_TRUE; |
509 | 509 | ||
510 | if (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) { |
510 | if (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) { |
511 | disp->Extensions.KHR_create_context = EGL_TRUE; |
511 | disp->Extensions.KHR_create_context = EGL_TRUE; |
512 | 512 | ||
513 | if (dri2_dpy->robustness) |
513 | if (dri2_dpy->robustness) |
514 | disp->Extensions.EXT_create_context_robustness = EGL_TRUE; |
514 | disp->Extensions.EXT_create_context_robustness = EGL_TRUE; |
515 | } |
515 | } |
516 | 516 | ||
517 | if (dri2_dpy->image) { |
517 | if (dri2_dpy->image) { |
518 | disp->Extensions.MESA_drm_image = EGL_TRUE; |
518 | disp->Extensions.MESA_drm_image = EGL_TRUE; |
519 | disp->Extensions.KHR_image_base = EGL_TRUE; |
519 | disp->Extensions.KHR_image_base = EGL_TRUE; |
520 | disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; |
520 | disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; |
521 | if (dri2_dpy->image->base.version >= 5 && |
521 | if (dri2_dpy->image->base.version >= 5 && |
522 | dri2_dpy->image->createImageFromTexture) { |
522 | dri2_dpy->image->createImageFromTexture) { |
523 | disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE; |
523 | disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE; |
524 | disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE; |
524 | disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE; |
525 | } |
525 | } |
526 | } |
526 | } |
527 | { |
527 | { |
528 | _EGLMode *mode; |
528 | _EGLMode *mode; |
529 | _EGLScreen *screen = malloc(sizeof(*screen)); |
529 | _EGLScreen *screen = malloc(sizeof(*screen)); |
530 | 530 | ||
531 | _eglInitScreen(screen, disp, 3); |
531 | _eglInitScreen(screen, disp, 3); |
532 | mode = &screen->Modes[0]; |
532 | mode = &screen->Modes[0]; |
533 | mode->Width = 800; |
533 | mode->Width = 800; |
534 | mode->Height = 600; |
534 | mode->Height = 600; |
535 | mode->RefreshRate = 60; |
535 | mode->RefreshRate = 60; |
536 | mode->Optimal = EGL_FALSE; |
536 | mode->Optimal = EGL_FALSE; |
537 | mode->Interlaced = EGL_FALSE; |
537 | mode->Interlaced = EGL_FALSE; |
538 | mode->Name = "800 x 600 60Hz"; |
538 | mode->Name = "800 x 600 60Hz"; |
539 | 539 | ||
540 | 540 | ||
541 | mode = &screen->Modes[1]; |
541 | mode = &screen->Modes[1]; |
542 | mode->Width = 1024; |
542 | mode->Width = 1024; |
543 | mode->Height = 768; |
543 | mode->Height = 768; |
544 | mode->RefreshRate = 60; |
544 | mode->RefreshRate = 60; |
545 | mode->Optimal = EGL_FALSE; |
545 | mode->Optimal = EGL_FALSE; |
546 | mode->Interlaced = EGL_FALSE; |
546 | mode->Interlaced = EGL_FALSE; |
547 | mode->Name = "1024 x 768 60Hz"; |
547 | mode->Name = "1024 x 768 60Hz"; |
548 | 548 | ||
549 | mode = &screen->Modes[2]; |
549 | mode = &screen->Modes[2]; |
550 | mode->Width = 1280; |
550 | mode->Width = 1280; |
551 | mode->Height = 1024; |
551 | mode->Height = 1024; |
552 | mode->RefreshRate = 60; |
552 | mode->RefreshRate = 60; |
553 | mode->Optimal = EGL_FALSE; |
553 | mode->Optimal = EGL_FALSE; |
554 | mode->Interlaced = EGL_FALSE; |
554 | mode->Interlaced = EGL_FALSE; |
555 | mode->Name = "1280 x 1024 60Hz"; |
555 | mode->Name = "1280 x 1024 60Hz"; |
556 | 556 | ||
557 | _eglLinkScreen(screen); |
557 | _eglLinkScreen(screen); |
558 | } |
558 | } |
559 | } |
559 | } |
560 | 560 | ||
561 | EGLBoolean |
561 | EGLBoolean |
562 | dri2_create_screen(_EGLDisplay *disp) |
562 | dri2_create_screen(_EGLDisplay *disp) |
563 | { |
563 | { |
564 | const __DRIextension **extensions; |
564 | const __DRIextension **extensions; |
565 | struct dri2_egl_display *dri2_dpy; |
565 | struct dri2_egl_display *dri2_dpy; |
566 | 566 | ||
567 | dri2_dpy = disp->DriverData; |
567 | dri2_dpy = disp->DriverData; |
568 | 568 | ||
569 | if (dri2_dpy->dri2) { |
569 | if (dri2_dpy->dri2) { |
570 | dri2_dpy->dri_screen = |
570 | dri2_dpy->dri_screen = |
571 | dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, |
571 | dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, |
572 | &dri2_dpy->driver_configs, disp); |
572 | &dri2_dpy->driver_configs, disp); |
573 | } else { |
573 | } else { |
574 | assert(dri2_dpy->swrast); |
574 | assert(dri2_dpy->swrast); |
575 | dri2_dpy->dri_screen = |
575 | dri2_dpy->dri_screen = |
576 | dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, |
576 | dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, |
577 | &dri2_dpy->driver_configs, disp); |
577 | &dri2_dpy->driver_configs, disp); |
578 | } |
578 | } |
579 | 579 | ||
580 | if (dri2_dpy->dri_screen == NULL) { |
580 | if (dri2_dpy->dri_screen == NULL) { |
581 | _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); |
581 | _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); |
582 | return EGL_FALSE; |
582 | return EGL_FALSE; |
583 | } |
583 | } |
584 | 584 | ||
585 | dri2_dpy->own_dri_screen = 1; |
585 | dri2_dpy->own_dri_screen = 1; |
586 | 586 | ||
587 | extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); |
587 | extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); |
588 | 588 | ||
589 | if (dri2_dpy->dri2) { |
589 | if (dri2_dpy->dri2) { |
590 | unsigned i; |
590 | unsigned i; |
591 | 591 | ||
592 | if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) |
592 | if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) |
593 | goto cleanup_dri_screen; |
593 | goto cleanup_dri_screen; |
594 | 594 | ||
595 | for (i = 0; extensions[i]; i++) { |
595 | for (i = 0; extensions[i]; i++) { |
596 | if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { |
596 | if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { |
597 | dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; |
597 | dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; |
598 | } |
598 | } |
599 | if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) { |
599 | if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) { |
600 | dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i]; |
600 | dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i]; |
601 | } |
601 | } |
602 | } |
602 | } |
603 | } else { |
603 | } else { |
604 | assert(dri2_dpy->swrast); |
604 | assert(dri2_dpy->swrast); |
605 | if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) |
605 | if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) |
606 | goto cleanup_dri_screen; |
606 | goto cleanup_dri_screen; |
607 | } |
607 | } |
608 | 608 | ||
609 | dri2_setup_screen(disp); |
609 | dri2_setup_screen(disp); |
610 | 610 | ||
611 | return EGL_TRUE; |
611 | return EGL_TRUE; |
612 | 612 | ||
613 | cleanup_dri_screen: |
613 | cleanup_dri_screen: |
614 | dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); |
614 | dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); |
615 | 615 | ||
616 | return EGL_FALSE; |
616 | return EGL_FALSE; |
617 | } |
617 | } |
618 | 618 | ||
619 | /** |
619 | /** |
620 | * Called via eglInitialize(), GLX_drv->API.Initialize(). |
620 | * Called via eglInitialize(), GLX_drv->API.Initialize(). |
621 | */ |
621 | */ |
622 | static EGLBoolean |
622 | static EGLBoolean |
623 | dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) |
623 | dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) |
624 | { |
624 | { |
625 | /* not until swrast_dri is supported */ |
625 | /* not until swrast_dri is supported */ |
626 | if (disp->Options.UseFallback) |
626 | if (disp->Options.UseFallback) |
627 | return EGL_FALSE; |
627 | return EGL_FALSE; |
628 | 628 | ||
629 | return dri2_initialize_drm(drv, disp); |
629 | return dri2_initialize_drm(drv, disp); |
630 | 630 | ||
631 | #if 0 |
631 | #if 0 |
632 | switch (disp->Platform) { |
632 | switch (disp->Platform) { |
633 | #ifdef HAVE_X11_PLATFORM |
633 | #ifdef HAVE_X11_PLATFORM |
634 | case _EGL_PLATFORM_X11: |
634 | case _EGL_PLATFORM_X11: |
635 | if (disp->Options.TestOnly) |
635 | if (disp->Options.TestOnly) |
636 | return EGL_TRUE; |
636 | return EGL_TRUE; |
637 | return dri2_initialize_x11(drv, disp); |
637 | return dri2_initialize_x11(drv, disp); |
638 | #endif |
638 | #endif |
639 | 639 | ||
640 | #ifdef HAVE_LIBUDEV |
640 | #ifdef HAVE_LIBUDEV |
641 | #ifdef HAVE_DRM_PLATFORM |
641 | #ifdef HAVE_DRM_PLATFORM |
642 | case _EGL_PLATFORM_DRM: |
642 | case _EGL_PLATFORM_DRM: |
643 | if (disp->Options.TestOnly) |
643 | if (disp->Options.TestOnly) |
644 | return EGL_TRUE; |
644 | return EGL_TRUE; |
645 | return dri2_initialize_drm(drv, disp); |
645 | return dri2_initialize_drm(drv, disp); |
646 | #endif |
646 | #endif |
647 | #ifdef HAVE_WAYLAND_PLATFORM |
647 | #ifdef HAVE_WAYLAND_PLATFORM |
648 | case _EGL_PLATFORM_WAYLAND: |
648 | case _EGL_PLATFORM_WAYLAND: |
649 | if (disp->Options.TestOnly) |
649 | if (disp->Options.TestOnly) |
650 | return EGL_TRUE; |
650 | return EGL_TRUE; |
651 | return dri2_initialize_wayland(drv, disp); |
651 | return dri2_initialize_wayland(drv, disp); |
652 | #endif |
652 | #endif |
653 | #endif |
653 | #endif |
654 | #ifdef HAVE_ANDROID_PLATFORM |
654 | #ifdef HAVE_ANDROID_PLATFORM |
655 | case _EGL_PLATFORM_ANDROID: |
655 | case _EGL_PLATFORM_ANDROID: |
656 | if (disp->Options.TestOnly) |
656 | if (disp->Options.TestOnly) |
657 | return EGL_TRUE; |
657 | return EGL_TRUE; |
658 | return dri2_initialize_android(drv, disp); |
658 | return dri2_initialize_android(drv, disp); |
659 | #endif |
659 | #endif |
660 | 660 | ||
661 | default: |
661 | default: |
662 | return EGL_FALSE; |
662 | return EGL_FALSE; |
663 | } |
663 | } |
664 | #endif |
664 | #endif |
665 | } |
665 | } |
666 | 666 | ||
667 | /** |
667 | /** |
668 | * Called via eglTerminate(), drv->API.Terminate(). |
668 | * Called via eglTerminate(), drv->API.Terminate(). |
669 | */ |
669 | */ |
670 | static EGLBoolean |
670 | static EGLBoolean |
671 | dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) |
671 | dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) |
672 | { |
672 | { |
673 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
673 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
674 | 674 | ||
675 | _eglReleaseDisplayResources(drv, disp); |
675 | _eglReleaseDisplayResources(drv, disp); |
676 | _eglCleanupDisplay(disp); |
676 | _eglCleanupDisplay(disp); |
677 | 677 | ||
678 | if (dri2_dpy->own_dri_screen) |
678 | if (dri2_dpy->own_dri_screen) |
679 | dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); |
679 | dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); |
680 | // if (dri2_dpy->fd) |
680 | // if (dri2_dpy->fd) |
681 | // close(dri2_dpy->fd); |
681 | // close(dri2_dpy->fd); |
682 | // if (dri2_dpy->driver) |
682 | // if (dri2_dpy->driver) |
683 | // dlclose(dri2_dpy->driver); |
683 | // dlclose(dri2_dpy->driver); |
684 | free(dri2_dpy->device_name); |
684 | free(dri2_dpy->device_name); |
685 | 685 | ||
686 | if (disp->PlatformDisplay == NULL) { |
686 | if (disp->PlatformDisplay == NULL) { |
687 | switch (disp->Platform) { |
687 | switch (disp->Platform) { |
688 | #ifdef HAVE_X11_PLATFORM |
688 | #ifdef HAVE_X11_PLATFORM |
689 | case _EGL_PLATFORM_X11: |
689 | case _EGL_PLATFORM_X11: |
690 | xcb_disconnect(dri2_dpy->conn); |
690 | xcb_disconnect(dri2_dpy->conn); |
691 | break; |
691 | break; |
692 | #endif |
692 | #endif |
693 | #ifdef HAVE_DRM_PLATFORM |
693 | #ifdef HAVE_DRM_PLATFORM |
694 | case _EGL_PLATFORM_DRM: |
694 | case _EGL_PLATFORM_DRM: |
695 | if (dri2_dpy->own_device) { |
695 | if (dri2_dpy->own_device) { |
696 | gbm_device_destroy(&dri2_dpy->gbm_dri->base.base); |
696 | gbm_device_destroy(&dri2_dpy->gbm_dri->base.base); |
697 | } |
697 | } |
698 | break; |
698 | break; |
699 | #endif |
699 | #endif |
700 | default: |
700 | default: |
701 | break; |
701 | break; |
702 | } |
702 | } |
703 | } |
703 | } |
704 | 704 | ||
705 | free(dri2_dpy); |
705 | free(dri2_dpy); |
706 | disp->DriverData = NULL; |
706 | disp->DriverData = NULL; |
707 | 707 | ||
708 | return EGL_TRUE; |
708 | return EGL_TRUE; |
709 | } |
709 | } |
710 | 710 | ||
711 | /** |
711 | /** |
712 | * Set the error code after a call to |
712 | * Set the error code after a call to |
713 | * dri2_egl_display::dri2::createContextAttribs. |
713 | * dri2_egl_display::dri2::createContextAttribs. |
714 | */ |
714 | */ |
715 | static void |
715 | static void |
716 | dri2_create_context_attribs_error(int dri_error) |
716 | dri2_create_context_attribs_error(int dri_error) |
717 | { |
717 | { |
718 | EGLint egl_error; |
718 | EGLint egl_error; |
719 | 719 | ||
720 | switch (dri_error) { |
720 | switch (dri_error) { |
721 | case __DRI_CTX_ERROR_SUCCESS: |
721 | case __DRI_CTX_ERROR_SUCCESS: |
722 | return; |
722 | return; |
723 | 723 | ||
724 | case __DRI_CTX_ERROR_NO_MEMORY: |
724 | case __DRI_CTX_ERROR_NO_MEMORY: |
725 | egl_error = EGL_BAD_ALLOC; |
725 | egl_error = EGL_BAD_ALLOC; |
726 | break; |
726 | break; |
727 | 727 | ||
728 | /* From the EGL_KHR_create_context spec, section "Errors": |
728 | /* From the EGL_KHR_create_context spec, section "Errors": |
729 | * |
729 | * |
730 | * * If |
730 | * * If |
731 | * with the requested API major and minor version, [...] context flags, |
731 | * with the requested API major and minor version, [...] context flags, |
732 | * and context reset notification behavior (for client API types where |
732 | * and context reset notification behavior (for client API types where |
733 | * these attributes are supported), then an EGL_BAD_MATCH error is |
733 | * these attributes are supported), then an EGL_BAD_MATCH error is |
734 | * generated. |
734 | * generated. |
735 | * |
735 | * |
736 | * * If an OpenGL ES context is requested and the values for |
736 | * * If an OpenGL ES context is requested and the values for |
737 | * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and |
737 | * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and |
738 | * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that |
738 | * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that |
739 | * is not defined, than an EGL_BAD_MATCH error is generated. |
739 | * is not defined, than an EGL_BAD_MATCH error is generated. |
740 | * |
740 | * |
741 | * * If an OpenGL context is requested, the requested version is |
741 | * * If an OpenGL context is requested, the requested version is |
742 | * greater than 3.2, and the value for attribute |
742 | * greater than 3.2, and the value for attribute |
743 | * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has any |
743 | * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has any |
744 | * bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR and |
744 | * bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR and |
745 | * EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has more than |
745 | * EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has more than |
746 | * one of these bits set; or if the implementation does not support |
746 | * one of these bits set; or if the implementation does not support |
747 | * the requested profile, then an EGL_BAD_MATCH error is generated. |
747 | * the requested profile, then an EGL_BAD_MATCH error is generated. |
748 | */ |
748 | */ |
749 | case __DRI_CTX_ERROR_BAD_API: |
749 | case __DRI_CTX_ERROR_BAD_API: |
750 | case __DRI_CTX_ERROR_BAD_VERSION: |
750 | case __DRI_CTX_ERROR_BAD_VERSION: |
751 | case __DRI_CTX_ERROR_BAD_FLAG: |
751 | case __DRI_CTX_ERROR_BAD_FLAG: |
752 | egl_error = EGL_BAD_MATCH; |
752 | egl_error = EGL_BAD_MATCH; |
753 | break; |
753 | break; |
754 | 754 | ||
755 | /* From the EGL_KHR_create_context spec, section "Errors": |
755 | /* From the EGL_KHR_create_context spec, section "Errors": |
756 | * |
756 | * |
757 | * * If an attribute name or attribute value in |
757 | * * If an attribute name or attribute value in |
758 | * recognized (including unrecognized bits in bitmask attributes), |
758 | * recognized (including unrecognized bits in bitmask attributes), |
759 | * then an EGL_BAD_ATTRIBUTE error is generated." |
759 | * then an EGL_BAD_ATTRIBUTE error is generated." |
760 | */ |
760 | */ |
761 | case __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE: |
761 | case __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE: |
762 | case __DRI_CTX_ERROR_UNKNOWN_FLAG: |
762 | case __DRI_CTX_ERROR_UNKNOWN_FLAG: |
763 | egl_error = EGL_BAD_ATTRIBUTE; |
763 | egl_error = EGL_BAD_ATTRIBUTE; |
764 | break; |
764 | break; |
765 | 765 | ||
766 | default: |
766 | default: |
767 | assert(0); |
767 | assert(0); |
768 | egl_error = EGL_BAD_MATCH; |
768 | egl_error = EGL_BAD_MATCH; |
769 | break; |
769 | break; |
770 | } |
770 | } |
771 | 771 | ||
772 | _eglError(egl_error, "dri2_create_context"); |
772 | _eglError(egl_error, "dri2_create_context"); |
773 | } |
773 | } |
774 | 774 | ||
775 | /** |
775 | /** |
776 | * Called via eglCreateContext(), drv->API.CreateContext(). |
776 | * Called via eglCreateContext(), drv->API.CreateContext(). |
777 | */ |
777 | */ |
778 | static _EGLContext * |
778 | static _EGLContext * |
779 | dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, |
779 | dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, |
780 | _EGLContext *share_list, const EGLint *attrib_list) |
780 | _EGLContext *share_list, const EGLint *attrib_list) |
781 | { |
781 | { |
782 | struct dri2_egl_context *dri2_ctx; |
782 | struct dri2_egl_context *dri2_ctx; |
783 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
783 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
784 | struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list); |
784 | struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list); |
785 | __DRIcontext *shared = |
785 | __DRIcontext *shared = |
786 | dri2_ctx_shared ? dri2_ctx_shared->dri_context : NULL; |
786 | dri2_ctx_shared ? dri2_ctx_shared->dri_context : NULL; |
787 | struct dri2_egl_config *dri2_config = dri2_egl_config(conf); |
787 | struct dri2_egl_config *dri2_config = dri2_egl_config(conf); |
788 | const __DRIconfig *dri_config; |
788 | const __DRIconfig *dri_config; |
789 | int api; |
789 | int api; |
790 | 790 | ||
791 | (void) drv; |
791 | (void) drv; |
792 | 792 | ||
793 | dri2_ctx = malloc(sizeof *dri2_ctx); |
793 | dri2_ctx = malloc(sizeof *dri2_ctx); |
794 | if (!dri2_ctx) { |
794 | if (!dri2_ctx) { |
795 | _eglError(EGL_BAD_ALLOC, "eglCreateContext"); |
795 | _eglError(EGL_BAD_ALLOC, "eglCreateContext"); |
796 | return NULL; |
796 | return NULL; |
797 | } |
797 | } |
798 | 798 | ||
799 | if (!_eglInitContext(&dri2_ctx->base, disp, conf, attrib_list)) |
799 | if (!_eglInitContext(&dri2_ctx->base, disp, conf, attrib_list)) |
800 | goto cleanup; |
800 | goto cleanup; |
801 | 801 | ||
802 | switch (dri2_ctx->base.ClientAPI) { |
802 | switch (dri2_ctx->base.ClientAPI) { |
803 | case EGL_OPENGL_ES_API: |
803 | case EGL_OPENGL_ES_API: |
804 | switch (dri2_ctx->base.ClientMajorVersion) { |
804 | switch (dri2_ctx->base.ClientMajorVersion) { |
805 | case 1: |
805 | case 1: |
806 | api = __DRI_API_GLES; |
806 | api = __DRI_API_GLES; |
807 | break; |
807 | break; |
808 | case 2: |
808 | case 2: |
809 | api = __DRI_API_GLES2; |
809 | api = __DRI_API_GLES2; |
810 | break; |
810 | break; |
811 | case 3: |
811 | case 3: |
812 | api = __DRI_API_GLES3; |
812 | api = __DRI_API_GLES3; |
813 | break; |
813 | break; |
814 | default: |
814 | default: |
815 | _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); |
815 | _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); |
816 | return NULL; |
816 | return NULL; |
817 | } |
817 | } |
818 | break; |
818 | break; |
819 | case EGL_OPENGL_API: |
819 | case EGL_OPENGL_API: |
820 | if ((dri2_ctx->base.ClientMajorVersion >= 4 |
820 | if ((dri2_ctx->base.ClientMajorVersion >= 4 |
821 | || (dri2_ctx->base.ClientMajorVersion == 3 |
821 | || (dri2_ctx->base.ClientMajorVersion == 3 |
822 | && dri2_ctx->base.ClientMinorVersion >= 2)) |
822 | && dri2_ctx->base.ClientMinorVersion >= 2)) |
823 | && dri2_ctx->base.Profile == EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) |
823 | && dri2_ctx->base.Profile == EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) |
824 | api = __DRI_API_OPENGL_CORE; |
824 | api = __DRI_API_OPENGL_CORE; |
825 | else |
825 | else |
826 | api = __DRI_API_OPENGL; |
826 | api = __DRI_API_OPENGL; |
827 | break; |
827 | break; |
828 | default: |
828 | default: |
829 | _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); |
829 | _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); |
830 | free(dri2_ctx); |
830 | free(dri2_ctx); |
831 | return NULL; |
831 | return NULL; |
832 | } |
832 | } |
833 | 833 | ||
834 | if (conf != NULL) { |
834 | if (conf != NULL) { |
835 | /* The config chosen here isn't necessarily |
835 | /* The config chosen here isn't necessarily |
836 | * used for surfaces later. |
836 | * used for surfaces later. |
837 | * A pixmap surface will use the single config. |
837 | * A pixmap surface will use the single config. |
838 | * This opportunity depends on disabling the |
838 | * This opportunity depends on disabling the |
839 | * doubleBufferMode check in |
839 | * doubleBufferMode check in |
840 | * src/mesa/main/context.c:check_compatible() |
840 | * src/mesa/main/context.c:check_compatible() |
841 | */ |
841 | */ |
842 | if (dri2_config->dri_double_config) |
842 | if (dri2_config->dri_double_config) |
843 | dri_config = dri2_config->dri_double_config; |
843 | dri_config = dri2_config->dri_double_config; |
844 | else |
844 | else |
845 | dri_config = dri2_config->dri_single_config; |
845 | dri_config = dri2_config->dri_single_config; |
846 | 846 | ||
847 | /* EGL_WINDOW_BIT is set only when there is a dri_double_config. This |
847 | /* EGL_WINDOW_BIT is set only when there is a dri_double_config. This |
848 | * makes sure the back buffer will always be used. |
848 | * makes sure the back buffer will always be used. |
849 | */ |
849 | */ |
850 | if (conf->SurfaceType & EGL_WINDOW_BIT) |
850 | if (conf->SurfaceType & EGL_WINDOW_BIT) |
851 | dri2_ctx->base.WindowRenderBuffer = EGL_BACK_BUFFER; |
851 | dri2_ctx->base.WindowRenderBuffer = EGL_BACK_BUFFER; |
852 | } |
852 | } |
853 | else |
853 | else |
854 | dri_config = NULL; |
854 | dri_config = NULL; |
855 | 855 | ||
856 | if (dri2_dpy->dri2) { |
856 | if (dri2_dpy->dri2) { |
857 | if (dri2_dpy->dri2->base.version >= 3) { |
857 | if (dri2_dpy->dri2->base.version >= 3) { |
858 | unsigned error; |
858 | unsigned error; |
859 | unsigned num_attribs = 0; |
859 | unsigned num_attribs = 0; |
860 | uint32_t ctx_attribs[8]; |
860 | uint32_t ctx_attribs[8]; |
861 | 861 | ||
862 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; |
862 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; |
863 | ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMajorVersion; |
863 | ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMajorVersion; |
864 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION; |
864 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION; |
865 | ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMinorVersion; |
865 | ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMinorVersion; |
866 | 866 | ||
867 | if (dri2_ctx->base.Flags != 0) { |
867 | if (dri2_ctx->base.Flags != 0) { |
868 | /* If the implementation doesn't support the __DRI2_ROBUSTNESS |
868 | /* If the implementation doesn't support the __DRI2_ROBUSTNESS |
869 | * extension, don't even try to send it the robust-access flag. |
869 | * extension, don't even try to send it the robust-access flag. |
870 | * It may explode. Instead, generate the required EGL error here. |
870 | * It may explode. Instead, generate the required EGL error here. |
871 | */ |
871 | */ |
872 | if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0 |
872 | if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0 |
873 | && !dri2_dpy->robustness) { |
873 | && !dri2_dpy->robustness) { |
874 | _eglError(EGL_BAD_MATCH, "eglCreateContext"); |
874 | _eglError(EGL_BAD_MATCH, "eglCreateContext"); |
875 | goto cleanup; |
875 | goto cleanup; |
876 | } |
876 | } |
877 | 877 | ||
878 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_FLAGS; |
878 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_FLAGS; |
879 | ctx_attribs[num_attribs++] = dri2_ctx->base.Flags; |
879 | ctx_attribs[num_attribs++] = dri2_ctx->base.Flags; |
880 | } |
880 | } |
881 | 881 | ||
882 | if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) { |
882 | if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) { |
883 | /* If the implementation doesn't support the __DRI2_ROBUSTNESS |
883 | /* If the implementation doesn't support the __DRI2_ROBUSTNESS |
884 | * extension, don't even try to send it a reset strategy. It may |
884 | * extension, don't even try to send it a reset strategy. It may |
885 | * explode. Instead, generate the required EGL error here. |
885 | * explode. Instead, generate the required EGL error here. |
886 | */ |
886 | */ |
887 | if (!dri2_dpy->robustness) { |
887 | if (!dri2_dpy->robustness) { |
888 | _eglError(EGL_BAD_CONFIG, "eglCreateContext"); |
888 | _eglError(EGL_BAD_CONFIG, "eglCreateContext"); |
889 | goto cleanup; |
889 | goto cleanup; |
890 | } |
890 | } |
891 | 891 | ||
892 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY; |
892 | ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY; |
893 | ctx_attribs[num_attribs++] = __DRI_CTX_RESET_LOSE_CONTEXT; |
893 | ctx_attribs[num_attribs++] = __DRI_CTX_RESET_LOSE_CONTEXT; |
894 | } |
894 | } |
895 | 895 | ||
896 | assert(num_attribs <= ARRAY_SIZE(ctx_attribs)); |
896 | assert(num_attribs <= ARRAY_SIZE(ctx_attribs)); |
897 | 897 | ||
898 | dri2_ctx->dri_context = |
898 | dri2_ctx->dri_context = |
899 | dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen, |
899 | dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen, |
900 | api, |
900 | api, |
901 | dri_config, |
901 | dri_config, |
902 | shared, |
902 | shared, |
903 | num_attribs / 2, |
903 | num_attribs / 2, |
904 | ctx_attribs, |
904 | ctx_attribs, |
905 | & error, |
905 | & error, |
906 | dri2_ctx); |
906 | dri2_ctx); |
907 | dri2_create_context_attribs_error(error); |
907 | dri2_create_context_attribs_error(error); |
908 | } else { |
908 | } else { |
909 | dri2_ctx->dri_context = |
909 | dri2_ctx->dri_context = |
910 | dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen, |
910 | dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen, |
911 | api, |
911 | api, |
912 | dri_config, |
912 | dri_config, |
913 | shared, |
913 | shared, |
914 | dri2_ctx); |
914 | dri2_ctx); |
915 | } |
915 | } |
916 | } else { |
916 | } else { |
917 | assert(dri2_dpy->swrast); |
917 | assert(dri2_dpy->swrast); |
918 | dri2_ctx->dri_context = |
918 | dri2_ctx->dri_context = |
919 | dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen, |
919 | dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen, |
920 | api, |
920 | api, |
921 | dri_config, |
921 | dri_config, |
922 | shared, |
922 | shared, |
923 | dri2_ctx); |
923 | dri2_ctx); |
924 | } |
924 | } |
925 | 925 | ||
926 | if (!dri2_ctx->dri_context) |
926 | if (!dri2_ctx->dri_context) |
927 | goto cleanup; |
927 | goto cleanup; |
928 | 928 | ||
929 | return &dri2_ctx->base; |
929 | return &dri2_ctx->base; |
930 | 930 | ||
931 | cleanup: |
931 | cleanup: |
932 | free(dri2_ctx); |
932 | free(dri2_ctx); |
933 | return NULL; |
933 | return NULL; |
934 | } |
934 | } |
935 | 935 | ||
936 | /** |
936 | /** |
937 | * Called via eglDestroyContext(), drv->API.DestroyContext(). |
937 | * Called via eglDestroyContext(), drv->API.DestroyContext(). |
938 | */ |
938 | */ |
939 | static EGLBoolean |
939 | static EGLBoolean |
940 | dri2_destroy_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) |
940 | dri2_destroy_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) |
941 | { |
941 | { |
942 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
942 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
943 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
943 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
944 | 944 | ||
945 | if (_eglPutContext(ctx)) { |
945 | if (_eglPutContext(ctx)) { |
946 | dri2_dpy->core->destroyContext(dri2_ctx->dri_context); |
946 | dri2_dpy->core->destroyContext(dri2_ctx->dri_context); |
947 | free(dri2_ctx); |
947 | free(dri2_ctx); |
948 | } |
948 | } |
949 | 949 | ||
950 | return EGL_TRUE; |
950 | return EGL_TRUE; |
951 | } |
951 | } |
952 | 952 | ||
953 | /** |
953 | /** |
954 | * Called via eglMakeCurrent(), drv->API.MakeCurrent(). |
954 | * Called via eglMakeCurrent(), drv->API.MakeCurrent(). |
955 | */ |
955 | */ |
956 | static EGLBoolean |
956 | static EGLBoolean |
957 | dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, |
957 | dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, |
958 | _EGLSurface *rsurf, _EGLContext *ctx) |
958 | _EGLSurface *rsurf, _EGLContext *ctx) |
959 | { |
959 | { |
960 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
960 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
961 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
961 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
962 | struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf); |
962 | struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf); |
963 | struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf); |
963 | struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf); |
964 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
964 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
965 | _EGLContext *old_ctx; |
965 | _EGLContext *old_ctx; |
966 | _EGLSurface *old_dsurf, *old_rsurf; |
966 | _EGLSurface *old_dsurf, *old_rsurf; |
967 | __DRIdrawable *ddraw, *rdraw; |
967 | __DRIdrawable *ddraw, *rdraw; |
968 | __DRIcontext *cctx; |
968 | __DRIcontext *cctx; |
969 | 969 | ||
970 | /* make new bindings */ |
970 | /* make new bindings */ |
971 | if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) |
971 | if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) |
972 | return EGL_FALSE; |
972 | return EGL_FALSE; |
973 | 973 | ||
974 | /* flush before context switch */ |
974 | /* flush before context switch */ |
975 | if (old_ctx && dri2_drv->glFlush) |
975 | if (old_ctx && dri2_drv->glFlush) |
976 | dri2_drv->glFlush(); |
976 | dri2_drv->glFlush(); |
977 | 977 | ||
978 | ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL; |
978 | ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL; |
979 | rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL; |
979 | rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL; |
980 | cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; |
980 | cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; |
981 | 981 | ||
982 | if (old_ctx) { |
982 | if (old_ctx) { |
983 | __DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context; |
983 | __DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context; |
984 | dri2_dpy->core->unbindContext(old_cctx); |
984 | dri2_dpy->core->unbindContext(old_cctx); |
985 | } |
985 | } |
986 | 986 | ||
987 | if ((cctx == NULL && ddraw == NULL && rdraw == NULL) || |
987 | if ((cctx == NULL && ddraw == NULL && rdraw == NULL) || |
988 | dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { |
988 | dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { |
989 | if (old_dsurf) |
989 | if (old_dsurf) |
990 | drv->API.DestroySurface(drv, disp, old_dsurf); |
990 | drv->API.DestroySurface(drv, disp, old_dsurf); |
991 | if (old_rsurf) |
991 | if (old_rsurf) |
992 | drv->API.DestroySurface(drv, disp, old_rsurf); |
992 | drv->API.DestroySurface(drv, disp, old_rsurf); |
993 | if (old_ctx) |
993 | if (old_ctx) |
994 | drv->API.DestroyContext(drv, disp, old_ctx); |
994 | drv->API.DestroyContext(drv, disp, old_ctx); |
995 | 995 | ||
996 | return EGL_TRUE; |
996 | return EGL_TRUE; |
997 | } else { |
997 | } else { |
998 | /* undo the previous _eglBindContext */ |
998 | /* undo the previous _eglBindContext */ |
999 | _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf); |
999 | _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf); |
1000 | assert(&dri2_ctx->base == ctx && |
1000 | assert(&dri2_ctx->base == ctx && |
1001 | &dri2_dsurf->base == dsurf && |
1001 | &dri2_dsurf->base == dsurf && |
1002 | &dri2_rsurf->base == rsurf); |
1002 | &dri2_rsurf->base == rsurf); |
1003 | 1003 | ||
1004 | _eglPutSurface(dsurf); |
1004 | _eglPutSurface(dsurf); |
1005 | _eglPutSurface(rsurf); |
1005 | _eglPutSurface(rsurf); |
1006 | _eglPutContext(ctx); |
1006 | _eglPutContext(ctx); |
1007 | 1007 | ||
1008 | _eglPutSurface(old_dsurf); |
1008 | _eglPutSurface(old_dsurf); |
1009 | _eglPutSurface(old_rsurf); |
1009 | _eglPutSurface(old_rsurf); |
1010 | _eglPutContext(old_ctx); |
1010 | _eglPutContext(old_ctx); |
1011 | 1011 | ||
1012 | return EGL_FALSE; |
1012 | return EGL_FALSE; |
1013 | } |
1013 | } |
1014 | } |
1014 | } |
1015 | 1015 | ||
1016 | /* |
1016 | /* |
1017 | * Called from eglGetProcAddress() via drv->API.GetProcAddress(). |
1017 | * Called from eglGetProcAddress() via drv->API.GetProcAddress(). |
1018 | */ |
1018 | */ |
1019 | static _EGLProc |
1019 | static _EGLProc |
1020 | dri2_get_proc_address(_EGLDriver *drv, const char *procname) |
1020 | dri2_get_proc_address(_EGLDriver *drv, const char *procname) |
1021 | { |
1021 | { |
1022 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
1022 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
1023 | 1023 | ||
1024 | return dri2_drv->get_proc_address(procname); |
1024 | return dri2_drv->get_proc_address(procname); |
1025 | } |
1025 | } |
1026 | 1026 | ||
1027 | static EGLBoolean |
1027 | static EGLBoolean |
1028 | dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) |
1028 | dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) |
1029 | { |
1029 | { |
1030 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1030 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1031 | struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface); |
1031 | struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface); |
1032 | 1032 | ||
1033 | (void) drv; |
1033 | (void) drv; |
1034 | 1034 | ||
1035 | /* FIXME: If EGL allows frontbuffer rendering for window surfaces, |
1035 | /* FIXME: If EGL allows frontbuffer rendering for window surfaces, |
1036 | * we need to copy fake to real here.*/ |
1036 | * we need to copy fake to real here.*/ |
1037 | 1037 | ||
1038 | if (dri2_dpy->flush != NULL) |
1038 | if (dri2_dpy->flush != NULL) |
1039 | dri2_dpy->flush->flush(dri2_surf->dri_drawable); |
1039 | dri2_dpy->flush->flush(dri2_surf->dri_drawable); |
1040 | 1040 | ||
1041 | return EGL_TRUE; |
1041 | return EGL_TRUE; |
1042 | } |
1042 | } |
1043 | 1043 | ||
1044 | static EGLBoolean |
1044 | static EGLBoolean |
1045 | dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine) |
1045 | dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine) |
1046 | { |
1046 | { |
1047 | (void) drv; |
1047 | (void) drv; |
1048 | (void) disp; |
1048 | (void) disp; |
1049 | 1049 | ||
1050 | if (engine != EGL_CORE_NATIVE_ENGINE) |
1050 | if (engine != EGL_CORE_NATIVE_ENGINE) |
1051 | return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); |
1051 | return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); |
1052 | /* glXWaitX(); */ |
1052 | /* glXWaitX(); */ |
1053 | 1053 | ||
1054 | return EGL_TRUE; |
1054 | return EGL_TRUE; |
1055 | } |
1055 | } |
1056 | 1056 | ||
1057 | static EGLBoolean |
1057 | static EGLBoolean |
1058 | dri2_bind_tex_image(_EGLDriver *drv, |
1058 | dri2_bind_tex_image(_EGLDriver *drv, |
1059 | _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) |
1059 | _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) |
1060 | { |
1060 | { |
1061 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1061 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1062 | struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); |
1062 | struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); |
1063 | struct dri2_egl_context *dri2_ctx; |
1063 | struct dri2_egl_context *dri2_ctx; |
1064 | _EGLContext *ctx; |
1064 | _EGLContext *ctx; |
1065 | GLint format, target; |
1065 | GLint format, target; |
1066 | 1066 | ||
1067 | ctx = _eglGetCurrentContext(); |
1067 | ctx = _eglGetCurrentContext(); |
1068 | dri2_ctx = dri2_egl_context(ctx); |
1068 | dri2_ctx = dri2_egl_context(ctx); |
1069 | 1069 | ||
1070 | if (!_eglBindTexImage(drv, disp, surf, buffer)) |
1070 | if (!_eglBindTexImage(drv, disp, surf, buffer)) |
1071 | return EGL_FALSE; |
1071 | return EGL_FALSE; |
1072 | 1072 | ||
1073 | switch (dri2_surf->base.TextureFormat) { |
1073 | switch (dri2_surf->base.TextureFormat) { |
1074 | case EGL_TEXTURE_RGB: |
1074 | case EGL_TEXTURE_RGB: |
1075 | format = __DRI_TEXTURE_FORMAT_RGB; |
1075 | format = __DRI_TEXTURE_FORMAT_RGB; |
1076 | break; |
1076 | break; |
1077 | case EGL_TEXTURE_RGBA: |
1077 | case EGL_TEXTURE_RGBA: |
1078 | format = __DRI_TEXTURE_FORMAT_RGBA; |
1078 | format = __DRI_TEXTURE_FORMAT_RGBA; |
1079 | break; |
1079 | break; |
1080 | default: |
1080 | default: |
1081 | assert(0); |
1081 | assert(0); |
1082 | } |
1082 | } |
1083 | 1083 | ||
1084 | switch (dri2_surf->base.TextureTarget) { |
1084 | switch (dri2_surf->base.TextureTarget) { |
1085 | case EGL_TEXTURE_2D: |
1085 | case EGL_TEXTURE_2D: |
1086 | target = GL_TEXTURE_2D; |
1086 | target = GL_TEXTURE_2D; |
1087 | break; |
1087 | break; |
1088 | default: |
1088 | default: |
1089 | assert(0); |
1089 | assert(0); |
1090 | } |
1090 | } |
1091 | 1091 | ||
1092 | (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context, |
1092 | (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context, |
1093 | target, format, |
1093 | target, format, |
1094 | dri2_surf->dri_drawable); |
1094 | dri2_surf->dri_drawable); |
1095 | 1095 | ||
1096 | return EGL_TRUE; |
1096 | return EGL_TRUE; |
1097 | } |
1097 | } |
1098 | 1098 | ||
1099 | static EGLBoolean |
1099 | static EGLBoolean |
1100 | dri2_release_tex_image(_EGLDriver *drv, |
1100 | dri2_release_tex_image(_EGLDriver *drv, |
1101 | _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) |
1101 | _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) |
1102 | { |
1102 | { |
1103 | #if __DRI_TEX_BUFFER_VERSION >= 3 |
1103 | #if __DRI_TEX_BUFFER_VERSION >= 3 |
1104 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1104 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1105 | struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); |
1105 | struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); |
1106 | struct dri2_egl_context *dri2_ctx; |
1106 | struct dri2_egl_context *dri2_ctx; |
1107 | _EGLContext *ctx; |
1107 | _EGLContext *ctx; |
1108 | GLint target; |
1108 | GLint target; |
1109 | 1109 | ||
1110 | ctx = _eglGetCurrentContext(); |
1110 | ctx = _eglGetCurrentContext(); |
1111 | dri2_ctx = dri2_egl_context(ctx); |
1111 | dri2_ctx = dri2_egl_context(ctx); |
1112 | 1112 | ||
1113 | if (!_eglReleaseTexImage(drv, disp, surf, buffer)) |
1113 | if (!_eglReleaseTexImage(drv, disp, surf, buffer)) |
1114 | return EGL_FALSE; |
1114 | return EGL_FALSE; |
1115 | 1115 | ||
1116 | switch (dri2_surf->base.TextureTarget) { |
1116 | switch (dri2_surf->base.TextureTarget) { |
1117 | case EGL_TEXTURE_2D: |
1117 | case EGL_TEXTURE_2D: |
1118 | target = GL_TEXTURE_2D; |
1118 | target = GL_TEXTURE_2D; |
1119 | break; |
1119 | break; |
1120 | default: |
1120 | default: |
1121 | assert(0); |
1121 | assert(0); |
1122 | } |
1122 | } |
1123 | if (dri2_dpy->tex_buffer->releaseTexBuffer!=NULL) |
1123 | if (dri2_dpy->tex_buffer->releaseTexBuffer!=NULL) |
1124 | (*dri2_dpy->tex_buffer->releaseTexBuffer)(dri2_ctx->dri_context, |
1124 | (*dri2_dpy->tex_buffer->releaseTexBuffer)(dri2_ctx->dri_context, |
1125 | target, |
1125 | target, |
1126 | dri2_surf->dri_drawable); |
1126 | dri2_surf->dri_drawable); |
1127 | #endif |
1127 | #endif |
1128 | 1128 | ||
1129 | return EGL_TRUE; |
1129 | return EGL_TRUE; |
1130 | } |
1130 | } |
1131 | 1131 | ||
1132 | static _EGLImage * |
1132 | static _EGLImage * |
1133 | dri2_create_image(_EGLDisplay *disp, __DRIimage *dri_image) |
1133 | dri2_create_image(_EGLDisplay *disp, __DRIimage *dri_image) |
1134 | { |
1134 | { |
1135 | struct dri2_egl_image *dri2_img; |
1135 | struct dri2_egl_image *dri2_img; |
1136 | 1136 | ||
1137 | if (dri_image == NULL) { |
1137 | if (dri_image == NULL) { |
1138 | _eglError(EGL_BAD_ALLOC, "dri2_create_image"); |
1138 | _eglError(EGL_BAD_ALLOC, "dri2_create_image"); |
1139 | return NULL; |
1139 | return NULL; |
1140 | } |
1140 | } |
1141 | 1141 | ||
1142 | dri2_img = malloc(sizeof *dri2_img); |
1142 | dri2_img = malloc(sizeof *dri2_img); |
1143 | if (!dri2_img) { |
1143 | if (!dri2_img) { |
1144 | _eglError(EGL_BAD_ALLOC, "dri2_create_image"); |
1144 | _eglError(EGL_BAD_ALLOC, "dri2_create_image"); |
1145 | return NULL; |
1145 | return NULL; |
1146 | } |
1146 | } |
1147 | 1147 | ||
1148 | if (!_eglInitImage(&dri2_img->base, disp)) { |
1148 | if (!_eglInitImage(&dri2_img->base, disp)) { |
1149 | free(dri2_img); |
1149 | free(dri2_img); |
1150 | return NULL; |
1150 | return NULL; |
1151 | } |
1151 | } |
1152 | 1152 | ||
1153 | dri2_img->dri_image = dri_image; |
1153 | dri2_img->dri_image = dri_image; |
1154 | 1154 | ||
1155 | return &dri2_img->base; |
1155 | return &dri2_img->base; |
1156 | } |
1156 | } |
1157 | 1157 | ||
1158 | static _EGLImage * |
1158 | static _EGLImage * |
1159 | dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, |
1159 | dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, |
1160 | EGLClientBuffer buffer, |
1160 | EGLClientBuffer buffer, |
1161 | const EGLint *attr_list) |
1161 | const EGLint *attr_list) |
1162 | { |
1162 | { |
1163 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1163 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1164 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
1164 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
1165 | GLuint renderbuffer = (GLuint) (uintptr_t) buffer; |
1165 | GLuint renderbuffer = (GLuint) (uintptr_t) buffer; |
1166 | __DRIimage *dri_image; |
1166 | __DRIimage *dri_image; |
1167 | 1167 | ||
1168 | if (renderbuffer == 0) { |
1168 | if (renderbuffer == 0) { |
1169 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1169 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1170 | return EGL_NO_IMAGE_KHR; |
1170 | return EGL_NO_IMAGE_KHR; |
1171 | } |
1171 | } |
1172 | 1172 | ||
1173 | dri_image = |
1173 | dri_image = |
1174 | dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context, |
1174 | dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context, |
1175 | renderbuffer, NULL); |
1175 | renderbuffer, NULL); |
1176 | 1176 | ||
1177 | return dri2_create_image(disp, dri_image); |
1177 | return dri2_create_image(disp, dri_image); |
1178 | } |
1178 | } |
1179 | 1179 | ||
1180 | static _EGLImage * |
1180 | static _EGLImage * |
1181 | dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, |
1181 | dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, |
1182 | EGLClientBuffer buffer, const EGLint *attr_list) |
1182 | EGLClientBuffer buffer, const EGLint *attr_list) |
1183 | { |
1183 | { |
1184 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1184 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1185 | EGLint format, name, pitch, err; |
1185 | EGLint format, name, pitch, err; |
1186 | _EGLImageAttribs attrs; |
1186 | _EGLImageAttribs attrs; |
1187 | __DRIimage *dri_image; |
1187 | __DRIimage *dri_image; |
1188 | 1188 | ||
1189 | name = (EGLint) (uintptr_t) buffer; |
1189 | name = (EGLint) (uintptr_t) buffer; |
1190 | 1190 | ||
1191 | err = _eglParseImageAttribList(&attrs, disp, attr_list); |
1191 | err = _eglParseImageAttribList(&attrs, disp, attr_list); |
1192 | if (err != EGL_SUCCESS) |
1192 | if (err != EGL_SUCCESS) |
1193 | return NULL; |
1193 | return NULL; |
1194 | 1194 | ||
1195 | if (attrs.Width <= 0 || attrs.Height <= 0 || |
1195 | if (attrs.Width <= 0 || attrs.Height <= 0 || |
1196 | attrs.DRMBufferStrideMESA <= 0) { |
1196 | attrs.DRMBufferStrideMESA <= 0) { |
1197 | _eglError(EGL_BAD_PARAMETER, |
1197 | _eglError(EGL_BAD_PARAMETER, |
1198 | "bad width, height or stride"); |
1198 | "bad width, height or stride"); |
1199 | return NULL; |
1199 | return NULL; |
1200 | } |
1200 | } |
1201 | 1201 | ||
1202 | switch (attrs.DRMBufferFormatMESA) { |
1202 | switch (attrs.DRMBufferFormatMESA) { |
1203 | case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: |
1203 | case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: |
1204 | format = __DRI_IMAGE_FORMAT_ARGB8888; |
1204 | format = __DRI_IMAGE_FORMAT_ARGB8888; |
1205 | pitch = attrs.DRMBufferStrideMESA; |
1205 | pitch = attrs.DRMBufferStrideMESA; |
1206 | break; |
1206 | break; |
1207 | default: |
1207 | default: |
1208 | _eglError(EGL_BAD_PARAMETER, |
1208 | _eglError(EGL_BAD_PARAMETER, |
1209 | "dri2_create_image_khr: unsupported pixmap depth"); |
1209 | "dri2_create_image_khr: unsupported pixmap depth"); |
1210 | return NULL; |
1210 | return NULL; |
1211 | } |
1211 | } |
1212 | 1212 | ||
1213 | dri_image = |
1213 | dri_image = |
1214 | dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, |
1214 | dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, |
1215 | attrs.Width, |
1215 | attrs.Width, |
1216 | attrs.Height, |
1216 | attrs.Height, |
1217 | format, |
1217 | format, |
1218 | name, |
1218 | name, |
1219 | pitch, |
1219 | pitch, |
1220 | NULL); |
1220 | NULL); |
1221 | 1221 | ||
1222 | return dri2_create_image(disp, dri_image); |
1222 | return dri2_create_image(disp, dri_image); |
1223 | } |
1223 | } |
1224 | 1224 | ||
1225 | #ifdef HAVE_WAYLAND_PLATFORM |
1225 | #ifdef HAVE_WAYLAND_PLATFORM |
1226 | 1226 | ||
1227 | /* This structure describes how a wl_buffer maps to one or more |
1227 | /* This structure describes how a wl_buffer maps to one or more |
1228 | * __DRIimages. A wl_drm_buffer stores the wl_drm format code and the |
1228 | * __DRIimages. A wl_drm_buffer stores the wl_drm format code and the |
1229 | * offsets and strides of the planes in the buffer. This table maps a |
1229 | * offsets and strides of the planes in the buffer. This table maps a |
1230 | * wl_drm format code to a description of the planes in the buffer |
1230 | * wl_drm format code to a description of the planes in the buffer |
1231 | * that lets us create a __DRIimage for each of the planes. */ |
1231 | * that lets us create a __DRIimage for each of the planes. */ |
1232 | 1232 | ||
1233 | static const struct wl_drm_components_descriptor { |
1233 | static const struct wl_drm_components_descriptor { |
1234 | uint32_t dri_components; |
1234 | uint32_t dri_components; |
1235 | EGLint components; |
1235 | EGLint components; |
1236 | int nplanes; |
1236 | int nplanes; |
1237 | } wl_drm_components[] = { |
1237 | } wl_drm_components[] = { |
1238 | { __DRI_IMAGE_COMPONENTS_RGB, EGL_TEXTURE_RGB, 1 }, |
1238 | { __DRI_IMAGE_COMPONENTS_RGB, EGL_TEXTURE_RGB, 1 }, |
1239 | { __DRI_IMAGE_COMPONENTS_RGBA, EGL_TEXTURE_RGBA, 1 }, |
1239 | { __DRI_IMAGE_COMPONENTS_RGBA, EGL_TEXTURE_RGBA, 1 }, |
1240 | { __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 }, |
1240 | { __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 }, |
1241 | { __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 }, |
1241 | { __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 }, |
1242 | { __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 }, |
1242 | { __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 }, |
1243 | }; |
1243 | }; |
1244 | 1244 | ||
1245 | static _EGLImage * |
1245 | static _EGLImage * |
1246 | dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx, |
1246 | dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx, |
1247 | EGLClientBuffer _buffer, |
1247 | EGLClientBuffer _buffer, |
1248 | const EGLint *attr_list) |
1248 | const EGLint *attr_list) |
1249 | { |
1249 | { |
1250 | struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; |
1250 | struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; |
1251 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1251 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1252 | const struct wl_drm_components_descriptor *f; |
1252 | const struct wl_drm_components_descriptor *f; |
1253 | __DRIimage *dri_image; |
1253 | __DRIimage *dri_image; |
1254 | _EGLImageAttribs attrs; |
1254 | _EGLImageAttribs attrs; |
1255 | EGLint err; |
1255 | EGLint err; |
1256 | int32_t plane; |
1256 | int32_t plane; |
1257 | 1257 | ||
1258 | if (!wayland_buffer_is_drm(&buffer->buffer)) |
1258 | if (!wayland_buffer_is_drm(dri2_dpy->wl_server_drm, &buffer->buffer)) |
1259 | return NULL; |
1259 | return NULL; |
1260 | 1260 | ||
1261 | err = _eglParseImageAttribList(&attrs, disp, attr_list); |
1261 | err = _eglParseImageAttribList(&attrs, disp, attr_list); |
1262 | plane = attrs.PlaneWL; |
1262 | plane = attrs.PlaneWL; |
1263 | if (err != EGL_SUCCESS) { |
1263 | if (err != EGL_SUCCESS) { |
1264 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); |
1264 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); |
1265 | return NULL; |
1265 | return NULL; |
1266 | } |
1266 | } |
1267 | 1267 | ||
1268 | f = buffer->driver_format; |
1268 | f = buffer->driver_format; |
1269 | if (plane < 0 || plane >= f->nplanes) { |
1269 | if (plane < 0 || plane >= f->nplanes) { |
1270 | _eglError(EGL_BAD_PARAMETER, |
1270 | _eglError(EGL_BAD_PARAMETER, |
1271 | "dri2_create_image_wayland_wl_buffer (plane out of bounds)"); |
1271 | "dri2_create_image_wayland_wl_buffer (plane out of bounds)"); |
1272 | return NULL; |
1272 | return NULL; |
1273 | } |
1273 | } |
1274 | 1274 | ||
1275 | dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL); |
1275 | dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL); |
1276 | 1276 | ||
1277 | if (dri_image == NULL) { |
1277 | if (dri_image == NULL) { |
1278 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); |
1278 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); |
1279 | return NULL; |
1279 | return NULL; |
1280 | } |
1280 | } |
1281 | 1281 | ||
1282 | return dri2_create_image(disp, dri_image); |
1282 | return dri2_create_image(disp, dri_image); |
1283 | } |
1283 | } |
1284 | #endif |
1284 | #endif |
1285 | 1285 | ||
1286 | /** |
1286 | /** |
1287 | * Set the error code after a call to |
1287 | * Set the error code after a call to |
1288 | * dri2_egl_image::dri_image::createImageFromTexture. |
1288 | * dri2_egl_image::dri_image::createImageFromTexture. |
1289 | */ |
1289 | */ |
1290 | static void |
1290 | static void |
1291 | dri2_create_image_khr_texture_error(int dri_error) |
1291 | dri2_create_image_khr_texture_error(int dri_error) |
1292 | { |
1292 | { |
1293 | EGLint egl_error; |
1293 | EGLint egl_error; |
1294 | 1294 | ||
1295 | switch (dri_error) { |
1295 | switch (dri_error) { |
1296 | case __DRI_IMAGE_ERROR_SUCCESS: |
1296 | case __DRI_IMAGE_ERROR_SUCCESS: |
1297 | return; |
1297 | return; |
1298 | 1298 | ||
1299 | case __DRI_IMAGE_ERROR_BAD_ALLOC: |
1299 | case __DRI_IMAGE_ERROR_BAD_ALLOC: |
1300 | egl_error = EGL_BAD_ALLOC; |
1300 | egl_error = EGL_BAD_ALLOC; |
1301 | break; |
1301 | break; |
1302 | 1302 | ||
1303 | case __DRI_IMAGE_ERROR_BAD_MATCH: |
1303 | case __DRI_IMAGE_ERROR_BAD_MATCH: |
1304 | egl_error = EGL_BAD_MATCH; |
1304 | egl_error = EGL_BAD_MATCH; |
1305 | break; |
1305 | break; |
1306 | 1306 | ||
1307 | case __DRI_IMAGE_ERROR_BAD_PARAMETER: |
1307 | case __DRI_IMAGE_ERROR_BAD_PARAMETER: |
1308 | egl_error = EGL_BAD_PARAMETER; |
1308 | egl_error = EGL_BAD_PARAMETER; |
1309 | break; |
1309 | break; |
1310 | 1310 | ||
1311 | default: |
1311 | default: |
1312 | assert(0); |
1312 | assert(0); |
1313 | egl_error = EGL_BAD_MATCH; |
1313 | egl_error = EGL_BAD_MATCH; |
1314 | break; |
1314 | break; |
1315 | } |
1315 | } |
1316 | 1316 | ||
1317 | _eglError(egl_error, "dri2_create_image_khr_texture"); |
1317 | _eglError(egl_error, "dri2_create_image_khr_texture"); |
1318 | } |
1318 | } |
1319 | 1319 | ||
1320 | static _EGLImage * |
1320 | static _EGLImage * |
1321 | dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx, |
1321 | dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx, |
1322 | EGLenum target, |
1322 | EGLenum target, |
1323 | EGLClientBuffer buffer, |
1323 | EGLClientBuffer buffer, |
1324 | const EGLint *attr_list) |
1324 | const EGLint *attr_list) |
1325 | { |
1325 | { |
1326 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1326 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1327 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
1327 | struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); |
1328 | struct dri2_egl_image *dri2_img; |
1328 | struct dri2_egl_image *dri2_img; |
1329 | GLuint texture = (GLuint) (uintptr_t) buffer; |
1329 | GLuint texture = (GLuint) (uintptr_t) buffer; |
1330 | _EGLImageAttribs attrs; |
1330 | _EGLImageAttribs attrs; |
1331 | GLuint depth; |
1331 | GLuint depth; |
1332 | GLenum gl_target; |
1332 | GLenum gl_target; |
1333 | unsigned error; |
1333 | unsigned error; |
1334 | 1334 | ||
1335 | if (texture == 0) { |
1335 | if (texture == 0) { |
1336 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1336 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1337 | return EGL_NO_IMAGE_KHR; |
1337 | return EGL_NO_IMAGE_KHR; |
1338 | } |
1338 | } |
1339 | 1339 | ||
1340 | if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS) |
1340 | if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS) |
1341 | return EGL_NO_IMAGE_KHR; |
1341 | return EGL_NO_IMAGE_KHR; |
1342 | 1342 | ||
1343 | switch (target) { |
1343 | switch (target) { |
1344 | case EGL_GL_TEXTURE_2D_KHR: |
1344 | case EGL_GL_TEXTURE_2D_KHR: |
1345 | depth = 0; |
1345 | depth = 0; |
1346 | gl_target = GL_TEXTURE_2D; |
1346 | gl_target = GL_TEXTURE_2D; |
1347 | break; |
1347 | break; |
1348 | case EGL_GL_TEXTURE_3D_KHR: |
1348 | case EGL_GL_TEXTURE_3D_KHR: |
1349 | depth = attrs.GLTextureZOffset; |
1349 | depth = attrs.GLTextureZOffset; |
1350 | gl_target = GL_TEXTURE_3D; |
1350 | gl_target = GL_TEXTURE_3D; |
1351 | break; |
1351 | break; |
1352 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: |
1352 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: |
1353 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: |
1353 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: |
1354 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: |
1354 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: |
1355 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: |
1355 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: |
1356 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: |
1356 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: |
1357 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: |
1357 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: |
1358 | depth = target - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR; |
1358 | depth = target - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR; |
1359 | gl_target = GL_TEXTURE_CUBE_MAP; |
1359 | gl_target = GL_TEXTURE_CUBE_MAP; |
1360 | break; |
1360 | break; |
1361 | default: |
1361 | default: |
1362 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1362 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1363 | return EGL_NO_IMAGE_KHR; |
1363 | return EGL_NO_IMAGE_KHR; |
1364 | } |
1364 | } |
1365 | 1365 | ||
1366 | dri2_img = malloc(sizeof *dri2_img); |
1366 | dri2_img = malloc(sizeof *dri2_img); |
1367 | if (!dri2_img) { |
1367 | if (!dri2_img) { |
1368 | _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); |
1368 | _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); |
1369 | return EGL_NO_IMAGE_KHR; |
1369 | return EGL_NO_IMAGE_KHR; |
1370 | } |
1370 | } |
1371 | 1371 | ||
1372 | if (!_eglInitImage(&dri2_img->base, disp)) { |
1372 | if (!_eglInitImage(&dri2_img->base, disp)) { |
1373 | _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); |
1373 | _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); |
1374 | free(dri2_img); |
1374 | free(dri2_img); |
1375 | return EGL_NO_IMAGE_KHR; |
1375 | return EGL_NO_IMAGE_KHR; |
1376 | } |
1376 | } |
1377 | 1377 | ||
1378 | dri2_img->dri_image = |
1378 | dri2_img->dri_image = |
1379 | dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context, |
1379 | dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context, |
1380 | gl_target, |
1380 | gl_target, |
1381 | texture, |
1381 | texture, |
1382 | depth, |
1382 | depth, |
1383 | attrs.GLTextureLevel, |
1383 | attrs.GLTextureLevel, |
1384 | &error, |
1384 | &error, |
1385 | dri2_img); |
1385 | dri2_img); |
1386 | dri2_create_image_khr_texture_error(error); |
1386 | dri2_create_image_khr_texture_error(error); |
1387 | 1387 | ||
1388 | if (!dri2_img->dri_image) { |
1388 | if (!dri2_img->dri_image) { |
1389 | free(dri2_img); |
1389 | free(dri2_img); |
1390 | return EGL_NO_IMAGE_KHR; |
1390 | return EGL_NO_IMAGE_KHR; |
1391 | } |
1391 | } |
1392 | return &dri2_img->base; |
1392 | return &dri2_img->base; |
1393 | } |
1393 | } |
1394 | 1394 | ||
1395 | _EGLImage * |
1395 | _EGLImage * |
1396 | dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, |
1396 | dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, |
1397 | _EGLContext *ctx, EGLenum target, |
1397 | _EGLContext *ctx, EGLenum target, |
1398 | EGLClientBuffer buffer, const EGLint *attr_list) |
1398 | EGLClientBuffer buffer, const EGLint *attr_list) |
1399 | { |
1399 | { |
1400 | (void) drv; |
1400 | (void) drv; |
1401 | 1401 | ||
1402 | switch (target) { |
1402 | switch (target) { |
1403 | case EGL_GL_TEXTURE_2D_KHR: |
1403 | case EGL_GL_TEXTURE_2D_KHR: |
1404 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: |
1404 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: |
1405 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: |
1405 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: |
1406 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: |
1406 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: |
1407 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: |
1407 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: |
1408 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: |
1408 | case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: |
1409 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: |
1409 | case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: |
1410 | return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list); |
1410 | return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list); |
1411 | case EGL_GL_RENDERBUFFER_KHR: |
1411 | case EGL_GL_RENDERBUFFER_KHR: |
1412 | return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list); |
1412 | return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list); |
1413 | case EGL_DRM_BUFFER_MESA: |
1413 | case EGL_DRM_BUFFER_MESA: |
1414 | return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list); |
1414 | return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list); |
1415 | #ifdef HAVE_WAYLAND_PLATFORM |
1415 | #ifdef HAVE_WAYLAND_PLATFORM |
1416 | case EGL_WAYLAND_BUFFER_WL: |
1416 | case EGL_WAYLAND_BUFFER_WL: |
1417 | return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list); |
1417 | return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list); |
1418 | #endif |
1418 | #endif |
1419 | default: |
1419 | default: |
1420 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1420 | _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); |
1421 | return EGL_NO_IMAGE_KHR; |
1421 | return EGL_NO_IMAGE_KHR; |
1422 | } |
1422 | } |
1423 | } |
1423 | } |
1424 | 1424 | ||
1425 | static EGLBoolean |
1425 | static EGLBoolean |
1426 | dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image) |
1426 | dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image) |
1427 | { |
1427 | { |
1428 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1428 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1429 | struct dri2_egl_image *dri2_img = dri2_egl_image(image); |
1429 | struct dri2_egl_image *dri2_img = dri2_egl_image(image); |
1430 | 1430 | ||
1431 | (void) drv; |
1431 | (void) drv; |
1432 | 1432 | ||
1433 | dri2_dpy->image->destroyImage(dri2_img->dri_image); |
1433 | dri2_dpy->image->destroyImage(dri2_img->dri_image); |
1434 | free(dri2_img); |
1434 | free(dri2_img); |
1435 | 1435 | ||
1436 | return EGL_TRUE; |
1436 | return EGL_TRUE; |
1437 | } |
1437 | } |
1438 | 1438 | ||
1439 | static _EGLImage * |
1439 | static _EGLImage * |
1440 | dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, |
1440 | dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, |
1441 | const EGLint *attr_list) |
1441 | const EGLint *attr_list) |
1442 | { |
1442 | { |
1443 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1443 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1444 | struct dri2_egl_image *dri2_img; |
1444 | struct dri2_egl_image *dri2_img; |
1445 | _EGLImageAttribs attrs; |
1445 | _EGLImageAttribs attrs; |
1446 | unsigned int dri_use, valid_mask; |
1446 | unsigned int dri_use, valid_mask; |
1447 | int format; |
1447 | int format; |
1448 | EGLint err = EGL_SUCCESS; |
1448 | EGLint err = EGL_SUCCESS; |
1449 | 1449 | ||
1450 | (void) drv; |
1450 | (void) drv; |
1451 | 1451 | ||
1452 | dri2_img = malloc(sizeof *dri2_img); |
1452 | dri2_img = malloc(sizeof *dri2_img); |
1453 | if (!dri2_img) { |
1453 | if (!dri2_img) { |
1454 | _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); |
1454 | _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); |
1455 | return EGL_NO_IMAGE_KHR; |
1455 | return EGL_NO_IMAGE_KHR; |
1456 | } |
1456 | } |
1457 | 1457 | ||
1458 | if (!attr_list) { |
1458 | if (!attr_list) { |
1459 | err = EGL_BAD_PARAMETER; |
1459 | err = EGL_BAD_PARAMETER; |
1460 | goto cleanup_img; |
1460 | goto cleanup_img; |
1461 | } |
1461 | } |
1462 | 1462 | ||
1463 | if (!_eglInitImage(&dri2_img->base, disp)) { |
1463 | if (!_eglInitImage(&dri2_img->base, disp)) { |
1464 | err = EGL_BAD_PARAMETER; |
1464 | err = EGL_BAD_PARAMETER; |
1465 | goto cleanup_img; |
1465 | goto cleanup_img; |
1466 | } |
1466 | } |
1467 | 1467 | ||
1468 | err = _eglParseImageAttribList(&attrs, disp, attr_list); |
1468 | err = _eglParseImageAttribList(&attrs, disp, attr_list); |
1469 | if (err != EGL_SUCCESS) |
1469 | if (err != EGL_SUCCESS) |
1470 | goto cleanup_img; |
1470 | goto cleanup_img; |
1471 | 1471 | ||
1472 | if (attrs.Width <= 0 || attrs.Height <= 0) { |
1472 | if (attrs.Width <= 0 || attrs.Height <= 0) { |
1473 | _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", |
1473 | _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", |
1474 | attrs.Width, attrs.Height); |
1474 | attrs.Width, attrs.Height); |
1475 | goto cleanup_img; |
1475 | goto cleanup_img; |
1476 | } |
1476 | } |
1477 | 1477 | ||
1478 | switch (attrs.DRMBufferFormatMESA) { |
1478 | switch (attrs.DRMBufferFormatMESA) { |
1479 | case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: |
1479 | case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: |
1480 | format = __DRI_IMAGE_FORMAT_ARGB8888; |
1480 | format = __DRI_IMAGE_FORMAT_ARGB8888; |
1481 | break; |
1481 | break; |
1482 | default: |
1482 | default: |
1483 | _eglLog(_EGL_WARNING, "bad image format value 0x%04x", |
1483 | _eglLog(_EGL_WARNING, "bad image format value 0x%04x", |
1484 | attrs.DRMBufferFormatMESA); |
1484 | attrs.DRMBufferFormatMESA); |
1485 | goto cleanup_img; |
1485 | goto cleanup_img; |
1486 | } |
1486 | } |
1487 | 1487 | ||
1488 | valid_mask = |
1488 | valid_mask = |
1489 | EGL_DRM_BUFFER_USE_SCANOUT_MESA | |
1489 | EGL_DRM_BUFFER_USE_SCANOUT_MESA | |
1490 | EGL_DRM_BUFFER_USE_SHARE_MESA | |
1490 | EGL_DRM_BUFFER_USE_SHARE_MESA | |
1491 | EGL_DRM_BUFFER_USE_CURSOR_MESA; |
1491 | EGL_DRM_BUFFER_USE_CURSOR_MESA; |
1492 | if (attrs.DRMBufferUseMESA & ~valid_mask) { |
1492 | if (attrs.DRMBufferUseMESA & ~valid_mask) { |
1493 | _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", |
1493 | _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", |
1494 | attrs.DRMBufferUseMESA & ~valid_mask); |
1494 | attrs.DRMBufferUseMESA & ~valid_mask); |
1495 | goto cleanup_img; |
1495 | goto cleanup_img; |
1496 | } |
1496 | } |
1497 | 1497 | ||
1498 | dri_use = 0; |
1498 | dri_use = 0; |
1499 | if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA) |
1499 | if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA) |
1500 | dri_use |= __DRI_IMAGE_USE_SHARE; |
1500 | dri_use |= __DRI_IMAGE_USE_SHARE; |
1501 | if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SCANOUT_MESA) |
1501 | if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SCANOUT_MESA) |
1502 | dri_use |= __DRI_IMAGE_USE_SCANOUT; |
1502 | dri_use |= __DRI_IMAGE_USE_SCANOUT; |
1503 | if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_CURSOR_MESA) |
1503 | if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_CURSOR_MESA) |
1504 | dri_use |= __DRI_IMAGE_USE_CURSOR; |
1504 | dri_use |= __DRI_IMAGE_USE_CURSOR; |
1505 | 1505 | ||
1506 | dri2_img->dri_image = |
1506 | dri2_img->dri_image = |
1507 | dri2_dpy->image->createImage(dri2_dpy->dri_screen, |
1507 | dri2_dpy->image->createImage(dri2_dpy->dri_screen, |
1508 | attrs.Width, attrs.Height, |
1508 | attrs.Width, attrs.Height, |
1509 | format, dri_use, dri2_img); |
1509 | format, dri_use, dri2_img); |
1510 | if (dri2_img->dri_image == NULL) { |
1510 | if (dri2_img->dri_image == NULL) { |
1511 | err = EGL_BAD_ALLOC; |
1511 | err = EGL_BAD_ALLOC; |
1512 | goto cleanup_img; |
1512 | goto cleanup_img; |
1513 | } |
1513 | } |
1514 | 1514 | ||
1515 | return &dri2_img->base; |
1515 | return &dri2_img->base; |
1516 | 1516 | ||
1517 | cleanup_img: |
1517 | cleanup_img: |
1518 | free(dri2_img); |
1518 | free(dri2_img); |
1519 | _eglError(err, "dri2_create_drm_image_mesa"); |
1519 | _eglError(err, "dri2_create_drm_image_mesa"); |
1520 | 1520 | ||
1521 | return EGL_NO_IMAGE_KHR; |
1521 | return EGL_NO_IMAGE_KHR; |
1522 | } |
1522 | } |
1523 | 1523 | ||
1524 | static EGLBoolean |
1524 | static EGLBoolean |
1525 | dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, |
1525 | dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, |
1526 | EGLint *name, EGLint *handle, EGLint *stride) |
1526 | EGLint *name, EGLint *handle, EGLint *stride) |
1527 | { |
1527 | { |
1528 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1528 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1529 | struct dri2_egl_image *dri2_img = dri2_egl_image(img); |
1529 | struct dri2_egl_image *dri2_img = dri2_egl_image(img); |
1530 | 1530 | ||
1531 | (void) drv; |
1531 | (void) drv; |
1532 | 1532 | ||
1533 | if (name && !dri2_dpy->image->queryImage(dri2_img->dri_image, |
1533 | if (name && !dri2_dpy->image->queryImage(dri2_img->dri_image, |
1534 | __DRI_IMAGE_ATTRIB_NAME, name)) { |
1534 | __DRI_IMAGE_ATTRIB_NAME, name)) { |
1535 | _eglError(EGL_BAD_ALLOC, "dri2_export_drm_image_mesa"); |
1535 | _eglError(EGL_BAD_ALLOC, "dri2_export_drm_image_mesa"); |
1536 | return EGL_FALSE; |
1536 | return EGL_FALSE; |
1537 | } |
1537 | } |
1538 | 1538 | ||
1539 | if (handle) |
1539 | if (handle) |
1540 | dri2_dpy->image->queryImage(dri2_img->dri_image, |
1540 | dri2_dpy->image->queryImage(dri2_img->dri_image, |
1541 | __DRI_IMAGE_ATTRIB_HANDLE, handle); |
1541 | __DRI_IMAGE_ATTRIB_HANDLE, handle); |
1542 | 1542 | ||
1543 | if (stride) |
1543 | if (stride) |
1544 | dri2_dpy->image->queryImage(dri2_img->dri_image, |
1544 | dri2_dpy->image->queryImage(dri2_img->dri_image, |
1545 | __DRI_IMAGE_ATTRIB_STRIDE, stride); |
1545 | __DRI_IMAGE_ATTRIB_STRIDE, stride); |
1546 | 1546 | ||
1547 | return EGL_TRUE; |
1547 | return EGL_TRUE; |
1548 | } |
1548 | } |
1549 | 1549 | ||
1550 | #ifdef HAVE_WAYLAND_PLATFORM |
1550 | #ifdef HAVE_WAYLAND_PLATFORM |
1551 | 1551 | ||
1552 | static void |
1552 | static void |
1553 | dri2_wl_reference_buffer(void *user_data, uint32_t name, int fd, |
1553 | dri2_wl_reference_buffer(void *user_data, uint32_t name, int fd, |
1554 | struct wl_drm_buffer *buffer) |
1554 | struct wl_drm_buffer *buffer) |
1555 | { |
1555 | { |
1556 | _EGLDisplay *disp = user_data; |
1556 | _EGLDisplay *disp = user_data; |
1557 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1557 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1558 | __DRIimage *img; |
1558 | __DRIimage *img; |
1559 | int i, dri_components = 0; |
1559 | int i, dri_components = 0; |
1560 | 1560 | ||
1561 | if (fd == -1) |
1561 | if (fd == -1) |
1562 | img = dri2_dpy->image->createImageFromNames(dri2_dpy->dri_screen, |
1562 | img = dri2_dpy->image->createImageFromNames(dri2_dpy->dri_screen, |
1563 | buffer->buffer.width, |
1563 | buffer->buffer.width, |
1564 | buffer->buffer.height, |
1564 | buffer->buffer.height, |
1565 | buffer->format, |
1565 | buffer->format, |
1566 | (int*)&name, 1, |
1566 | (int*)&name, 1, |
1567 | buffer->stride, |
1567 | buffer->stride, |
1568 | buffer->offset, |
1568 | buffer->offset, |
1569 | NULL); |
1569 | NULL); |
1570 | else |
1570 | else |
1571 | img = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, |
1571 | img = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, |
1572 | buffer->buffer.width, |
1572 | buffer->buffer.width, |
1573 | buffer->buffer.height, |
1573 | buffer->buffer.height, |
1574 | buffer->format, |
1574 | buffer->format, |
1575 | &fd, 1, |
1575 | &fd, 1, |
1576 | buffer->stride, |
1576 | buffer->stride, |
1577 | buffer->offset, |
1577 | buffer->offset, |
1578 | NULL); |
1578 | NULL); |
1579 | 1579 | ||
1580 | if (img == NULL) |
1580 | if (img == NULL) |
1581 | return; |
1581 | return; |
1582 | 1582 | ||
1583 | dri2_dpy->image->queryImage(img, __DRI_IMAGE_ATTRIB_COMPONENTS, &dri_components); |
1583 | dri2_dpy->image->queryImage(img, __DRI_IMAGE_ATTRIB_COMPONENTS, &dri_components); |
1584 | 1584 | ||
1585 | buffer->driver_format = NULL; |
1585 | buffer->driver_format = NULL; |
1586 | for (i = 0; i < ARRAY_SIZE(wl_drm_components); i++) |
1586 | for (i = 0; i < ARRAY_SIZE(wl_drm_components); i++) |
1587 | if (wl_drm_components[i].dri_components == dri_components) |
1587 | if (wl_drm_components[i].dri_components == dri_components) |
1588 | buffer->driver_format = &wl_drm_components[i]; |
1588 | buffer->driver_format = &wl_drm_components[i]; |
1589 | 1589 | ||
1590 | if (buffer->driver_format == NULL) |
1590 | if (buffer->driver_format == NULL) |
1591 | dri2_dpy->image->destroyImage(img); |
1591 | dri2_dpy->image->destroyImage(img); |
1592 | else |
1592 | else |
1593 | buffer->driver_buffer = img; |
1593 | buffer->driver_buffer = img; |
1594 | } |
1594 | } |
1595 | 1595 | ||
1596 | static void |
1596 | static void |
1597 | dri2_wl_release_buffer(void *user_data, struct wl_drm_buffer *buffer) |
1597 | dri2_wl_release_buffer(void *user_data, struct wl_drm_buffer *buffer) |
1598 | { |
1598 | { |
1599 | _EGLDisplay *disp = user_data; |
1599 | _EGLDisplay *disp = user_data; |
1600 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1600 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1601 | 1601 | ||
1602 | dri2_dpy->image->destroyImage(buffer->driver_buffer); |
1602 | dri2_dpy->image->destroyImage(buffer->driver_buffer); |
1603 | } |
1603 | } |
1604 | 1604 | ||
1605 | static struct wayland_drm_callbacks wl_drm_callbacks = { |
1605 | static struct wayland_drm_callbacks wl_drm_callbacks = { |
1606 | .authenticate = NULL, |
1606 | .authenticate = NULL, |
1607 | .reference_buffer = dri2_wl_reference_buffer, |
1607 | .reference_buffer = dri2_wl_reference_buffer, |
1608 | .release_buffer = dri2_wl_release_buffer |
1608 | .release_buffer = dri2_wl_release_buffer |
1609 | }; |
1609 | }; |
1610 | 1610 | ||
1611 | static EGLBoolean |
1611 | static EGLBoolean |
1612 | dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, |
1612 | dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, |
1613 | struct wl_display *wl_dpy) |
1613 | struct wl_display *wl_dpy) |
1614 | { |
1614 | { |
1615 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1615 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1616 | int ret, flags = 0; |
1616 | int ret, flags = 0; |
1617 | uint64_t cap; |
1617 | uint64_t cap; |
1618 | 1618 | ||
1619 | (void) drv; |
1619 | (void) drv; |
1620 | 1620 | ||
1621 | if (dri2_dpy->wl_server_drm) |
1621 | if (dri2_dpy->wl_server_drm) |
1622 | return EGL_FALSE; |
1622 | return EGL_FALSE; |
1623 | 1623 | ||
1624 | wl_drm_callbacks.authenticate = |
1624 | wl_drm_callbacks.authenticate = |
1625 | (int(*)(void *, uint32_t)) dri2_dpy->authenticate; |
1625 | (int(*)(void *, uint32_t)) dri2_dpy->authenticate; |
1626 | 1626 | ||
1627 | ret = drmGetCap(dri2_dpy->fd, DRM_CAP_PRIME, &cap); |
1627 | ret = drmGetCap(dri2_dpy->fd, DRM_CAP_PRIME, &cap); |
1628 | if (ret == 0 && cap == (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT) && |
1628 | if (ret == 0 && cap == (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT) && |
1629 | dri2_dpy->image->base.version >= 7 && |
1629 | dri2_dpy->image->base.version >= 7 && |
1630 | dri2_dpy->image->createImageFromFds != NULL) |
1630 | dri2_dpy->image->createImageFromFds != NULL) |
1631 | flags |= WAYLAND_DRM_PRIME; |
1631 | flags |= WAYLAND_DRM_PRIME; |
1632 | 1632 | ||
1633 | dri2_dpy->wl_server_drm = |
1633 | dri2_dpy->wl_server_drm = |
1634 | wayland_drm_init(wl_dpy, dri2_dpy->device_name, |
1634 | wayland_drm_init(wl_dpy, dri2_dpy->device_name, |
1635 | &wl_drm_callbacks, disp, flags); |
1635 | &wl_drm_callbacks, disp, flags); |
1636 | 1636 | ||
1637 | if (!dri2_dpy->wl_server_drm) |
1637 | if (!dri2_dpy->wl_server_drm) |
1638 | return EGL_FALSE; |
1638 | return EGL_FALSE; |
1639 | 1639 | ||
1640 | return EGL_TRUE; |
1640 | return EGL_TRUE; |
1641 | } |
1641 | } |
1642 | 1642 | ||
1643 | static EGLBoolean |
1643 | static EGLBoolean |
1644 | dri2_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, |
1644 | dri2_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, |
1645 | struct wl_display *wl_dpy) |
1645 | struct wl_display *wl_dpy) |
1646 | { |
1646 | { |
1647 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1647 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
1648 | 1648 | ||
1649 | (void) drv; |
1649 | (void) drv; |
1650 | 1650 | ||
1651 | if (!dri2_dpy->wl_server_drm) |
1651 | if (!dri2_dpy->wl_server_drm) |
1652 | return EGL_FALSE; |
1652 | return EGL_FALSE; |
1653 | 1653 | ||
1654 | wayland_drm_uninit(dri2_dpy->wl_server_drm); |
1654 | wayland_drm_uninit(dri2_dpy->wl_server_drm); |
1655 | dri2_dpy->wl_server_drm = NULL; |
1655 | dri2_dpy->wl_server_drm = NULL; |
1656 | 1656 | ||
1657 | return EGL_TRUE; |
1657 | return EGL_TRUE; |
1658 | } |
1658 | } |
1659 | 1659 | ||
1660 | static EGLBoolean |
1660 | static EGLBoolean |
1661 | dri2_query_wayland_buffer_wl(_EGLDriver *drv, _EGLDisplay *disp, |
1661 | dri2_query_wayland_buffer_wl(_EGLDriver *drv, _EGLDisplay *disp, |
1662 | struct wl_buffer *_buffer, |
1662 | struct wl_buffer *_buffer, |
1663 | EGLint attribute, EGLint *value) |
1663 | EGLint attribute, EGLint *value) |
1664 | { |
1664 | { |
1665 | struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; |
1665 | struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; |
- | 1666 | struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); |
|
1666 | const struct wl_drm_components_descriptor *format; |
1667 | const struct wl_drm_components_descriptor *format; |
1667 | 1668 | ||
1668 | if (!wayland_buffer_is_drm(&buffer->buffer)) |
1669 | if (!wayland_buffer_is_drm(dri2_dpy->wl_server_drm, &buffer->buffer)) |
1669 | return EGL_FALSE; |
1670 | return EGL_FALSE; |
1670 | 1671 | ||
1671 | format = buffer->driver_format; |
1672 | format = buffer->driver_format; |
1672 | switch (attribute) { |
1673 | switch (attribute) { |
1673 | case EGL_TEXTURE_FORMAT: |
1674 | case EGL_TEXTURE_FORMAT: |
1674 | *value = format->components; |
1675 | *value = format->components; |
1675 | return EGL_TRUE; |
1676 | return EGL_TRUE; |
1676 | case EGL_WIDTH: |
1677 | case EGL_WIDTH: |
1677 | *value = buffer->buffer.width; |
1678 | *value = buffer->buffer.width; |
1678 | return EGL_TRUE; |
1679 | return EGL_TRUE; |
1679 | case EGL_HEIGHT: |
1680 | case EGL_HEIGHT: |
1680 | *value = buffer->buffer.height; |
1681 | *value = buffer->buffer.height; |
1681 | return EGL_TRUE; |
1682 | return EGL_TRUE; |
1682 | } |
1683 | } |
1683 | 1684 | ||
1684 | return EGL_FALSE; |
1685 | return EGL_FALSE; |
1685 | } |
1686 | } |
1686 | #endif |
1687 | #endif |
1687 | 1688 | ||
1688 | static void |
1689 | static void |
1689 | dri2_unload(_EGLDriver *drv) |
1690 | dri2_unload(_EGLDriver *drv) |
1690 | { |
1691 | { |
1691 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
1692 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
1692 | 1693 | ||
1693 | // if (dri2_drv->handle) |
1694 | // if (dri2_drv->handle) |
1694 | // dlclose(dri2_drv->handle); |
1695 | // dlclose(dri2_drv->handle); |
1695 | free(dri2_drv); |
1696 | free(dri2_drv); |
1696 | } |
1697 | } |
1697 | 1698 | ||
1698 | static EGLBoolean |
1699 | static EGLBoolean |
1699 | dri2_load(_EGLDriver *drv) |
1700 | dri2_load(_EGLDriver *drv) |
1700 | { |
1701 | { |
1701 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
1702 | struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); |
1702 | const char *libname = "libGL.dll"; |
1703 | const char *libname = "libGL.dll"; |
1703 | 1704 | ||
1704 | lib_handle handle; |
1705 | lib_handle handle; |
1705 | 1706 | ||
1706 | handle = load_library(libname); |
1707 | handle = load_library(libname); |
1707 | if (handle) { |
1708 | if (handle) { |
1708 | dri2_drv->get_proc_address = (_EGLProc (*)(const char *)) |
1709 | dri2_drv->get_proc_address = (_EGLProc (*)(const char *)) |
1709 | get_proc_address(handle, "_glapi_get_proc_address"); |
1710 | get_proc_address(handle, "_glapi_get_proc_address"); |
1710 | if (!dri2_drv->get_proc_address) { |
1711 | if (!dri2_drv->get_proc_address) { |
1711 | /* no need to keep a reference */ |
1712 | /* no need to keep a reference */ |
1712 | handle = 0; |
1713 | handle = 0; |
1713 | } |
1714 | } |
1714 | } |
1715 | } |
1715 | 1716 | ||
1716 | /* if glapi is not available, loading DRI drivers will fail */ |
1717 | /* if glapi is not available, loading DRI drivers will fail */ |
1717 | if (!dri2_drv->get_proc_address) { |
1718 | if (!dri2_drv->get_proc_address) { |
1718 | _eglLog(_EGL_WARNING, "DRI2: failed to find _glapi_get_proc_address"); |
1719 | _eglLog(_EGL_WARNING, "DRI2: failed to find _glapi_get_proc_address"); |
1719 | return EGL_FALSE; |
1720 | return EGL_FALSE; |
1720 | } |
1721 | } |
1721 | 1722 | ||
1722 | dri2_drv->glFlush = (void (*)(void)) |
1723 | dri2_drv->glFlush = (void (*)(void)) |
1723 | dri2_drv->get_proc_address("glFlush"); |
1724 | dri2_drv->get_proc_address("glFlush"); |
1724 | 1725 | ||
1725 | dri2_drv->handle = (void*)handle; |
1726 | dri2_drv->handle = (void*)handle; |
1726 | 1727 | ||
1727 | return EGL_TRUE; |
1728 | return EGL_TRUE; |
1728 | } |
1729 | } |
1729 | 1730 | ||
1730 | /** |
1731 | /** |
1731 | * This is the main entrypoint into the driver, called by libEGL. |
1732 | * This is the main entrypoint into the driver, called by libEGL. |
1732 | * Create a new _EGLDriver object and init its dispatch table. |
1733 | * Create a new _EGLDriver object and init its dispatch table. |
1733 | */ |
1734 | */ |
1734 | _EGLDriver * |
1735 | _EGLDriver * |
1735 | _eglBuiltInDriverDRI2(const char *args) |
1736 | _eglBuiltInDriverDRI2(const char *args) |
1736 | { |
1737 | { |
1737 | struct dri2_egl_driver *dri2_drv; |
1738 | struct dri2_egl_driver *dri2_drv; |
1738 | 1739 | ||
1739 | (void) args; |
1740 | (void) args; |
1740 | 1741 | ||
1741 | dri2_drv = calloc(1, sizeof *dri2_drv); |
1742 | dri2_drv = calloc(1, sizeof *dri2_drv); |
1742 | if (!dri2_drv) |
1743 | if (!dri2_drv) |
1743 | return NULL; |
1744 | return NULL; |
1744 | 1745 | ||
1745 | if (!dri2_load(&dri2_drv->base)) { |
1746 | if (!dri2_load(&dri2_drv->base)) { |
1746 | free(dri2_drv); |
1747 | free(dri2_drv); |
1747 | return NULL; |
1748 | return NULL; |
1748 | } |
1749 | } |
1749 | 1750 | ||
1750 | _eglInitDriverFallbacks(&dri2_drv->base); |
1751 | _eglInitDriverFallbacks(&dri2_drv->base); |
1751 | dri2_drv->base.API.Initialize = dri2_initialize; |
1752 | dri2_drv->base.API.Initialize = dri2_initialize; |
1752 | dri2_drv->base.API.Terminate = dri2_terminate; |
1753 | dri2_drv->base.API.Terminate = dri2_terminate; |
1753 | dri2_drv->base.API.CreateContext = dri2_create_context; |
1754 | dri2_drv->base.API.CreateContext = dri2_create_context; |
1754 | dri2_drv->base.API.DestroyContext = dri2_destroy_context; |
1755 | dri2_drv->base.API.DestroyContext = dri2_destroy_context; |
1755 | dri2_drv->base.API.MakeCurrent = dri2_make_current; |
1756 | dri2_drv->base.API.MakeCurrent = dri2_make_current; |
1756 | dri2_drv->base.API.GetProcAddress = dri2_get_proc_address; |
1757 | dri2_drv->base.API.GetProcAddress = dri2_get_proc_address; |
1757 | dri2_drv->base.API.WaitClient = dri2_wait_client; |
1758 | dri2_drv->base.API.WaitClient = dri2_wait_client; |
1758 | dri2_drv->base.API.WaitNative = dri2_wait_native; |
1759 | dri2_drv->base.API.WaitNative = dri2_wait_native; |
1759 | dri2_drv->base.API.BindTexImage = dri2_bind_tex_image; |
1760 | dri2_drv->base.API.BindTexImage = dri2_bind_tex_image; |
1760 | dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image; |
1761 | dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image; |
1761 | dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr; |
1762 | dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr; |
1762 | dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr; |
1763 | dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr; |
1763 | dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa; |
1764 | dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa; |
1764 | dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa; |
1765 | dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa; |
1765 | #ifdef HAVE_WAYLAND_PLATFORM |
1766 | #ifdef HAVE_WAYLAND_PLATFORM |
1766 | dri2_drv->base.API.BindWaylandDisplayWL = dri2_bind_wayland_display_wl; |
1767 | dri2_drv->base.API.BindWaylandDisplayWL = dri2_bind_wayland_display_wl; |
1767 | dri2_drv->base.API.UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl; |
1768 | dri2_drv->base.API.UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl; |
1768 | dri2_drv->base.API.QueryWaylandBufferWL = dri2_query_wayland_buffer_wl; |
1769 | dri2_drv->base.API.QueryWaylandBufferWL = dri2_query_wayland_buffer_wl; |
1769 | #endif |
1770 | #endif |
1770 | 1771 | ||
1771 | dri2_drv->base.Name = "DRI2"; |
1772 | dri2_drv->base.Name = "DRI2"; |
1772 | dri2_drv->base.Unload = dri2_unload; |
1773 | dri2_drv->base.Unload = dri2_unload; |
1773 | 1774 | ||
1774 | return &dri2_drv->base; |
1775 | return &dri2_drv->base; |
1775 | }>=>=>>=>=>=>=>><>><> |
1776 | }>=>=>>=>=>=>=>><>><> |
1776 | ><__DRI_API_GLES)) |
1777 | ><__DRI_API_GLES)) |
1777 | > |
1778 | > |
1778 | ><__DRI_API_OPENGL)) |
1779 | ><__DRI_API_OPENGL)) |
1779 | >><>><>><>><>> |
1780 | >><>><>><>><>> |