6488965e5b06fdf6b675cce464dfc1f0a302e404
[mesa.git] / src / gallium / state_trackers / egl / common / egl_g3d_st.c
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
37 struct egl_g3d_st_manager {
38 struct st_manager base;
39 _EGLDisplay *display;
40 };
41
42 static INLINE struct egl_g3d_st_manager *
43 egl_g3d_st_manager(struct st_manager *smapi)
44 {
45 return (struct egl_g3d_st_manager *) smapi;
46 }
47
48 struct st_api *
49 egl_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
88 struct st_manager *
89 egl_g3d_create_st_manager(_EGLDisplay *dpy)
90 {
91 struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
92 struct egl_g3d_st_manager *gsmapi;
93
94 gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
95 if (gsmapi) {
96 gsmapi->display = dpy;
97
98 gsmapi->base.screen = gdpy->native->screen;
99 }
100
101 return &gsmapi->base;;
102 }
103
104 void
105 egl_g3d_destroy_st_manager(struct st_manager *smapi)
106 {
107 struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
108 free(gsmapi);
109 }
110
111 static boolean
112 egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
113 enum st_attachment_type statt)
114 {
115 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
116 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
117
118 return gsurf->native->flush_frontbuffer(gsurf->native);
119 }
120
121 static boolean
122 egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
123 const enum st_attachment_type *statts,
124 unsigned count,
125 struct pipe_texture **out)
126 {
127 _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
128 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
129 struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
130 uint attachment_mask = 0;
131 unsigned i;
132
133 for (i = 0; i < count; i++) {
134 int natt;
135
136 switch (statts[i]) {
137 case ST_ATTACHMENT_FRONT_LEFT:
138 natt = NATIVE_ATTACHMENT_FRONT_LEFT;
139 break;
140 case ST_ATTACHMENT_BACK_LEFT:
141 natt = NATIVE_ATTACHMENT_BACK_LEFT;
142 break;
143 case ST_ATTACHMENT_FRONT_RIGHT:
144 natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
145 break;
146 case ST_ATTACHMENT_BACK_RIGHT:
147 natt = NATIVE_ATTACHMENT_BACK_RIGHT;
148 break;
149 default:
150 natt = -1;
151 break;
152 }
153
154 if (natt >= 0)
155 attachment_mask |= 1 << natt;
156 }
157
158 if (!gsurf->native->validate(gsurf->native, attachment_mask,
159 &gsurf->sequence_number, textures, &gsurf->base.Width,
160 &gsurf->base.Height))
161 return FALSE;
162
163 for (i = 0; i < count; i++) {
164 struct pipe_texture *tex;
165 int natt;
166
167 switch (statts[i]) {
168 case ST_ATTACHMENT_FRONT_LEFT:
169 natt = NATIVE_ATTACHMENT_FRONT_LEFT;
170 break;
171 case ST_ATTACHMENT_BACK_LEFT:
172 natt = NATIVE_ATTACHMENT_BACK_LEFT;
173 break;
174 case ST_ATTACHMENT_FRONT_RIGHT:
175 natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
176 break;
177 case ST_ATTACHMENT_BACK_RIGHT:
178 natt = NATIVE_ATTACHMENT_BACK_RIGHT;
179 break;
180 default:
181 natt = -1;
182 break;
183 }
184
185 if (natt >= 0) {
186 tex = textures[natt];
187
188 if (statts[i] == stfbi->visual->render_buffer)
189 pipe_texture_reference(&gsurf->render_texture, tex);
190
191 if (attachment_mask & (1 << natt)) {
192 /* transfer the ownership to the caller */
193 out[i] = tex;
194 attachment_mask &= ~(1 << natt);
195 }
196 else {
197 /* the attachment is listed more than once */
198 pipe_texture_reference(&out[i], tex);
199 }
200 }
201 }
202
203 return TRUE;
204 }
205
206 struct st_framebuffer_iface *
207 egl_g3d_create_st_framebuffer(_EGLSurface *surf)
208 {
209 struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
210 struct st_framebuffer_iface *stfbi;
211
212 stfbi = CALLOC_STRUCT(st_framebuffer_iface);
213 if (!stfbi)
214 return NULL;
215
216 stfbi->visual = &gsurf->stvis;
217 stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
218 stfbi->validate = egl_g3d_st_framebuffer_validate;
219 stfbi->st_manager_private = (void *) &gsurf->base;
220
221 return stfbi;
222 }
223
224 void
225 egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
226 {
227 free(stfbi);
228 }