egl_g3d_st.c revision f69b35fa15f43747dde29addaeec845604d7e127
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.9 4 * 5 * Copyright (C) 2010 LunarG Inc. 6 * 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: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Chia-I Wu <olv@lunarg.com> 26 */ 27 28#include "util/u_memory.h" 29#include "util/u_inlines.h" 30#include "util/u_dl.h" 31#include "eglimage.h" 32#include "eglmutex.h" 33 34#include "egl_g3d.h" 35#include "egl_g3d_st.h" 36 37struct egl_g3d_st_manager { 38 struct st_manager base; 39 _EGLDisplay *display; 40}; 41 42static INLINE struct egl_g3d_st_manager * 43egl_g3d_st_manager(struct st_manager *smapi) 44{ 45 return (struct egl_g3d_st_manager *) smapi; 46} 47 48struct st_api * 49egl_g3d_create_st_api(enum st_api_type api) 50{ 51 const char *stmod_name; 52 struct util_dl_library *lib; 53 const struct st_module *mod; 54 55 switch (api) { 56 case ST_API_OPENGL: 57 stmod_name = ST_MODULE_OPENGL_SYMBOL; 58 break; 59 case ST_API_OPENGL_ES1: 60 stmod_name = ST_MODULE_OPENGL_ES1_SYMBOL; 61 break; 62 case ST_API_OPENGL_ES2: 63 stmod_name = ST_MODULE_OPENGL_ES2_SYMBOL; 64 break; 65 case ST_API_OPENVG: 66 stmod_name = ST_MODULE_OPENVG_SYMBOL; 67 break; 68 default: 69 stmod_name = NULL; 70 break; 71 } 72 if (!stmod_name) 73 return NULL; 74 75 mod = NULL; 76 lib = util_dl_open(NULL); 77 if (lib) { 78 mod = (const struct st_module *) 79 util_dl_get_proc_address(lib, stmod_name); 80 util_dl_close(lib); 81 } 82 if (!mod || mod->api != api) 83 return NULL; 84 85 return mod->create_api(); 86} 87 88static boolean 89egl_g3d_st_manager_get_egl_image(struct st_manager *smapi, 90 struct st_egl_image *stimg) 91{ 92 struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi); 93 EGLImageKHR handle = (EGLImageKHR) stimg->egl_image; 94 _EGLImage *img; 95 struct egl_g3d_image *gimg; 96 97 /* this is called from state trackers */ 98 _eglLockMutex(&gsmapi->display->Mutex); 99 100 img = _eglLookupImage(handle, gsmapi->display); 101 if (!img) { 102 _eglUnlockMutex(&gsmapi->display->Mutex); 103 return FALSE; 104 } 105 106 gimg = egl_g3d_image(img); 107 108 stimg->texture = NULL; 109 pipe_texture_reference(&stimg->texture, gimg->texture); 110 stimg->face = gimg->face; 111 stimg->level = gimg->level; 112 stimg->zslice = gimg->zslice; 113 114 _eglUnlockMutex(&gsmapi->display->Mutex); 115 116 return TRUE; 117} 118 119struct st_manager * 120egl_g3d_create_st_manager(_EGLDisplay *dpy) 121{ 122 struct egl_g3d_display *gdpy = egl_g3d_display(dpy); 123 struct egl_g3d_st_manager *gsmapi; 124 125 gsmapi = CALLOC_STRUCT(egl_g3d_st_manager); 126 if (gsmapi) { 127 gsmapi->display = dpy; 128 129 gsmapi->base.screen = gdpy->native->screen; 130 gsmapi->base.get_egl_image = egl_g3d_st_manager_get_egl_image; 131 } 132 133 return &gsmapi->base;; 134} 135 136void 137egl_g3d_destroy_st_manager(struct st_manager *smapi) 138{ 139 struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi); 140 free(gsmapi); 141} 142 143static boolean 144egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface *stfbi, 145 enum st_attachment_type statt) 146{ 147 return TRUE; 148} 149 150static boolean 151egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi, 152 const enum st_attachment_type *statts, 153 unsigned count, 154 struct pipe_texture **out) 155{ 156 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; 157 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 158 struct pipe_texture templ; 159 unsigned i; 160 161 for (i = 0; i < count; i++) { 162 out[i] = NULL; 163 164 if (gsurf->stvis.render_buffer != statts[i]) 165 continue; 166 167 if (!gsurf->render_texture) { 168 struct egl_g3d_display *gdpy = 169 egl_g3d_display(gsurf->base.Resource.Display); 170 struct pipe_screen *screen = gdpy->native->screen; 171 172 memset(&templ, 0, sizeof(templ)); 173 templ.target = PIPE_TEXTURE_2D; 174 templ.last_level = 0; 175 templ.width0 = gsurf->base.Width; 176 templ.height0 = gsurf->base.Height; 177 templ.depth0 = 1; 178 templ.format = gsurf->stvis.color_format; 179 templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; 180 181 gsurf->render_texture = screen->texture_create(screen, &templ); 182 } 183 184 pipe_texture_reference(&out[i], gsurf->render_texture); 185 } 186 187 return TRUE; 188} 189 190static boolean 191egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, 192 enum st_attachment_type statt) 193{ 194 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; 195 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 196 197 return gsurf->native->flush_frontbuffer(gsurf->native); 198} 199 200static boolean 201egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, 202 const enum st_attachment_type *statts, 203 unsigned count, 204 struct pipe_texture **out) 205{ 206 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; 207 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 208 struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; 209 uint attachment_mask = 0; 210 unsigned i; 211 212 for (i = 0; i < count; i++) { 213 int natt; 214 215 switch (statts[i]) { 216 case ST_ATTACHMENT_FRONT_LEFT: 217 natt = NATIVE_ATTACHMENT_FRONT_LEFT; 218 break; 219 case ST_ATTACHMENT_BACK_LEFT: 220 natt = NATIVE_ATTACHMENT_BACK_LEFT; 221 break; 222 case ST_ATTACHMENT_FRONT_RIGHT: 223 natt = NATIVE_ATTACHMENT_FRONT_RIGHT; 224 break; 225 case ST_ATTACHMENT_BACK_RIGHT: 226 natt = NATIVE_ATTACHMENT_BACK_RIGHT; 227 break; 228 default: 229 natt = -1; 230 break; 231 } 232 233 if (natt >= 0) 234 attachment_mask |= 1 << natt; 235 } 236 237 if (!gsurf->native->validate(gsurf->native, attachment_mask, 238 &gsurf->sequence_number, textures, &gsurf->base.Width, 239 &gsurf->base.Height)) 240 return FALSE; 241 242 for (i = 0; i < count; i++) { 243 struct pipe_texture *tex; 244 int natt; 245 246 switch (statts[i]) { 247 case ST_ATTACHMENT_FRONT_LEFT: 248 natt = NATIVE_ATTACHMENT_FRONT_LEFT; 249 break; 250 case ST_ATTACHMENT_BACK_LEFT: 251 natt = NATIVE_ATTACHMENT_BACK_LEFT; 252 break; 253 case ST_ATTACHMENT_FRONT_RIGHT: 254 natt = NATIVE_ATTACHMENT_FRONT_RIGHT; 255 break; 256 case ST_ATTACHMENT_BACK_RIGHT: 257 natt = NATIVE_ATTACHMENT_BACK_RIGHT; 258 break; 259 default: 260 natt = -1; 261 break; 262 } 263 264 if (natt >= 0) { 265 tex = textures[natt]; 266 267 if (statts[i] == stfbi->visual->render_buffer) 268 pipe_texture_reference(&gsurf->render_texture, tex); 269 270 if (attachment_mask & (1 << natt)) { 271 /* transfer the ownership to the caller */ 272 out[i] = tex; 273 attachment_mask &= ~(1 << natt); 274 } 275 else { 276 /* the attachment is listed more than once */ 277 pipe_texture_reference(&out[i], tex); 278 } 279 } 280 } 281 282 return TRUE; 283} 284 285struct st_framebuffer_iface * 286egl_g3d_create_st_framebuffer(_EGLSurface *surf) 287{ 288 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 289 struct st_framebuffer_iface *stfbi; 290 291 stfbi = CALLOC_STRUCT(st_framebuffer_iface); 292 if (!stfbi) 293 return NULL; 294 295 stfbi->visual = &gsurf->stvis; 296 if (gsurf->base.Type != EGL_PBUFFER_BIT) { 297 stfbi->flush_front = egl_g3d_st_framebuffer_flush_front; 298 stfbi->validate = egl_g3d_st_framebuffer_validate; 299 } 300 else { 301 stfbi->flush_front = egl_g3d_st_framebuffer_flush_front_pbuffer; 302 stfbi->validate = egl_g3d_st_framebuffer_validate_pbuffer; 303 } 304 stfbi->st_manager_private = (void *) &gsurf->base; 305 306 return stfbi; 307} 308 309void 310egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi) 311{ 312 free(stfbi); 313} 314