Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * |
||
4 | * Copyright (C) 2009-2010 Chia-I Wu |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * copy of this software and associated documentation files (the "Software"), |
||
8 | * to deal in the Software without restriction, including without limitation |
||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
10 | * and/or sell copies of the Software, and to permit persons to whom the |
||
11 | * Software is furnished to do so, subject to the following conditions: |
||
12 | * |
||
13 | * The above copyright notice and this permission notice shall be included |
||
14 | * in all copies or substantial portions of the Software. |
||
15 | * |
||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||
22 | * DEALINGS IN THE SOFTWARE. |
||
23 | */ |
||
24 | |||
25 | #include "egldriver.h" |
||
26 | #include "eglcurrent.h" |
||
27 | #include "egllog.h" |
||
28 | |||
29 | #include "pipe/p_screen.h" |
||
30 | #include "util/u_memory.h" |
||
31 | #include "util/u_format.h" |
||
32 | #include "util/u_string.h" |
||
33 | #include "util/u_atomic.h" |
||
34 | |||
35 | #include "egl_g3d.h" |
||
36 | #include "egl_g3d_api.h" |
||
37 | #include "egl_g3d_st.h" |
||
38 | #include "egl_g3d_loader.h" |
||
39 | #include "native.h" |
||
40 | |||
41 | static void |
||
42 | egl_g3d_invalid_surface(struct native_display *ndpy, |
||
43 | struct native_surface *nsurf, |
||
44 | unsigned int seq_num) |
||
45 | { |
||
46 | /* XXX not thread safe? */ |
||
47 | struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data); |
||
48 | |||
49 | if (gsurf && gsurf->stfbi) |
||
50 | p_atomic_inc(&gsurf->stfbi->stamp); |
||
51 | } |
||
52 | |||
53 | static struct pipe_screen * |
||
54 | egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd) |
||
55 | { |
||
56 | _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; |
||
57 | struct egl_g3d_display *gdpy = egl_g3d_display(dpy); |
||
58 | return gdpy->loader->create_drm_screen(name, fd); |
||
59 | } |
||
60 | |||
61 | static struct pipe_screen * |
||
62 | egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws) |
||
63 | { |
||
64 | _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; |
||
65 | struct egl_g3d_display *gdpy = egl_g3d_display(dpy); |
||
66 | return gdpy->loader->create_sw_screen(ws); |
||
67 | } |
||
68 | |||
69 | static struct pipe_resource * |
||
70 | egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image) |
||
71 | { |
||
72 | _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; |
||
73 | struct egl_g3d_display *gdpy = egl_g3d_display(dpy); |
||
74 | struct st_egl_image img; |
||
75 | struct pipe_resource *resource = NULL; |
||
76 | |||
77 | memset(&img, 0, sizeof(img)); |
||
78 | if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img)) |
||
79 | resource = img.texture; |
||
80 | |||
81 | return resource; |
||
82 | } |
||
83 | |||
84 | static const struct native_event_handler egl_g3d_native_event_handler = { |
||
85 | egl_g3d_invalid_surface, |
||
86 | egl_g3d_new_drm_screen, |
||
87 | egl_g3d_new_sw_screen, |
||
88 | egl_g3d_lookup_egl_image |
||
89 | }; |
||
90 | |||
91 | /** |
||
92 | * Get the native platform. |
||
93 | */ |
||
94 | static const struct native_platform * |
||
95 | egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat) |
||
96 | { |
||
97 | struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); |
||
98 | |||
99 | if (!gdrv->platforms[plat]) { |
||
100 | const char *plat_name = NULL; |
||
101 | const struct native_platform *nplat = NULL; |
||
102 | |||
5080 | serge | 103 | plat_name = "DRM"; |
104 | nplat = native_get_drm_platform(&egl_g3d_native_event_handler); |
||
4358 | Serge | 105 | |
106 | if (!nplat) |
||
107 | _eglLog(_EGL_WARNING, "unsupported platform %s", plat_name); |
||
108 | |||
109 | gdrv->platforms[plat] = nplat; |
||
110 | } |
||
111 | |||
112 | return gdrv->platforms[plat]; |
||
113 | } |
||
114 | |||
115 | #ifdef EGL_MESA_screen_surface |
||
116 | |||
117 | static void |
||
118 | egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy) |
||
119 | { |
||
120 | struct egl_g3d_display *gdpy = egl_g3d_display(dpy); |
||
121 | const struct native_connector **native_connectors; |
||
122 | EGLint num_connectors, i; |
||
123 | |||
124 | native_connectors = |
||
125 | gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL); |
||
126 | if (!num_connectors) { |
||
127 | FREE(native_connectors); |
||
128 | return; |
||
129 | } |
||
130 | |||
131 | for (i = 0; i < num_connectors; i++) { |
||
132 | const struct native_connector *nconn = native_connectors[i]; |
||
133 | struct egl_g3d_screen *gscr; |
||
134 | const struct native_mode **native_modes; |
||
135 | EGLint num_modes, j; |
||
136 | |||
137 | /* TODO support for hotplug */ |
||
138 | native_modes = |
||
139 | gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes); |
||
140 | if (!num_modes) { |
||
141 | FREE(native_modes); |
||
142 | continue; |
||
143 | } |
||
144 | |||
145 | gscr = CALLOC_STRUCT(egl_g3d_screen); |
||
146 | if (!gscr) { |
||
147 | FREE(native_modes); |
||
148 | continue; |
||
149 | } |
||
150 | |||
151 | _eglInitScreen(&gscr->base, dpy, num_modes); |
||
152 | for (j = 0; j < gscr->base.NumModes; j++) { |
||
153 | const struct native_mode *nmode = native_modes[j]; |
||
154 | _EGLMode *mode = &gscr->base.Modes[j]; |
||
155 | |||
156 | mode->Width = nmode->width; |
||
157 | mode->Height = nmode->height; |
||
158 | mode->RefreshRate = nmode->refresh_rate; |
||
159 | mode->Optimal = EGL_FALSE; |
||
160 | mode->Interlaced = EGL_FALSE; |
||
161 | /* no need to strdup() */ |
||
162 | mode->Name = nmode->desc; |
||
163 | } |
||
164 | |||
165 | gscr->native = nconn; |
||
166 | gscr->native_modes = native_modes; |
||
167 | |||
168 | _eglLinkScreen(&gscr->base); |
||
169 | } |
||
170 | |||
171 | FREE(native_connectors); |
||
172 | } |
||
173 | |||
174 | #endif /* EGL_MESA_screen_surface */ |
||
175 | |||
176 | /** |
||
177 | * Initialize and validate the EGL config attributes. |
||
178 | */ |
||
179 | static EGLBoolean |
||
180 | init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, |
||
181 | EGLint api_mask, enum pipe_format depth_stencil_format, |
||
182 | EGLint preserve_buffer, EGLint max_swap_interval, |
||
183 | EGLBoolean pre_alpha) |
||
184 | { |
||
185 | uint rgba[4], depth_stencil[2], buffer_size; |
||
186 | EGLint surface_type; |
||
187 | EGLint i; |
||
188 | |||
189 | /* get the color and depth/stencil component sizes */ |
||
190 | assert(nconf->color_format != PIPE_FORMAT_NONE); |
||
191 | buffer_size = 0; |
||
192 | for (i = 0; i < 4; i++) { |
||
193 | rgba[i] = util_format_get_component_bits(nconf->color_format, |
||
194 | UTIL_FORMAT_COLORSPACE_RGB, i); |
||
195 | buffer_size += rgba[i]; |
||
196 | } |
||
197 | for (i = 0; i < 2; i++) { |
||
198 | if (depth_stencil_format != PIPE_FORMAT_NONE) { |
||
199 | depth_stencil[i] = |
||
200 | util_format_get_component_bits(depth_stencil_format, |
||
201 | UTIL_FORMAT_COLORSPACE_ZS, i); |
||
202 | } |
||
203 | else { |
||
204 | depth_stencil[i] = 0; |
||
205 | } |
||
206 | } |
||
207 | |||
208 | surface_type = 0x0; |
||
209 | /* pixmap surfaces should be EGL_SINGLE_BUFFER */ |
||
210 | if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) { |
||
211 | if (nconf->pixmap_bit) |
||
212 | surface_type |= EGL_PIXMAP_BIT; |
||
213 | } |
||
214 | /* the others surfaces should be EGL_BACK_BUFFER (or settable) */ |
||
215 | if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) { |
||
216 | if (nconf->window_bit) |
||
217 | surface_type |= EGL_WINDOW_BIT; |
||
218 | #ifdef EGL_MESA_screen_surface |
||
219 | if (nconf->scanout_bit) |
||
220 | surface_type |= EGL_SCREEN_BIT_MESA; |
||
221 | #endif |
||
222 | surface_type |= EGL_PBUFFER_BIT; |
||
223 | } |
||
224 | |||
225 | if (preserve_buffer) |
||
226 | surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT; |
||
227 | |||
228 | if (pre_alpha && rgba[3]) { |
||
229 | surface_type |= EGL_VG_ALPHA_FORMAT_PRE_BIT; |
||
230 | /* st/vega does not support premultiplied alpha yet */ |
||
231 | api_mask &= ~EGL_OPENVG_BIT; |
||
232 | } |
||
233 | |||
234 | conf->Conformant = api_mask; |
||
235 | conf->RenderableType = api_mask; |
||
236 | |||
237 | conf->RedSize = rgba[0]; |
||
238 | conf->GreenSize = rgba[1]; |
||
239 | conf->BlueSize = rgba[2]; |
||
240 | conf->AlphaSize = rgba[3]; |
||
241 | conf->BufferSize = buffer_size; |
||
242 | |||
243 | conf->DepthSize = depth_stencil[0]; |
||
244 | conf->StencilSize = depth_stencil[1]; |
||
245 | |||
246 | /* st/vega will allocate the mask on demand */ |
||
247 | if (api_mask & EGL_OPENVG_BIT) |
||
248 | conf->AlphaMaskSize = 8; |
||
249 | |||
250 | conf->SurfaceType = surface_type; |
||
251 | |||
252 | conf->NativeRenderable = EGL_TRUE; |
||
253 | if (surface_type & EGL_WINDOW_BIT) { |
||
254 | conf->NativeVisualID = nconf->native_visual_id; |
||
255 | conf->NativeVisualType = nconf->native_visual_type; |
||
256 | } |
||
257 | |||
258 | if (surface_type & EGL_PBUFFER_BIT) { |
||
259 | conf->BindToTextureRGB = EGL_TRUE; |
||
260 | if (rgba[3]) |
||
261 | conf->BindToTextureRGBA = EGL_TRUE; |
||
262 | |||
263 | conf->MaxPbufferWidth = 4096; |
||
264 | conf->MaxPbufferHeight = 4096; |
||
265 | conf->MaxPbufferPixels = 4096 * 4096; |
||
266 | } |
||
267 | |||
268 | conf->Level = nconf->level; |
||
269 | |||
270 | if (nconf->transparent_rgb) { |
||
271 | conf->TransparentType = EGL_TRANSPARENT_RGB; |
||
272 | conf->TransparentRedValue = nconf->transparent_rgb_values[0]; |
||
273 | conf->TransparentGreenValue = nconf->transparent_rgb_values[1]; |
||
274 | conf->TransparentBlueValue = nconf->transparent_rgb_values[2]; |
||
275 | } |
||
276 | |||
277 | conf->MinSwapInterval = 0; |
||
278 | conf->MaxSwapInterval = max_swap_interval; |
||
279 | |||
280 | return _eglValidateConfig(conf, EGL_FALSE); |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Initialize an EGL config from the native config. |
||
285 | */ |
||
286 | static EGLBoolean |
||
287 | egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, |
||
288 | _EGLConfig *conf, const struct native_config *nconf, |
||
289 | enum pipe_format depth_stencil_format, |
||
290 | int preserve_buffer, int max_swap_interval, |
||
291 | int pre_alpha) |
||
292 | { |
||
293 | struct egl_g3d_config *gconf = egl_g3d_config(conf); |
||
294 | EGLint buffer_mask; |
||
295 | EGLBoolean valid; |
||
296 | |||
297 | buffer_mask = 0x0; |
||
298 | if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) |
||
299 | buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; |
||
300 | if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) |
||
301 | buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; |
||
302 | if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_RIGHT)) |
||
303 | buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; |
||
304 | if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_RIGHT)) |
||
305 | buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; |
||
306 | |||
307 | gconf->stvis.buffer_mask = buffer_mask; |
||
308 | gconf->stvis.color_format = nconf->color_format; |
||
309 | gconf->stvis.depth_stencil_format = depth_stencil_format; |
||
310 | gconf->stvis.accum_format = PIPE_FORMAT_NONE; |
||
311 | gconf->stvis.samples = 0; |
||
312 | |||
313 | /* will be overridden per surface */ |
||
314 | gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ? |
||
315 | ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT; |
||
316 | |||
317 | valid = init_config_attributes(&gconf->base, |
||
318 | nconf, dpy->ClientAPIs, depth_stencil_format, |
||
319 | preserve_buffer, max_swap_interval, pre_alpha); |
||
320 | if (!valid) { |
||
321 | _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id); |
||
322 | return EGL_FALSE; |
||
323 | } |
||
324 | |||
325 | gconf->native = nconf; |
||
326 | |||
327 | return EGL_TRUE; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * Get all interested depth/stencil formats of a display. |
||
332 | */ |
||
333 | static EGLint |
||
334 | egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy, |
||
335 | enum pipe_format formats[8]) |
||
336 | { |
||
337 | struct egl_g3d_display *gdpy = egl_g3d_display(dpy); |
||
338 | struct pipe_screen *screen = gdpy->native->screen; |
||
339 | const EGLint candidates[] = { |
||
340 | 1, PIPE_FORMAT_Z16_UNORM, |
||
341 | 1, PIPE_FORMAT_Z32_UNORM, |
||
342 | 2, PIPE_FORMAT_Z24_UNORM_S8_UINT, PIPE_FORMAT_S8_UINT_Z24_UNORM, |
||
343 | 2, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM, |
||
344 | |||
345 | }; |
||
346 | const EGLint *fmt = candidates; |
||
347 | EGLint count; |
||
348 | |||
349 | count = 0; |
||
350 | formats[count++] = PIPE_FORMAT_NONE; |
||
351 | |||
352 | while (*fmt) { |
||
353 | EGLint i, n = *fmt++; |
||
354 | |||
355 | /* pick the first supported format */ |
||
356 | for (i = 0; i < n; i++) { |
||
357 | if (screen->is_format_supported(screen, fmt[i], |
||
358 | PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) { |
||
359 | formats[count++] = fmt[i]; |
||
360 | break; |
||
361 | } |
||
362 | } |
||
363 | |||
364 | fmt += n; |
||
365 | } |
||
366 | |||
367 | return count; |
||
368 | } |
||
369 | |||
370 | /** |
||
371 | * Add configs to display and return the next config ID. |
||
372 | */ |
||
373 | static EGLint |
||
374 | egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) |
||
375 | { |
||
376 | struct egl_g3d_display *gdpy = egl_g3d_display(dpy); |
||
377 | const struct native_config **native_configs; |
||
378 | enum pipe_format depth_stencil_formats[8]; |
||
379 | int num_formats, num_configs, i, j; |
||
380 | int preserve_buffer, max_swap_interval, premultiplied_alpha; |
||
381 | |||
382 | native_configs = gdpy->native->get_configs(gdpy->native, &num_configs); |
||
383 | if (!num_configs) { |
||
384 | FREE(native_configs); |
||
385 | return id; |
||
386 | } |
||
387 | |||
388 | preserve_buffer = |
||
389 | gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER); |
||
390 | max_swap_interval = |
||
391 | gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL); |
||
392 | premultiplied_alpha = |
||
393 | gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PREMULTIPLIED_ALPHA); |
||
394 | |||
395 | num_formats = egl_g3d_fill_depth_stencil_formats(dpy, |
||
396 | depth_stencil_formats); |
||
397 | |||
398 | for (i = 0; i < num_configs; i++) { |
||
399 | for (j = 0; j < num_formats; j++) { |
||
400 | struct egl_g3d_config *gconf; |
||
401 | |||
402 | gconf = CALLOC_STRUCT(egl_g3d_config); |
||
403 | if (gconf) { |
||
404 | _eglInitConfig(&gconf->base, dpy, id); |
||
405 | if (!egl_g3d_init_config(drv, dpy, &gconf->base, |
||
406 | native_configs[i], depth_stencil_formats[j], |
||
407 | preserve_buffer, max_swap_interval, |
||
408 | premultiplied_alpha)) { |
||
409 | FREE(gconf); |
||
410 | break; |
||
411 | } |
||
412 | |||
413 | _eglLinkConfig(&gconf->base); |
||
414 | id++; |
||
415 | } |
||
416 | } |
||
417 | } |
||
418 | |||
419 | FREE(native_configs); |
||
420 | return id; |
||
421 | } |
||
422 | |||
423 | static void |
||
424 | egl_g3d_free_config(void *conf) |
||
425 | { |
||
426 | struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf); |
||
427 | FREE(gconf); |
||
428 | } |
||
429 | |||
430 | static void |
||
431 | egl_g3d_free_screen(void *scr) |
||
432 | { |
||
433 | #ifdef EGL_MESA_screen_surface |
||
434 | struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr); |
||
435 | FREE(gscr->native_modes); |
||
436 | FREE(gscr); |
||
437 | #endif |
||
438 | } |
||
439 | |||
440 | static EGLBoolean |
||
441 | egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) |
||
442 | { |
||
443 | struct egl_g3d_display *gdpy = egl_g3d_display(dpy); |
||
444 | |||
445 | _eglReleaseDisplayResources(drv, dpy); |
||
446 | |||
447 | if (dpy->Configs) { |
||
448 | _eglDestroyArray(dpy->Configs, egl_g3d_free_config); |
||
449 | dpy->Configs = NULL; |
||
450 | } |
||
451 | if (dpy->Screens) { |
||
452 | _eglDestroyArray(dpy->Screens, egl_g3d_free_screen); |
||
453 | dpy->Screens = NULL; |
||
454 | } |
||
455 | |||
456 | _eglCleanupDisplay(dpy); |
||
457 | |||
458 | if (gdpy->smapi) |
||
459 | egl_g3d_destroy_st_manager(gdpy->smapi); |
||
460 | |||
461 | if (gdpy->native) |
||
462 | gdpy->native->destroy(gdpy->native); |
||
463 | |||
464 | FREE(gdpy); |
||
465 | dpy->DriverData = NULL; |
||
466 | |||
467 | return EGL_TRUE; |
||
468 | } |
||
469 | |||
470 | static EGLBoolean |
||
471 | egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy) |
||
472 | { |
||
473 | struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); |
||
474 | struct egl_g3d_display *gdpy; |
||
475 | const struct native_platform *nplat; |
||
476 | |||
477 | nplat = egl_g3d_get_platform(drv, dpy->Platform); |
||
478 | if (!nplat) |
||
479 | return EGL_FALSE; |
||
480 | |||
481 | if (dpy->Options.TestOnly) |
||
482 | return EGL_TRUE; |
||
483 | |||
484 | gdpy = CALLOC_STRUCT(egl_g3d_display); |
||
485 | if (!gdpy) { |
||
486 | _eglError(EGL_BAD_ALLOC, "eglInitialize"); |
||
487 | goto fail; |
||
488 | } |
||
489 | gdpy->loader = gdrv->loader; |
||
490 | dpy->DriverData = gdpy; |
||
491 | |||
492 | _eglLog(_EGL_INFO, "use %s for display %p", |
||
493 | nplat->name, dpy->PlatformDisplay); |
||
494 | gdpy->native = |
||
495 | nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback); |
||
496 | if (!gdpy->native) { |
||
497 | _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); |
||
498 | goto fail; |
||
499 | } |
||
500 | gdpy->native->user_data = (void *) dpy; |
||
501 | if (!gdpy->native->init_screen(gdpy->native)) { |
||
502 | _eglError(EGL_NOT_INITIALIZED, |
||
503 | "eglInitialize(failed to initialize screen)"); |
||
504 | goto fail; |
||
505 | } |
||
506 | |||
507 | if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK) |
||
508 | dpy->ClientAPIs |= EGL_OPENGL_BIT; |
||
509 | if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK) |
||
510 | dpy->ClientAPIs |= EGL_OPENGL_ES_BIT; |
||
511 | if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK) |
||
512 | dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT; |
||
513 | if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK) |
||
514 | dpy->ClientAPIs |= EGL_OPENVG_BIT; |
||
515 | |||
516 | gdpy->smapi = egl_g3d_create_st_manager(dpy); |
||
517 | if (!gdpy->smapi) { |
||
518 | _eglError(EGL_NOT_INITIALIZED, |
||
519 | "eglInitialize(failed to create st manager)"); |
||
520 | goto fail; |
||
521 | } |
||
522 | |||
523 | #ifdef EGL_MESA_screen_surface |
||
524 | /* enable MESA_screen_surface before adding (and validating) configs */ |
||
525 | if (gdpy->native->modeset) { |
||
526 | dpy->Extensions.MESA_screen_surface = EGL_TRUE; |
||
527 | egl_g3d_add_screens(drv, dpy); |
||
528 | } |
||
529 | #endif |
||
530 | |||
531 | dpy->Extensions.KHR_image_base = EGL_TRUE; |
||
532 | if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER)) |
||
533 | dpy->Extensions.KHR_image_pixmap = EGL_TRUE; |
||
534 | |||
535 | dpy->Extensions.KHR_reusable_sync = EGL_TRUE; |
||
536 | dpy->Extensions.KHR_fence_sync = EGL_TRUE; |
||
537 | |||
538 | dpy->Extensions.KHR_surfaceless_context = EGL_TRUE; |
||
539 | |||
540 | if (dpy->Platform == _EGL_PLATFORM_DRM) { |
||
541 | dpy->Extensions.MESA_drm_display = EGL_TRUE; |
||
542 | if (gdpy->native->buffer) |
||
543 | dpy->Extensions.MESA_drm_image = EGL_TRUE; |
||
544 | } |
||
545 | |||
5080 | serge | 546 | // if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer) |
547 | // dpy->Extensions.MESA_drm_image = EGL_TRUE; |
||
4358 | Serge | 548 | |
549 | |||
550 | if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESENT_REGION) && |
||
551 | gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER)) { |
||
552 | #ifdef EGL_NOK_swap_region |
||
553 | dpy->Extensions.NOK_swap_region = EGL_TRUE; |
||
554 | #endif |
||
555 | dpy->Extensions.NV_post_sub_buffer = EGL_TRUE; |
||
556 | } |
||
557 | |||
558 | if (egl_g3d_add_configs(drv, dpy, 1) == 1) { |
||
559 | _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)"); |
||
560 | goto fail; |
||
561 | } |
||
562 | |||
563 | dpy->VersionMajor = 1; |
||
564 | dpy->VersionMinor = 4; |
||
565 | |||
566 | return EGL_TRUE; |
||
567 | |||
568 | fail: |
||
569 | if (gdpy) |
||
570 | egl_g3d_terminate(drv, dpy); |
||
571 | return EGL_FALSE; |
||
572 | } |
||
573 | |||
574 | static _EGLProc |
||
575 | egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) |
||
576 | { |
||
577 | struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); |
||
578 | struct st_api *stapi = NULL; |
||
579 | |||
580 | if (procname && procname[0] == 'v' && procname[1] == 'g') |
||
581 | stapi = gdrv->loader->get_st_api(ST_API_OPENVG); |
||
582 | else if (procname && procname[0] == 'g' && procname[1] == 'l') |
||
583 | stapi = gdrv->loader->get_st_api(ST_API_OPENGL); |
||
584 | |||
585 | return (_EGLProc) ((stapi) ? |
||
586 | stapi->get_proc_address(stapi, procname) : NULL); |
||
587 | } |
||
588 | |||
589 | _EGLDriver * |
||
590 | egl_g3d_create_driver(const struct egl_g3d_loader *loader) |
||
591 | { |
||
592 | struct egl_g3d_driver *gdrv; |
||
593 | |||
594 | gdrv = CALLOC_STRUCT(egl_g3d_driver); |
||
595 | if (!gdrv) |
||
596 | return NULL; |
||
597 | |||
598 | gdrv->loader = loader; |
||
599 | |||
600 | egl_g3d_init_driver_api(&gdrv->base); |
||
601 | gdrv->base.API.Initialize = egl_g3d_initialize; |
||
602 | gdrv->base.API.Terminate = egl_g3d_terminate; |
||
603 | gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; |
||
604 | |||
605 | /* to be filled by the caller */ |
||
606 | gdrv->base.Name = NULL; |
||
607 | gdrv->base.Unload = NULL; |
||
608 | |||
609 | return &gdrv->base; |
||
610 | } |
||
611 | |||
612 | void |
||
613 | egl_g3d_destroy_driver(_EGLDriver *drv) |
||
614 | { |
||
615 | struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); |
||
616 | FREE(gdrv); |
||
617 | }>>>><>><>><>><>><>><>>>>> |