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_dl.h"
34 #include "egldriver.h"
39 #include "egl_g3d_st.h"
41 struct egl_g3d_st_manager
{
42 struct st_manager base
;
46 static INLINE
struct egl_g3d_st_manager
*
47 egl_g3d_st_manager(struct st_manager
*smapi
)
49 return (struct egl_g3d_st_manager
*) smapi
;
53 egl_g3d_st_manager_get_egl_image(struct st_manager
*smapi
,
55 struct st_egl_image
*out
)
57 struct egl_g3d_st_manager
*gsmapi
= egl_g3d_st_manager(smapi
);
58 EGLImageKHR handle
= (EGLImageKHR
) egl_image
;
60 struct egl_g3d_image
*gimg
;
62 /* this is called from state trackers */
63 _eglLockMutex(&gsmapi
->display
->Mutex
);
65 img
= _eglLookupImage(handle
, gsmapi
->display
);
67 _eglUnlockMutex(&gsmapi
->display
->Mutex
);
71 gimg
= egl_g3d_image(img
);
74 pipe_resource_reference(&out
->texture
, gimg
->texture
);
75 out
->level
= gimg
->level
;
76 out
->layer
= gimg
->layer
;
78 _eglUnlockMutex(&gsmapi
->display
->Mutex
);
84 egl_g3d_st_manager_get_param(struct st_manager
*smapi
,
85 enum st_manager_param param
)
91 egl_g3d_create_st_manager(_EGLDisplay
*dpy
)
93 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
94 struct egl_g3d_st_manager
*gsmapi
;
96 gsmapi
= CALLOC_STRUCT(egl_g3d_st_manager
);
98 gsmapi
->display
= dpy
;
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
;
105 return &gsmapi
->base
;;
109 egl_g3d_destroy_st_manager(struct st_manager
*smapi
)
111 struct egl_g3d_st_manager
*gsmapi
= egl_g3d_st_manager(smapi
);
116 egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface
*stfbi
,
117 enum st_attachment_type statt
)
123 pbuffer_reference_openvg_image(struct egl_g3d_surface
*gsurf
)
129 pbuffer_allocate_pbuffer_texture(struct egl_g3d_surface
*gsurf
)
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
;
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
;
142 templ
.array_size
= 1;
143 templ
.format
= gsurf
->stvis
.color_format
;
144 /* for rendering and binding to texture */
145 templ
.bind
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
147 ptex
= screen
->resource_create(screen
, &templ
);
148 gsurf
->render_texture
= ptex
;
152 egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface
*stfbi
,
153 const enum st_attachment_type
*statts
,
155 struct pipe_resource
**out
)
157 _EGLSurface
*surf
= (_EGLSurface
*) stfbi
->st_manager_private
;
158 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
161 for (i
= 0; i
< count
; i
++) {
164 if (gsurf
->stvis
.render_buffer
!= statts
[i
])
167 if (!gsurf
->render_texture
) {
168 switch (gsurf
->client_buffer_type
) {
170 pbuffer_allocate_pbuffer_texture(gsurf
);
172 case EGL_OPENVG_IMAGE
:
173 pbuffer_reference_openvg_image(gsurf
);
179 if (!gsurf
->render_texture
)
183 pipe_resource_reference(&out
[i
], gsurf
->render_texture
);
190 egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface
*stfbi
,
191 enum st_attachment_type statt
)
193 _EGLSurface
*surf
= (_EGLSurface
*) stfbi
->st_manager_private
;
194 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
196 return gsurf
->native
->present(gsurf
->native
,
197 NATIVE_ATTACHMENT_FRONT_LEFT
, FALSE
, 0);
201 egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface
*stfbi
,
202 const enum st_attachment_type
*statts
,
204 struct pipe_resource
**out
)
206 _EGLSurface
*surf
= (_EGLSurface
*) stfbi
->st_manager_private
;
207 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
208 struct pipe_resource
*textures
[NUM_NATIVE_ATTACHMENTS
];
209 uint attachment_mask
= 0;
212 for (i
= 0; i
< count
; i
++) {
216 case ST_ATTACHMENT_FRONT_LEFT
:
217 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
219 case ST_ATTACHMENT_BACK_LEFT
:
220 natt
= NATIVE_ATTACHMENT_BACK_LEFT
;
222 case ST_ATTACHMENT_FRONT_RIGHT
:
223 natt
= NATIVE_ATTACHMENT_FRONT_RIGHT
;
225 case ST_ATTACHMENT_BACK_RIGHT
:
226 natt
= NATIVE_ATTACHMENT_BACK_RIGHT
;
234 attachment_mask
|= 1 << natt
;
237 if (!gsurf
->native
->validate(gsurf
->native
, attachment_mask
,
238 &gsurf
->sequence_number
, textures
, &gsurf
->base
.Width
,
239 &gsurf
->base
.Height
))
242 for (i
= 0; i
< count
; i
++) {
243 struct pipe_resource
*tex
;
247 case ST_ATTACHMENT_FRONT_LEFT
:
248 natt
= NATIVE_ATTACHMENT_FRONT_LEFT
;
250 case ST_ATTACHMENT_BACK_LEFT
:
251 natt
= NATIVE_ATTACHMENT_BACK_LEFT
;
253 case ST_ATTACHMENT_FRONT_RIGHT
:
254 natt
= NATIVE_ATTACHMENT_FRONT_RIGHT
;
256 case ST_ATTACHMENT_BACK_RIGHT
:
257 natt
= NATIVE_ATTACHMENT_BACK_RIGHT
;
265 tex
= textures
[natt
];
267 if (statts
[i
] == stfbi
->visual
->render_buffer
)
268 pipe_resource_reference(&gsurf
->render_texture
, tex
);
270 if (attachment_mask
& (1 << natt
)) {
271 /* transfer the ownership to the caller */
273 attachment_mask
&= ~(1 << natt
);
276 /* the attachment is listed more than once */
277 pipe_resource_reference(&out
[i
], tex
);
285 struct st_framebuffer_iface
*
286 egl_g3d_create_st_framebuffer(_EGLSurface
*surf
)
288 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
289 struct st_framebuffer_iface
*stfbi
;
291 stfbi
= CALLOC_STRUCT(st_framebuffer_iface
);
295 stfbi
->visual
= &gsurf
->stvis
;
296 p_atomic_set(&stfbi
->stamp
, 1);
298 if (gsurf
->base
.Type
!= EGL_PBUFFER_BIT
) {
299 stfbi
->flush_front
= egl_g3d_st_framebuffer_flush_front
;
300 stfbi
->validate
= egl_g3d_st_framebuffer_validate
;
303 stfbi
->flush_front
= egl_g3d_st_framebuffer_flush_front_pbuffer
;
304 stfbi
->validate
= egl_g3d_st_framebuffer_validate_pbuffer
;
306 stfbi
->st_manager_private
= (void *) &gsurf
->base
;
312 egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface
*stfbi
)