egl_g3d_st.c revision ac8fdbc1c723afb19eeaba5457ba78d0bf33b8d4
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 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. 24 * 25 * Authors: 26 * Chia-I Wu <olv@lunarg.com> 27 */ 28 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_dl.h" 34#include "egldriver.h" 35#include "eglimage.h" 36#include "eglmutex.h" 37 38#include "egl_g3d.h" 39#include "egl_g3d_st.h" 40 41struct egl_g3d_st_manager { 42 struct st_manager base; 43 _EGLDisplay *display; 44}; 45 46static INLINE struct egl_g3d_st_manager * 47egl_g3d_st_manager(struct st_manager *smapi) 48{ 49 return (struct egl_g3d_st_manager *) smapi; 50} 51 52static boolean 53egl_g3d_st_manager_get_egl_image(struct st_manager *smapi, 54 void *egl_image, 55 struct st_egl_image *out) 56{ 57 struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi); 58 EGLImageKHR handle = (EGLImageKHR) egl_image; 59 _EGLImage *img; 60 struct egl_g3d_image *gimg; 61 62 /* this is called from state trackers */ 63 _eglLockMutex(&gsmapi->display->Mutex); 64 65 img = _eglLookupImage(handle, gsmapi->display); 66 if (!img) { 67 _eglUnlockMutex(&gsmapi->display->Mutex); 68 return FALSE; 69 } 70 71 gimg = egl_g3d_image(img); 72 73 out->texture = NULL; 74 pipe_resource_reference(&out->texture, gimg->texture); 75 out->level = gimg->level; 76 out->layer = gimg->layer; 77 78 _eglUnlockMutex(&gsmapi->display->Mutex); 79 80 return TRUE; 81} 82 83static int 84egl_g3d_st_manager_get_param(struct st_manager *smapi, 85 enum st_manager_param param) 86{ 87 return 0; 88} 89 90struct st_manager * 91egl_g3d_create_st_manager(_EGLDisplay *dpy) 92{ 93 struct egl_g3d_display *gdpy = egl_g3d_display(dpy); 94 struct egl_g3d_st_manager *gsmapi; 95 96 gsmapi = CALLOC_STRUCT(egl_g3d_st_manager); 97 if (gsmapi) { 98 gsmapi->display = dpy; 99 100 gsmapi->base.screen = gdpy->native->screen; 101 gsmapi->base.get_egl_image = egl_g3d_st_manager_get_egl_image; 102 gsmapi->base.get_param = egl_g3d_st_manager_get_param; 103 } 104 105 return &gsmapi->base;; 106} 107 108void 109egl_g3d_destroy_st_manager(struct st_manager *smapi) 110{ 111 struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi); 112 FREE(gsmapi); 113} 114 115static boolean 116egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface *stfbi, 117 enum st_attachment_type statt) 118{ 119 return TRUE; 120} 121 122static void 123pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf) 124{ 125 /* TODO */ 126} 127 128static void 129pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf) 130{ 131 struct egl_g3d_display *gdpy = 132 egl_g3d_display(gsurf->base.Resource.Display); 133 struct pipe_screen *screen = gdpy->native->screen; 134 struct pipe_resource templ, *ptex; 135 136 memset(&templ, 0, sizeof(templ)); 137 templ.target = PIPE_TEXTURE_2D; 138 templ.last_level = 0; 139 templ.width0 = gsurf->base.Width; 140 templ.height0 = gsurf->base.Height; 141 templ.depth0 = 1; 142 templ.array_size = 1; 143 templ.format = gsurf->stvis.color_format; 144 templ.bind = PIPE_BIND_RENDER_TARGET; 145 146 ptex = screen->resource_create(screen, &templ); 147 gsurf->render_texture = ptex; 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_resource **out) 155{ 156 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; 157 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 158 unsigned i; 159 160 for (i = 0; i < count; i++) { 161 out[i] = NULL; 162 163 if (gsurf->stvis.render_buffer != statts[i]) 164 continue; 165 166 if (!gsurf->render_texture) { 167 switch (gsurf->client_buffer_type) { 168 case EGL_NONE: 169 pbuffer_allocate_render_texture(gsurf); 170 break; 171 case EGL_OPENVG_IMAGE: 172 pbuffer_reference_openvg_image(gsurf); 173 break; 174 default: 175 break; 176 } 177 178 if (!gsurf->render_texture) 179 return FALSE; 180 } 181 182 pipe_resource_reference(&out[i], gsurf->render_texture); 183 } 184 185 return TRUE; 186} 187 188static boolean 189egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, 190 enum st_attachment_type statt) 191{ 192 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; 193 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 194 195 return gsurf->native->present(gsurf->native, 196 NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); 197} 198 199static boolean 200egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, 201 const enum st_attachment_type *statts, 202 unsigned count, 203 struct pipe_resource **out) 204{ 205 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; 206 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 207 struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS]; 208 uint attachment_mask = 0; 209 unsigned i; 210 211 for (i = 0; i < count; i++) { 212 int natt; 213 214 switch (statts[i]) { 215 case ST_ATTACHMENT_FRONT_LEFT: 216 natt = NATIVE_ATTACHMENT_FRONT_LEFT; 217 break; 218 case ST_ATTACHMENT_BACK_LEFT: 219 natt = NATIVE_ATTACHMENT_BACK_LEFT; 220 break; 221 case ST_ATTACHMENT_FRONT_RIGHT: 222 natt = NATIVE_ATTACHMENT_FRONT_RIGHT; 223 break; 224 case ST_ATTACHMENT_BACK_RIGHT: 225 natt = NATIVE_ATTACHMENT_BACK_RIGHT; 226 break; 227 default: 228 natt = -1; 229 break; 230 } 231 232 if (natt >= 0) 233 attachment_mask |= 1 << natt; 234 } 235 236 if (!gsurf->native->validate(gsurf->native, attachment_mask, 237 &gsurf->sequence_number, textures, &gsurf->base.Width, 238 &gsurf->base.Height)) 239 return FALSE; 240 241 for (i = 0; i < count; i++) { 242 struct pipe_resource *tex; 243 int natt; 244 245 switch (statts[i]) { 246 case ST_ATTACHMENT_FRONT_LEFT: 247 natt = NATIVE_ATTACHMENT_FRONT_LEFT; 248 break; 249 case ST_ATTACHMENT_BACK_LEFT: 250 natt = NATIVE_ATTACHMENT_BACK_LEFT; 251 break; 252 case ST_ATTACHMENT_FRONT_RIGHT: 253 natt = NATIVE_ATTACHMENT_FRONT_RIGHT; 254 break; 255 case ST_ATTACHMENT_BACK_RIGHT: 256 natt = NATIVE_ATTACHMENT_BACK_RIGHT; 257 break; 258 default: 259 natt = -1; 260 break; 261 } 262 263 if (natt >= 0) { 264 tex = textures[natt]; 265 266 if (statts[i] == stfbi->visual->render_buffer) 267 pipe_resource_reference(&gsurf->render_texture, tex); 268 269 if (attachment_mask & (1 << natt)) { 270 /* transfer the ownership to the caller */ 271 out[i] = tex; 272 attachment_mask &= ~(1 << natt); 273 } 274 else { 275 /* the attachment is listed more than once */ 276 pipe_resource_reference(&out[i], tex); 277 } 278 } 279 } 280 281 return TRUE; 282} 283 284struct st_framebuffer_iface * 285egl_g3d_create_st_framebuffer(_EGLSurface *surf) 286{ 287 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); 288 struct st_framebuffer_iface *stfbi; 289 290 stfbi = CALLOC_STRUCT(st_framebuffer_iface); 291 if (!stfbi) 292 return NULL; 293 294 stfbi->visual = &gsurf->stvis; 295 p_atomic_set(&stfbi->stamp, 1); 296 297 if (gsurf->base.Type != EGL_PBUFFER_BIT) { 298 stfbi->flush_front = egl_g3d_st_framebuffer_flush_front; 299 stfbi->validate = egl_g3d_st_framebuffer_validate; 300 } 301 else { 302 stfbi->flush_front = egl_g3d_st_framebuffer_flush_front_pbuffer; 303 stfbi->validate = egl_g3d_st_framebuffer_validate_pbuffer; 304 } 305 stfbi->st_manager_private = (void *) &gsurf->base; 306 307 return stfbi; 308} 309 310void 311egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi) 312{ 313 FREE(stfbi); 314} 315