2 * Mesa 3-D graphics library
5 * Copyright (C) 2010 LunarG Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 * Chia-I Wu <olv@lunarg.com>
29 #include "util/u_memory.h"
30 #include "util/u_string.h"
31 #include "util/u_inlines.h"
32 #include "util/u_pointer.h"
33 #include "util/u_format.h"
34 #include "util/u_dl.h"
35 #include "egldriver.h"
40 #include "egl_g3d_st.h"
42 struct egl_g3d_st_manager
{
43 struct st_manager base
;
47 static INLINE
struct egl_g3d_st_manager
*
48 egl_g3d_st_manager(struct st_manager
*smapi
)
50 return (struct egl_g3d_st_manager
*) smapi
;
53 static struct egl_g3d_st_module
{
55 struct util_dl_library
*lib
;
57 } egl_g3d_st_modules
[ST_API_COUNT
];
60 egl_g3d_search_path_callback(const char *dir
, size_t len
, void *callback_data
)
62 struct egl_g3d_st_module
*stmod
=
63 (struct egl_g3d_st_module
*) callback_data
;
68 stmod
->lib
= util_dl_open(stmod
->filename
);
72 ret
= util_snprintf(path
, sizeof(path
),
73 "%.*s/%s", len
, dir
, stmod
->filename
);
74 if (ret
> 0 && ret
< sizeof(path
))
75 stmod
->lib
= util_dl_open(path
);
81 egl_g3d_load_st_module(struct egl_g3d_st_module
*stmod
,
82 const char *filename
, const char *procname
)
84 struct st_api
*(*create_api
)(void);
86 stmod
->filename
= filename
;
88 _eglSearchPathForEach(egl_g3d_search_path_callback
, (void *) stmod
);
90 stmod
->lib
= util_dl_open(NULL
);
93 create_api
= (struct st_api
*(*)(void))
94 util_dl_get_proc_address(stmod
->lib
, procname
);
96 stmod
->stapi
= create_api();
99 util_dl_close(stmod
->lib
);
108 stmod
->filename
= NULL
;
113 #ifdef PIPE_OS_WINDOWS
114 #define ST_MODULE_SUFFIX ".dll"
116 #define ST_MODULE_SUFFIX ".so"
120 egl_g3d_init_st_apis(struct st_api
*stapis
[ST_API_COUNT
])
122 const char *skip_checks
[ST_API_COUNT
], *symbols
[ST_API_COUNT
];
123 const char *filenames
[ST_API_COUNT
][4];
124 struct util_dl_library
*self
;
125 int num_needed
= 0, api
;
127 self
= util_dl_open(NULL
);
129 /* collect the necessary data for loading modules */
130 for (api
= 0; api
< ST_API_COUNT
; api
++) {
135 skip_checks
[api
] = "glColor4d";
136 symbols
[api
] = ST_CREATE_OPENGL_SYMBOL
;
137 filenames
[api
][count
++] = "api_GL" ST_MODULE_SUFFIX
;
139 case ST_API_OPENGL_ES1
:
140 skip_checks
[api
] = "glColor4x";
141 symbols
[api
] = ST_CREATE_OPENGL_ES1_SYMBOL
;
142 filenames
[api
][count
++] = "api_GLESv1_CM" ST_MODULE_SUFFIX
;
143 filenames
[api
][count
++] = "api_GL" ST_MODULE_SUFFIX
;
145 case ST_API_OPENGL_ES2
:
146 skip_checks
[api
] = "glShaderBinary";
147 symbols
[api
] = ST_CREATE_OPENGL_ES2_SYMBOL
;
148 filenames
[api
][count
++] = "api_GLESv2" ST_MODULE_SUFFIX
;
149 filenames
[api
][count
++] = "api_GL" ST_MODULE_SUFFIX
;
152 skip_checks
[api
] = "vgClear";
153 symbols
[api
] = ST_CREATE_OPENVG_SYMBOL
;
154 filenames
[api
][count
++]= "api_OpenVG" ST_MODULE_SUFFIX
;
157 assert(!"Unknown API Type\n");
158 skip_checks
[api
] = NULL
;
162 filenames
[api
][count
++]= NULL
;
163 assert(count
< Elements(filenames
[api
]));
165 /* heuristicically decide if the module is needed */
166 if (!self
|| !skip_checks
[api
] ||
167 util_dl_get_proc_address(self
, skip_checks
[api
])) {
168 /* unset so the module is not skipped */
169 skip_checks
[api
] = NULL
;
173 /* mark all moudles needed if we wrongly decided that none is needed */
175 memset(skip_checks
, 0, sizeof(skip_checks
));
180 for (api
= 0; api
< ST_API_COUNT
; api
++) {
181 struct egl_g3d_st_module
*stmod
= &egl_g3d_st_modules
[api
];
184 /* skip the module */
185 if (skip_checks
[api
])
188 /* try all filenames, including NULL */
189 for (p
= filenames
[api
]; *p
; p
++) {
190 if (egl_g3d_load_st_module(stmod
, *p
, symbols
[api
]))
194 egl_g3d_load_st_module(stmod
, NULL
, symbols
[api
]);
196 stapis
[api
] = stmod
->stapi
;
201 egl_g3d_destroy_st_apis(void)
205 for (api
= 0; api
< ST_API_COUNT
; api
++) {
206 struct egl_g3d_st_module
*stmod
= &egl_g3d_st_modules
[api
];
209 stmod
->stapi
->destroy(stmod
->stapi
);
213 util_dl_close(stmod
->lib
);
216 stmod
->filename
= NULL
;
221 egl_g3d_st_manager_get_egl_image(struct st_manager
*smapi
,
222 struct st_context_iface
*stctx
,
224 struct st_egl_image
*out
)
226 struct egl_g3d_st_manager
*gsmapi
= egl_g3d_st_manager(smapi
);
227 EGLImageKHR handle
= (EGLImageKHR
) egl_image
;
229 struct egl_g3d_image
*gimg
;
231 /* this is called from state trackers */
232 _eglLockMutex(&gsmapi
->display
->Mutex
);
234 img
= _eglLookupImage(handle
, gsmapi
->display
);
236 _eglUnlockMutex(&gsmapi
->display
->Mutex
);
240 gimg
= egl_g3d_image(img
);
243 pipe_resource_reference(&out
->texture
, gimg
->texture
);
244 out
->face
= gimg
->face
;
245 out
->level
= gimg
->level
;
246 out
->zslice
= gimg
->zslice
;
248 _eglUnlockMutex(&gsmapi
->display
->Mutex
);
254 egl_g3d_st_manager_get_param(struct st_manager
*smapi
,
255 enum st_manager_param param
)
261 egl_g3d_create_st_manager(_EGLDisplay
*dpy
)
263 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
264 struct egl_g3d_st_manager
*gsmapi
;
266 gsmapi
= CALLOC_STRUCT(egl_g3d_st_manager
);
268 gsmapi
->display
= dpy
;
270 gsmapi
->base
.screen
= gdpy
->native
->screen
;
271 gsmapi
->base
.get_egl_image
= egl_g3d_st_manager_get_egl_image
;
272 gsmapi
->base
.get_param
= egl_g3d_st_manager_get_param
;
275 return &gsmapi
->base
;;
279 egl_g3d_destroy_st_manager(struct st_manager
*smapi
)
281 struct egl_g3d_st_manager
*gsmapi
= egl_g3d_st_manager(smapi
);
286 egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface
*stfbi
,
287 enum st_attachment_type statt
)
293 pbuffer_reference_openvg_image(struct egl_g3d_surface
*gsurf
)
299 pbuffer_allocate_render_texture(struct egl_g3d_surface
*gsurf
)
301 struct egl_g3d_display
*gdpy
=
302 egl_g3d_display(gsurf
->base
.Resource
.Display
);
303 struct pipe_screen
*screen
= gdpy
->native
->screen
;
304 struct pipe_resource templ
, *ptex
;
306 memset(&templ
, 0, sizeof(templ
));
307 templ
.target
= PIPE_TEXTURE_2D
;
308 templ
.last_level
= 0;
309 templ
.width0
= gsurf
->base
.Width
;
310 templ
.height0
= gsurf
->base
.Height
;
312 templ
.format
= gsurf
->stvis
.color_format
;
313 templ
.bind
= PIPE_BIND_RENDER_TARGET
;
315 ptex
= screen
->resource_create(screen
, &templ
);
316 gsurf
->render_texture
= ptex
;
320 egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface
*stfbi
,
321 const enum st_attachment_type
*statts
,
323 struct pipe_resource
**out
)
325 _EGLSurface
*surf
= (_EGLSurface
*) stfbi
->st_manager_private
;
326 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
329 for (i
= 0; i
< count
; i
++) {
332 if (gsurf
->stvis
.render_buffer
!= statts
[i
])
335 if (!gsurf
->render_texture
) {
336 switch (gsurf
->client_buffer_type
) {
338 pbuffer_allocate_render_texture(gsurf
);
340 case EGL_OPENVG_IMAGE
:
341 pbuffer_reference_openvg_image(gsurf
);
347 if (!gsurf
->render_texture
)
351 pipe_resource_reference(&out
[i
], gsurf
->render_texture
);
358 egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface
*stfbi
,
359 enum st_attachment_type statt
)
361 _EGLSurface
*surf
= (_EGLSurface
*) stfbi
->st_manager_private
;
362 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
364 return gsurf
->native
->flush_frontbuffer(gsurf
->native
);
368 egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface
*stfbi
,
369 const enum st_attachment_type
*statts
,
371 struct pipe_resource
**out
)
373 _EGLSurface
*surf
= (_EGLSurface
*) stfbi
->st_manager_private
;
374 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
375 struct pipe_resource
*textures
[NUM_NATIVE_ATTACHMENTS
];
376 uint attachment_mask
= 0;
379 for (i
= 0; i
< count
; i
++) {
383 case ST_ATTACHMENT_FRONT_LEFT
:
384 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
386 case ST_ATTACHMENT_BACK_LEFT
:
387 natt
= NATIVE_ATTACHMENT_BACK_LEFT
;
389 case ST_ATTACHMENT_FRONT_RIGHT
:
390 natt
= NATIVE_ATTACHMENT_FRONT_RIGHT
;
392 case ST_ATTACHMENT_BACK_RIGHT
:
393 natt
= NATIVE_ATTACHMENT_BACK_RIGHT
;
401 attachment_mask
|= 1 << natt
;
404 if (!gsurf
->native
->validate(gsurf
->native
, attachment_mask
,
405 &gsurf
->sequence_number
, textures
, &gsurf
->base
.Width
,
406 &gsurf
->base
.Height
))
409 for (i
= 0; i
< count
; i
++) {
410 struct pipe_resource
*tex
;
414 case ST_ATTACHMENT_FRONT_LEFT
:
415 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
417 case ST_ATTACHMENT_BACK_LEFT
:
418 natt
= NATIVE_ATTACHMENT_BACK_LEFT
;
420 case ST_ATTACHMENT_FRONT_RIGHT
:
421 natt
= NATIVE_ATTACHMENT_FRONT_RIGHT
;
423 case ST_ATTACHMENT_BACK_RIGHT
:
424 natt
= NATIVE_ATTACHMENT_BACK_RIGHT
;
432 tex
= textures
[natt
];
434 if (statts
[i
] == stfbi
->visual
->render_buffer
)
435 pipe_resource_reference(&gsurf
->render_texture
, tex
);
437 if (attachment_mask
& (1 << natt
)) {
438 /* transfer the ownership to the caller */
440 attachment_mask
&= ~(1 << natt
);
443 /* the attachment is listed more than once */
444 pipe_resource_reference(&out
[i
], tex
);
452 struct st_framebuffer_iface
*
453 egl_g3d_create_st_framebuffer(_EGLSurface
*surf
)
455 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
456 struct st_framebuffer_iface
*stfbi
;
458 stfbi
= CALLOC_STRUCT(st_framebuffer_iface
);
462 stfbi
->visual
= &gsurf
->stvis
;
463 if (gsurf
->base
.Type
!= EGL_PBUFFER_BIT
) {
464 stfbi
->flush_front
= egl_g3d_st_framebuffer_flush_front
;
465 stfbi
->validate
= egl_g3d_st_framebuffer_validate
;
468 stfbi
->flush_front
= egl_g3d_st_framebuffer_flush_front_pbuffer
;
469 stfbi
->validate
= egl_g3d_st_framebuffer_validate_pbuffer
;
471 stfbi
->st_manager_private
= (void *) &gsurf
->base
;
477 egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface
*stfbi
)