Merge lp:~ahmed-a-ammar/pigment/pigment-gles2 into lp:~loic.molinari/pigment/trunk
- pigment-gles2
- Merge into trunk
Proposed by
Ahmed Ammar
Status: | Needs review |
---|---|
Proposed branch: | lp:~ahmed-a-ammar/pigment/pigment-gles2 |
Merge into: | lp:~loic.molinari/pigment/trunk |
Diff against target: |
1362 lines (+1077/-25) 9 files modified
ChangeLog (+15/-0) configure.ac (+48/-3) src/pgm/gst/pgm-gst-image.c (+77/-13) src/renderers/opengles/Makefile.am (+49/-1) src/renderers/opengles/backend-native.c (+22/-1) src/renderers/opengles/backend-x11.c (+26/-5) src/renderers/opengles/plugin-opengles2.c (+838/-0) tests/manual/test-geometry-sorting.c (+1/-1) tests/manual/test-gst-image.c (+1/-1) |
To merge this branch: | bzr merge lp:~ahmed-a-ammar/pigment/pigment-gles2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Loïc Molinari | Pending | ||
Review via email: mp+25630@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Unmerged revisions
- 255. By Ahmed Ammar
-
* configure.ac:
* src/pgm/gst/pgm- gst-image. c:
* src/renderers/opengles/ Makefile. am:
* src/renderers/opengles/ backend- native. c:
* src/renderers/opengles/ backend- x11.c:
* src/renderers/opengles/ plugin- opengles2. c:
Implementation for OpenGL ES 2 renderer. Currently supports three texture
units and no lights.* tests/manual/
test-geometry- sorting. c:
* tests/manual/test-gst- image.c:
Modified tests to use auto renderer selection.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'ChangeLog' | |||
2 | --- ChangeLog 2010-05-19 16:53:41 +0000 | |||
3 | +++ ChangeLog 2010-05-19 17:34:31 +0000 | |||
4 | @@ -1,3 +1,18 @@ | |||
5 | 1 | 2010-05-19 Ahmed Ammar <ahmed.ammar@connectmetv.com> | ||
6 | 2 | |||
7 | 3 | * configure.ac: | ||
8 | 4 | * src/pgm/gst/pgm-gst-image.c: | ||
9 | 5 | * src/renderers/opengles/Makefile.am: | ||
10 | 6 | * src/renderers/opengles/backend-native.c: | ||
11 | 7 | * src/renderers/opengles/backend-x11.c: | ||
12 | 8 | * src/renderers/opengles/plugin-opengles2.c: | ||
13 | 9 | Implementation for OpenGL ES 2 renderer. Currently supports three texture | ||
14 | 10 | units and no lights. | ||
15 | 11 | |||
16 | 12 | * tests/manual/test-geometry-sorting.c: | ||
17 | 13 | * tests/manual/test-gst-image.c: | ||
18 | 14 | Modified tests to use auto renderer selection. | ||
19 | 15 | |||
20 | 1 | 2010-05-19 Loïc Molinari <loic@fluendo.com> | 16 | 2010-05-19 Loïc Molinari <loic@fluendo.com> |
21 | 2 | 17 | ||
22 | 3 | Patch by: Ahmed Ammar <ahmed.ammar@connectmetv.com> | 18 | Patch by: Ahmed Ammar <ahmed.ammar@connectmetv.com> |
23 | 4 | 19 | ||
24 | === modified file 'configure.ac' | |||
25 | --- configure.ac 2010-05-10 10:09:50 +0000 | |||
26 | +++ configure.ac 2010-05-19 17:34:31 +0000 | |||
27 | @@ -247,6 +247,8 @@ | |||
28 | 247 | 247 | ||
29 | 248 | AC_CHECK_HEADERS([GLES/egl.h], [HAVE_EGL=yes], [HAVE_EGL=no]) | 248 | AC_CHECK_HEADERS([GLES/egl.h], [HAVE_EGL=yes], [HAVE_EGL=no]) |
30 | 249 | AC_CHECK_HEADERS([GLES/gl.h], [HAVE_GLES=yes], [HAVE_GLES=no]) | 249 | AC_CHECK_HEADERS([GLES/gl.h], [HAVE_GLES=yes], [HAVE_GLES=no]) |
31 | 250 | AC_CHECK_HEADERS([GLES2/gl2.h], [HAVE_GLES2=yes], [HAVE_GLES2=no]) | ||
32 | 251 | AC_CHECK_HEADERS([EGL/egl.h], [HAVE_EGL2=yes], [HAVE_EGL2=no]) | ||
33 | 250 | 252 | ||
34 | 251 | AC_ARG_ENABLE(opengles1-gdl, | 253 | AC_ARG_ENABLE(opengles1-gdl, |
35 | 252 | AS_HELP_STRING([--enable-opengles1-gdl],[enable build of OpenGL ES 1 renderer using Intel GDL backend]), | 254 | AS_HELP_STRING([--enable-opengles1-gdl],[enable build of OpenGL ES 1 renderer using Intel GDL backend]), |
36 | @@ -270,6 +272,38 @@ | |||
37 | 270 | ], | 272 | ], |
38 | 271 | [ENABLE_OPENGLES1_X11=no]) | 273 | [ENABLE_OPENGLES1_X11=no]) |
39 | 272 | 274 | ||
40 | 275 | AC_ARG_ENABLE(opengles2-x11, | ||
41 | 276 | AC_HELP_STRING([--enable-opengles2-x11], [enable build of OpenGL ES 2 renderer using X11 backend]), | ||
42 | 277 | [ | ||
43 | 278 | case "${enableval}" in | ||
44 | 279 | yes) ENABLE_OPENGLES2_X11=yes ;; | ||
45 | 280 | no) ENABLE_OPENGLES2_X11=no ;; | ||
46 | 281 | *) AC_MSG_ERROR(bad value ${enableval} for --enable-opengles2-x11) ;; | ||
47 | 282 | esac | ||
48 | 283 | ], | ||
49 | 284 | [ENABLE_OPENGLES2_X11=no]) | ||
50 | 285 | |||
51 | 286 | if test x$HAVE_EGL2 = xyes -a x$HAVE_GLES2 = xyes; then | ||
52 | 287 | if test x$ENABLE_OPENGLES2_X11 = xyes -a x$HAVE_X11 = xyes; then | ||
53 | 288 | AC_DEFINE([HAVE_EGL2_X11], [1], | ||
54 | 289 | [Defined to 1 if the OpenGL ES 2 renderer uses the X11 backend]) | ||
55 | 290 | HAVE_OPENGLES2_PLUGIN="yes" | ||
56 | 291 | OPENGLES2_BACKEND="(X11 backend)" | ||
57 | 292 | PGM_GLES2_CFLAGS="$XLIB_CFLAG $GLIB_CFLAGS" | ||
58 | 293 | PGM_GLES2_LIBS="$XLIB_LIBS $GLIB_LIBS -lGLESv2 -lEGL" | ||
59 | 294 | else | ||
60 | 295 | AC_DEFINE([HAVE_EGL2_NATIVE], [1], | ||
61 | 296 | [Defined to 1 if the OpenGL ES 2 renderer uses the native backend]) | ||
62 | 297 | HAVE_OPENGLES2_PLUGIN="yes" | ||
63 | 298 | OPENGLES2_BACKEND="(native backend)" | ||
64 | 299 | PGM_GLES2_CFLAGS="$GLIB_CFLAGS" | ||
65 | 300 | PGM_GLES2_LIBS="$GLIB_LIBS -lGLESv2 -lEGL" | ||
66 | 301 | fi | ||
67 | 302 | else | ||
68 | 303 | HAVE_OPENGLES2_PLUGIN="no" | ||
69 | 304 | OPENGLES2_BACKEND="" | ||
70 | 305 | fi | ||
71 | 306 | |||
72 | 273 | if test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes; then | 307 | if test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes; then |
73 | 274 | if test x$ENABLE_OPENGLES1_GDL = xyes; then | 308 | if test x$ENABLE_OPENGLES1_GDL = xyes; then |
74 | 275 | AC_CHECK_HEADERS([libgdl.h], [HAVE_GDL=yes], [HAVE_GDL=no]) | 309 | AC_CHECK_HEADERS([libgdl.h], [HAVE_GDL=yes], [HAVE_GDL=no]) |
75 | @@ -290,8 +324,8 @@ | |||
76 | 290 | [Defined to 1 if the OpenGL ES 1 renderer uses the X11 backend]) | 324 | [Defined to 1 if the OpenGL ES 1 renderer uses the X11 backend]) |
77 | 291 | HAVE_OPENGLES1_PLUGIN="yes" | 325 | HAVE_OPENGLES1_PLUGIN="yes" |
78 | 292 | OPENGLES1_BACKEND="(X11 backend)" | 326 | OPENGLES1_BACKEND="(X11 backend)" |
81 | 293 | PGM_GLES1_CFLAGS="$GLIB_CFLAGS" | 327 | PGM_GLES1_CFLAGS="$XLIB_LIBS $GLIB_CFLAGS" |
82 | 294 | PGM_GLES1_LIBS="$GLIB_LIBS -lGLES_CM" | 328 | PGM_GLES1_LIBS="$XLIB_LIBS $GLIB_LIBS -lGLES_CM -lEGL" |
83 | 295 | else | 329 | else |
84 | 296 | HAVE_OPENGLES1_PLUGIN="no" | 330 | HAVE_OPENGLES1_PLUGIN="no" |
85 | 297 | OPENGLES1_BACKEND="" | 331 | OPENGLES1_BACKEND="" |
86 | @@ -302,7 +336,7 @@ | |||
87 | 302 | HAVE_OPENGLES1_PLUGIN="yes" | 336 | HAVE_OPENGLES1_PLUGIN="yes" |
88 | 303 | OPENGLES1_BACKEND="(native backend)" | 337 | OPENGLES1_BACKEND="(native backend)" |
89 | 304 | PGM_GLES1_CFLAGS="$GLIB_CFLAGS" | 338 | PGM_GLES1_CFLAGS="$GLIB_CFLAGS" |
91 | 305 | PGM_GLES1_LIBS="$GLIB_LIBS -lGLES_CM" | 339 | PGM_GLES1_LIBS="$GLIB_LIBS -lGLES_CM -lEGL" |
92 | 306 | fi | 340 | fi |
93 | 307 | else | 341 | else |
94 | 308 | HAVE_OPENGLES1_PLUGIN="no" | 342 | HAVE_OPENGLES1_PLUGIN="no" |
95 | @@ -313,9 +347,19 @@ | |||
96 | 313 | AC_SUBST(HAVE_OPENGLES1_PLUGIN) | 347 | AC_SUBST(HAVE_OPENGLES1_PLUGIN) |
97 | 314 | AC_SUBST(PGM_GLES1_CFLAGS) | 348 | AC_SUBST(PGM_GLES1_CFLAGS) |
98 | 315 | AC_SUBST(PGM_GLES1_LIBS) | 349 | AC_SUBST(PGM_GLES1_LIBS) |
99 | 350 | |||
100 | 351 | AC_SUBST(OPENGLES2_BACKEND) | ||
101 | 352 | AC_SUBST(HAVE_OPENGLES2_PLUGIN) | ||
102 | 353 | AC_SUBST(PGM_GLES2_CFLAGS) | ||
103 | 354 | AC_SUBST(PGM_GLES2_LIBS) | ||
104 | 355 | |||
105 | 316 | AM_CONDITIONAL(HAVE_OPENGLES1_PLUGIN_COND, test x$HAVE_OPENGLES1_PLUGIN = xyes) | 356 | AM_CONDITIONAL(HAVE_OPENGLES1_PLUGIN_COND, test x$HAVE_OPENGLES1_PLUGIN = xyes) |
106 | 357 | AM_CONDITIONAL(HAVE_OPENGLES2_PLUGIN_COND, test x$HAVE_OPENGLES2_PLUGIN = xyes) | ||
107 | 358 | AM_CONDITIONAL(HAVE_OPENGLES_PLUGIN_COND, test x$HAVE_OPENGLES2_PLUGIN = xyes -o x$HAVE_OPENGLES1_PLUGIN = xyes ) | ||
108 | 317 | AM_CONDITIONAL(HAVE_EGL_GDL_COND, test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes -a x$ENABLE_OPENGLES1_GDL = xyes) | 359 | AM_CONDITIONAL(HAVE_EGL_GDL_COND, test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes -a x$ENABLE_OPENGLES1_GDL = xyes) |
109 | 318 | AM_CONDITIONAL(HAVE_EGL_X11_COND, test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes -a x$ENABLE_OPENGLES1_X11 = xyes) | 360 | AM_CONDITIONAL(HAVE_EGL_X11_COND, test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes -a x$ENABLE_OPENGLES1_X11 = xyes) |
110 | 361 | AM_CONDITIONAL(HAVE_EGL2_X11_COND, test x$HAVE_EGL2 = xyes -a x$HAVE_GLES2 = xyes -a x$ENABLE_OPENGLES2_X11 = xyes) | ||
111 | 362 | AM_CONDITIONAL(HAVE_EGL2_NATIVE_COND, test x$HAVE_EGL2 = xyes -a x$HAVE_GLES2 = xyes -a x$ENABLE_OPENGLES2_X11 = xno) | ||
112 | 319 | AM_CONDITIONAL(HAVE_EGL_NATIVE_COND, test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes -a x$ENABLE_OPENGLES1_X11 = xno -a x$ENABLE_OPENGLES1_GDL = xno) | 363 | AM_CONDITIONAL(HAVE_EGL_NATIVE_COND, test x$HAVE_EGL = xyes -a x$HAVE_GLES = xyes -a x$ENABLE_OPENGLES1_X11 = xno -a x$ENABLE_OPENGLES1_GDL = xno) |
113 | 320 | 364 | ||
114 | 321 | # *** Documentation *** | 365 | # *** Documentation *** |
115 | @@ -448,6 +492,7 @@ | |||
116 | 448 | echo " 3D graphics engine: yes" | 492 | echo " 3D graphics engine: yes" |
117 | 449 | echo " OpenGL renderer: ${HAVE_OPENGL_PLUGIN} ${OPENGL_BACKEND}" | 493 | echo " OpenGL renderer: ${HAVE_OPENGL_PLUGIN} ${OPENGL_BACKEND}" |
118 | 450 | echo " OpenGL ES 1 renderer: ${HAVE_OPENGLES1_PLUGIN} ${OPENGLES1_BACKEND}" | 494 | echo " OpenGL ES 1 renderer: ${HAVE_OPENGLES1_PLUGIN} ${OPENGLES1_BACKEND}" |
119 | 495 | echo " OpenGL ES 2 renderer: ${HAVE_OPENGLES2_PLUGIN} ${OPENGLES2_BACKEND}" | ||
120 | 451 | echo " GUI classes: ${HAVE_GUI_CLASSES}" | 496 | echo " GUI classes: ${HAVE_GUI_CLASSES}" |
121 | 452 | echo " GStreamer classes: ${HAVE_GST_CLASSES}" | 497 | echo " GStreamer classes: ${HAVE_GST_CLASSES}" |
122 | 453 | echo " GTK+ classes: ${HAVE_GTK_CLASSES}" | 498 | echo " GTK+ classes: ${HAVE_GTK_CLASSES}" |
123 | 454 | 499 | ||
124 | === modified file 'src/pgm/gst/pgm-gst-image.c' | |||
125 | --- src/pgm/gst/pgm-gst-image.c 2009-11-30 18:52:29 +0000 | |||
126 | +++ src/pgm/gst/pgm-gst-image.c 2010-05-19 17:34:31 +0000 | |||
127 | @@ -17,6 +17,7 @@ | |||
128 | 17 | * | 17 | * |
129 | 18 | * Contributor(s): | 18 | * Contributor(s): |
130 | 19 | * Loïc Molinari <loic@fluendo.com> | 19 | * Loïc Molinari <loic@fluendo.com> |
131 | 20 | * Ahmed Ammar <ahmed.ammar@connecmetv.com> | ||
132 | 20 | */ | 21 | */ |
133 | 21 | 22 | ||
134 | 22 | /** | 23 | /** |
135 | @@ -47,10 +48,12 @@ | |||
136 | 47 | static void pgm_gst_image_map (PgmNode*, PgmRenderer*, gfloat, gfloat); | 48 | static void pgm_gst_image_map (PgmNode*, PgmRenderer*, gfloat, gfloat); |
137 | 48 | static void pgm_gst_image_unmap (PgmNode*); | 49 | static void pgm_gst_image_unmap (PgmNode*); |
138 | 49 | 50 | ||
143 | 50 | /* OpenGL ARB fragment program to convert from YV12/I420 planar YCbCr to RGB | 51 | /* Shaders converting from YV12/I420 planar YCbCr to RGB color space using |
144 | 51 | * color space using coefficients from the ITU-R BT.601 standard for SDTV and | 52 | * coefficients from the ITU-R BT.601 standard for SDTV and the equations |
145 | 52 | * the equations detailed in the book "Video Demystified, 4th Edition" */ | 53 | * detailed in the book "Video Demystified, 4th Edition" */ |
146 | 53 | static const gchar *ycbcr2rgb_bt601_fp = | 54 | |
147 | 55 | /* OpenGL ARB fragment program */ | ||
148 | 56 | static const gchar *ycbcr2rgb_bt601_glarbfp = | ||
149 | 54 | "!!ARBfp1.0" | 57 | "!!ARBfp1.0" |
150 | 55 | "OPTION ARB_precision_hint_fastest;" | 58 | "OPTION ARB_precision_hint_fastest;" |
151 | 56 | "ATTRIB position = fragment.texcoord[0];" | 59 | "ATTRIB position = fragment.texcoord[0];" |
152 | @@ -65,12 +68,52 @@ | |||
153 | 65 | "MUL result.color, fragment.color, color;" | 68 | "MUL result.color, fragment.color, color;" |
154 | 66 | "END"; | 69 | "END"; |
155 | 67 | 70 | ||
156 | 71 | /* OpenGL ES 2 shaders */ | ||
157 | 72 | static const gchar *ycbcr2rgb_bt601_glslesvp = | ||
158 | 73 | "uniform mat4 pgm_projection;\n" | ||
159 | 74 | "uniform mat4 pgm_modelview;\n" | ||
160 | 75 | "attribute highp vec4 pgm_position;\n" | ||
161 | 76 | "attribute highp vec4 pgm_color;\n" | ||
162 | 77 | "attribute highp vec4 pgm_texcoord;\n" | ||
163 | 78 | "varying highp vec2 frag_texcoord;\n" | ||
164 | 79 | "varying highp vec4 frag_color;\n" | ||
165 | 80 | "void main() {\n" | ||
166 | 81 | " frag_texcoord = pgm_texcoord.xy;\n" | ||
167 | 82 | " frag_color = pgm_color/255.0;\n" | ||
168 | 83 | " gl_Position = pgm_projection * pgm_modelview * pgm_position;\n" | ||
169 | 84 | "}\n"; | ||
170 | 85 | static const gchar *ycbcr2rgb_bt601_glslesfp = | ||
171 | 86 | "uniform sampler2D pgm_texture0;\n" | ||
172 | 87 | "uniform sampler2D pgm_texture1;\n" | ||
173 | 88 | "uniform sampler2D pgm_texture2;\n" | ||
174 | 89 | "varying highp vec2 frag_texcoord;\n" | ||
175 | 90 | "varying lowp vec4 frag_color;\n" | ||
176 | 91 | "void main() {" | ||
177 | 92 | " const lowp vec4 kcr = vec4( 1.596, -0.813, 0, 0 );\n" | ||
178 | 93 | " const lowp vec4 kcb = vec4( 0, -0.391, 2.018, 0 );\n" | ||
179 | 94 | " const lowp vec4 kadj = vec4( -0.871, 0.53, -1.082, 0 );\n" | ||
180 | 95 | " lowp float y = texture2D(pgm_texture0, frag_texcoord).x;\n" | ||
181 | 96 | " lowp float cb = texture2D(pgm_texture1, frag_texcoord).x;\n" | ||
182 | 97 | " lowp float cr = texture2D(pgm_texture2, frag_texcoord).x;\n" | ||
183 | 98 | " lowp vec4 color = vec4(y * 1.164);\n" | ||
184 | 99 | " color += kcr * cr;\n" | ||
185 | 100 | " color += kcb * cb;\n" | ||
186 | 101 | " color += kadj;\n" | ||
187 | 102 | " gl_FragColor = vec4(color.r, color.g, color.b, 1.0);\n" | ||
188 | 103 | "}\n"; | ||
189 | 104 | |||
190 | 68 | /* Image negociated format */ | 105 | /* Image negociated format */ |
192 | 69 | typedef enum { | 106 | enum { |
193 | 70 | IMAGE_NOT_NEGOCIATED = 0, | 107 | IMAGE_NOT_NEGOCIATED = 0, |
194 | 71 | IMAGE_RGB, | 108 | IMAGE_RGB, |
195 | 72 | IMAGE_YCBCR | 109 | IMAGE_YCBCR |
197 | 73 | } ImageNegociatedFormat; | 110 | }; |
198 | 111 | |||
199 | 112 | /* Image available shading language */ | ||
200 | 113 | enum { | ||
201 | 114 | IMAGE_SHADING_LANGUAGE_ARBP = (1 << 0), | ||
202 | 115 | IMAGE_SHADING_LANGUAGE_GLSLES = (1 << 1) | ||
203 | 116 | } ; | ||
204 | 74 | 117 | ||
205 | 75 | /* Private structure */ | 118 | /* Private structure */ |
206 | 76 | struct _PgmGstImagePimpl { | 119 | struct _PgmGstImagePimpl { |
207 | @@ -86,6 +129,7 @@ | |||
208 | 86 | gfloat texture_ratio; | 129 | gfloat texture_ratio; |
209 | 87 | PgmGstImageLayout layout; | 130 | PgmGstImageLayout layout; |
210 | 88 | guint8 negociated_format; | 131 | guint8 negociated_format; |
211 | 132 | guint8 shading_language; | ||
212 | 89 | }; | 133 | }; |
213 | 90 | 134 | ||
214 | 91 | /* GObject type definition */ | 135 | /* GObject type definition */ |
215 | @@ -158,6 +202,7 @@ | |||
216 | 158 | /* pimpl->texture_ratio = 0.0f; */ | 202 | /* pimpl->texture_ratio = 0.0f; */ |
217 | 159 | pimpl->layout = PGM_GST_IMAGE_SCALED; | 203 | pimpl->layout = PGM_GST_IMAGE_SCALED; |
218 | 160 | /* pimpl->negociated_format = 0; */ | 204 | /* pimpl->negociated_format = 0; */ |
219 | 205 | /* pimpl->shading_language = 0; */ | ||
220 | 161 | } | 206 | } |
221 | 162 | 207 | ||
222 | 163 | /* Private functions */ | 208 | /* Private functions */ |
223 | @@ -317,11 +362,18 @@ | |||
224 | 317 | pgm_mesh_set_texture (pimpl->mesh, 1, cb); | 362 | pgm_mesh_set_texture (pimpl->mesh, 1, cb); |
225 | 318 | pgm_mesh_set_texture (pimpl->mesh, 2, cr); | 363 | pgm_mesh_set_texture (pimpl->mesh, 2, cr); |
226 | 319 | 364 | ||
232 | 320 | /* Since we checked the support for ARB fragment program support for the | 365 | /* Since we checked the support for shaders for the mapped renderer in the |
233 | 321 | * mapped renderer in the map virtual function, we can safely apply the | 366 | * map virtual function, we can safely apply the color space conversion |
234 | 322 | * color space conversion shader to the mesh */ | 367 | * shader to the mesh depending on the supported language */ |
235 | 323 | shader = pgm_shader_new ("arbp", NULL, 0, NULL, 0, ycbcr2rgb_bt601_fp, | 368 | if (pimpl->shading_language & IMAGE_SHADING_LANGUAGE_ARBP) |
236 | 324 | strlen (ycbcr2rgb_bt601_fp), 0); | 369 | shader = pgm_shader_new ("arbp", NULL, 0, NULL, 0, |
237 | 370 | ycbcr2rgb_bt601_glarbfp, | ||
238 | 371 | strlen (ycbcr2rgb_bt601_glarbfp), 0); | ||
239 | 372 | else | ||
240 | 373 | shader = pgm_shader_new ("glsles", ycbcr2rgb_bt601_glslesvp, | ||
241 | 374 | strlen (ycbcr2rgb_bt601_glslesvp), NULL, 0, | ||
242 | 375 | ycbcr2rgb_bt601_glslesfp, | ||
243 | 376 | strlen (ycbcr2rgb_bt601_glslesfp), 0); | ||
244 | 325 | pgm_mesh_set_shader (pimpl->mesh, shader); | 377 | pgm_mesh_set_shader (pimpl->mesh, shader); |
245 | 326 | 378 | ||
246 | 327 | /* Store the texture ratio, no need to check for a height of 0 since such a | 379 | /* Store the texture ratio, no need to check for a height of 0 since such a |
247 | @@ -410,7 +462,20 @@ | |||
248 | 410 | if (strcmp (sl->language, "arbp") == 0) | 462 | if (strcmp (sl->language, "arbp") == 0) |
249 | 411 | { | 463 | { |
250 | 412 | if (sl->programs | PGM_RENDERER_FRAGMENT_PROGRAM) | 464 | if (sl->programs | PGM_RENDERER_FRAGMENT_PROGRAM) |
252 | 413 | formats |= PGM_GST_BASE_YCBCR; | 465 | { |
253 | 466 | formats |= PGM_GST_BASE_YCBCR; | ||
254 | 467 | pimpl->shading_language = IMAGE_SHADING_LANGUAGE_ARBP; | ||
255 | 468 | } | ||
256 | 469 | break; | ||
257 | 470 | } | ||
258 | 471 | else if (strcmp (sl->language, "glsles") == 0) | ||
259 | 472 | { | ||
260 | 473 | if (sl->programs | PGM_RENDERER_FRAGMENT_PROGRAM | ||
261 | 474 | && sl->programs | PGM_RENDERER_VERTEX_PROGRAM) | ||
262 | 475 | { | ||
263 | 476 | formats |= PGM_GST_BASE_YCBCR; | ||
264 | 477 | pimpl->shading_language = IMAGE_SHADING_LANGUAGE_GLSLES; | ||
265 | 478 | } | ||
266 | 414 | break; | 479 | break; |
267 | 415 | } | 480 | } |
268 | 416 | walk = walk->next; | 481 | walk = walk->next; |
269 | @@ -536,7 +601,6 @@ | |||
270 | 536 | /* Set up the initial average position */ | 601 | /* Set up the initial average position */ |
271 | 537 | pgm_mesh_set_average_position (pimpl->mesh, x + pimpl->width * 0.5f, | 602 | pgm_mesh_set_average_position (pimpl->mesh, x + pimpl->width * 0.5f, |
272 | 538 | y + pimpl->height * 0.5f, z); | 603 | y + pimpl->height * 0.5f, z); |
273 | 539 | |||
274 | 540 | return PGM_NODE (image); | 604 | return PGM_NODE (image); |
275 | 541 | } | 605 | } |
276 | 542 | 606 | ||
277 | 543 | 607 | ||
278 | === modified file 'src/renderers/opengles/Makefile.am' | |||
279 | --- src/renderers/opengles/Makefile.am 2009-11-04 17:50:39 +0000 | |||
280 | +++ src/renderers/opengles/Makefile.am 2010-05-19 17:34:31 +0000 | |||
281 | @@ -1,7 +1,18 @@ | |||
283 | 1 | if HAVE_OPENGLES1_PLUGIN_COND | 1 | if HAVE_OPENGLES_PLUGIN_COND |
284 | 2 | 2 | ||
285 | 3 | plugindir = @PLUGIN_PATH@ | 3 | plugindir = @PLUGIN_PATH@ |
286 | 4 | |||
287 | 5 | if HAVE_OPENGLES1_PLUGIN_COND | ||
288 | 6 | if HAVE_OPENGLES2_PLUGIN_COND | ||
289 | 7 | plugin_LTLIBRARIES = libpgmopengles1.la libpgmopengles2.la | ||
290 | 8 | else | ||
291 | 4 | plugin_LTLIBRARIES = libpgmopengles1.la | 9 | plugin_LTLIBRARIES = libpgmopengles1.la |
292 | 10 | endif | ||
293 | 11 | else | ||
294 | 12 | plugin_LTLIBRARIES = libpgmopengles2.la | ||
295 | 13 | endif | ||
296 | 14 | |||
297 | 15 | if HAVE_OPENGLES1_PLUGIN_COND | ||
298 | 5 | 16 | ||
299 | 6 | libpgmopengles1_la_DEPENDENCIES = \ | 17 | libpgmopengles1_la_DEPENDENCIES = \ |
300 | 7 | $(top_builddir)/src/pgm/libpigment-@PGM_MAJORMINOR@.la | 18 | $(top_builddir)/src/pgm/libpigment-@PGM_MAJORMINOR@.la |
301 | @@ -39,3 +50,40 @@ | |||
302 | 39 | noinst_HEADERS = backend.h | 50 | noinst_HEADERS = backend.h |
303 | 40 | 51 | ||
304 | 41 | endif | 52 | endif |
305 | 53 | |||
306 | 54 | if HAVE_OPENGLES2_PLUGIN_COND | ||
307 | 55 | |||
308 | 56 | |||
309 | 57 | libpgmopengles2_la_DEPENDENCIES = \ | ||
310 | 58 | $(top_builddir)/src/pgm/libpigment-@PGM_MAJORMINOR@.la | ||
311 | 59 | |||
312 | 60 | if HAVE_EGL2_NATIVE_COND | ||
313 | 61 | libpgmopengles2_la_SOURCES = \ | ||
314 | 62 | plugin-opengles2.c \ | ||
315 | 63 | backend-native.c | ||
316 | 64 | endif | ||
317 | 65 | if HAVE_EGL2_X11_COND | ||
318 | 66 | libpgmopengles2_la_SOURCES = \ | ||
319 | 67 | plugin-opengles2.c \ | ||
320 | 68 | backend-x11.c | ||
321 | 69 | endif | ||
322 | 70 | |||
323 | 71 | # egl.h contains non-strictly prototyped function declarations | ||
324 | 72 | libpgmopengles2_la_CFLAGS = \ | ||
325 | 73 | -I$(top_srcdir)/src -DHAVE_GLES2 \ | ||
326 | 74 | $(PGM_CFLAGS) -Wno-strict-prototypes \ | ||
327 | 75 | $(PGM_GLES2_CFLAGS) | ||
328 | 76 | |||
329 | 77 | libpgmopengles2_la_LIBADD = \ | ||
330 | 78 | $(top_builddir)/src/pgm/libpigment-@PGM_MAJORMINOR@.la \ | ||
331 | 79 | $(PGM_GLES2_LIBS) | ||
332 | 80 | |||
333 | 81 | libpgmopengles2_la_LDFLAGS = $(PGM_PLUGIN_LDFLAGS) | ||
334 | 82 | |||
335 | 83 | libpgmopengles2_la_LIBTOOLFLAGS = --tag=disable-static | ||
336 | 84 | |||
337 | 85 | noinst_HEADERS = backend.h | ||
338 | 86 | |||
339 | 87 | endif | ||
340 | 88 | |||
341 | 89 | endif | ||
342 | 42 | 90 | ||
343 | === modified file 'src/renderers/opengles/backend-native.c' | |||
344 | --- src/renderers/opengles/backend-native.c 2010-05-11 08:42:10 +0000 | |||
345 | +++ src/renderers/opengles/backend-native.c 2010-05-19 17:34:31 +0000 | |||
346 | @@ -17,6 +17,7 @@ | |||
347 | 17 | * | 17 | * |
348 | 18 | * Contributor(s): | 18 | * Contributor(s): |
349 | 19 | * Loïc Molinari <loic@fluendo.com> | 19 | * Loïc Molinari <loic@fluendo.com> |
350 | 20 | * Ahmed Ammar <ahmed.ammar@connectmetv.com> | ||
351 | 20 | */ | 21 | */ |
352 | 21 | 22 | ||
353 | 22 | #ifdef HAVE_CONFIG_H | 23 | #ifdef HAVE_CONFIG_H |
354 | @@ -24,7 +25,12 @@ | |||
355 | 24 | #endif /* HAVE_CONFIG_H */ | 25 | #endif /* HAVE_CONFIG_H */ |
356 | 25 | 26 | ||
357 | 26 | #include "backend.h" | 27 | #include "backend.h" |
358 | 28 | |||
359 | 29 | #ifdef HAVE_GLES2 | ||
360 | 30 | #include <EGL/egl.h> | ||
361 | 31 | #else | ||
362 | 27 | #include <GLES/egl.h> | 32 | #include <GLES/egl.h> |
363 | 33 | #endif | ||
364 | 28 | 34 | ||
365 | 29 | /* Private structure */ | 35 | /* Private structure */ |
366 | 30 | typedef struct { | 36 | typedef struct { |
367 | @@ -87,9 +93,21 @@ | |||
368 | 87 | EGL_GREEN_SIZE, 6, | 93 | EGL_GREEN_SIZE, 6, |
369 | 88 | EGL_BLUE_SIZE, 5, | 94 | EGL_BLUE_SIZE, 5, |
370 | 89 | EGL_DEPTH_SIZE, 16, | 95 | EGL_DEPTH_SIZE, 16, |
371 | 96 | #ifdef HAVE_GLES2 | ||
372 | 97 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | ||
373 | 98 | #else | ||
374 | 90 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, | 99 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, |
375 | 100 | #endif | ||
376 | 91 | EGL_NONE | 101 | EGL_NONE |
377 | 92 | }; | 102 | }; |
378 | 103 | |||
379 | 104 | const EGLint context_attribs[] = { | ||
380 | 105 | #ifdef HAVE_GLES2 | ||
381 | 106 | EGL_CONTEXT_CLIENT_VERSION, 2, | ||
382 | 107 | #endif | ||
383 | 108 | EGL_NONE | ||
384 | 109 | }; | ||
385 | 110 | |||
386 | 93 | const gchar *version, *vendor, *extensions; | 111 | const gchar *version, *vendor, *extensions; |
387 | 94 | BackendNative *native; | 112 | BackendNative *native; |
388 | 95 | EGLConfig config; | 113 | EGLConfig config; |
389 | @@ -106,6 +124,9 @@ | |||
390 | 106 | PGM_ERROR_OBJECT (native->rdr, "can't open default display"); | 124 | PGM_ERROR_OBJECT (native->rdr, "can't open default display"); |
391 | 107 | return NULL; | 125 | return NULL; |
392 | 108 | } | 126 | } |
393 | 127 | |||
394 | 128 | eglBindAPI(EGL_OPENGL_ES_API); | ||
395 | 129 | |||
396 | 109 | if (eglInitialize (native->dpy, NULL, NULL) == EGL_FALSE) | 130 | if (eglInitialize (native->dpy, NULL, NULL) == EGL_FALSE) |
397 | 110 | { | 131 | { |
398 | 111 | print_egl_error (native->rdr, "eglInitialize"); | 132 | print_egl_error (native->rdr, "eglInitialize"); |
399 | @@ -142,7 +163,7 @@ | |||
400 | 142 | return NULL; | 163 | return NULL; |
401 | 143 | } | 164 | } |
402 | 144 | native->context = eglCreateContext (native->dpy, config, | 165 | native->context = eglCreateContext (native->dpy, config, |
404 | 145 | EGL_NO_CONTEXT, NULL); | 166 | EGL_NO_CONTEXT, context_attribs); |
405 | 146 | if (native->context == EGL_NO_CONTEXT) | 167 | if (native->context == EGL_NO_CONTEXT) |
406 | 147 | { | 168 | { |
407 | 148 | print_egl_error (native->rdr, "eglCreateContext"); | 169 | print_egl_error (native->rdr, "eglCreateContext"); |
408 | 149 | 170 | ||
409 | === modified file 'src/renderers/opengles/backend-x11.c' | |||
410 | --- src/renderers/opengles/backend-x11.c 2010-05-11 08:42:10 +0000 | |||
411 | +++ src/renderers/opengles/backend-x11.c 2010-05-19 17:34:31 +0000 | |||
412 | @@ -17,6 +17,7 @@ | |||
413 | 17 | * | 17 | * |
414 | 18 | * Contributor(s): | 18 | * Contributor(s): |
415 | 19 | * Loïc Molinari <loic@fluendo.com> | 19 | * Loïc Molinari <loic@fluendo.com> |
416 | 20 | * Ahmed Ammar <ahmed.ammar@connectmetv.com> | ||
417 | 20 | */ | 21 | */ |
418 | 21 | 22 | ||
419 | 22 | #ifdef HAVE_CONFIG_H | 23 | #ifdef HAVE_CONFIG_H |
420 | @@ -25,7 +26,11 @@ | |||
421 | 25 | 26 | ||
422 | 26 | #include "backend.h" | 27 | #include "backend.h" |
423 | 27 | #include <string.h> /* memset */ | 28 | #include <string.h> /* memset */ |
424 | 29 | #ifdef HAVE_GLES2 | ||
425 | 30 | #include <EGL/egl.h> | ||
426 | 31 | #else | ||
427 | 28 | #include <GLES/egl.h> | 32 | #include <GLES/egl.h> |
428 | 33 | #endif | ||
429 | 29 | #include <X11/Xlib.h> | 34 | #include <X11/Xlib.h> |
430 | 30 | #include <X11/Xutil.h> | 35 | #include <X11/Xutil.h> |
431 | 31 | #include <X11/Xatom.h> | 36 | #include <X11/Xatom.h> |
432 | @@ -643,8 +648,19 @@ | |||
433 | 643 | EGL_GREEN_SIZE, 8, | 648 | EGL_GREEN_SIZE, 8, |
434 | 644 | EGL_BLUE_SIZE, 8, | 649 | EGL_BLUE_SIZE, 8, |
435 | 645 | EGL_DEPTH_SIZE, 0, | 650 | EGL_DEPTH_SIZE, 0, |
436 | 651 | #ifdef HAVE_GLES2 | ||
437 | 652 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | ||
438 | 653 | #endif | ||
439 | 646 | EGL_NONE | 654 | EGL_NONE |
440 | 647 | }; | 655 | }; |
441 | 656 | |||
442 | 657 | const EGLint context_attribs[] = { | ||
443 | 658 | #ifdef HAVE_GLES2 | ||
444 | 659 | EGL_CONTEXT_CLIENT_VERSION, 2, | ||
445 | 660 | #endif | ||
446 | 661 | EGL_NONE | ||
447 | 662 | }; | ||
448 | 663 | |||
449 | 648 | const gchar *version, *vendor, *extensions; | 664 | const gchar *version, *vendor, *extensions; |
450 | 649 | BackendX11 *x11; | 665 | BackendX11 *x11; |
451 | 650 | EGLConfig config; | 666 | EGLConfig config; |
452 | @@ -670,6 +686,9 @@ | |||
453 | 670 | g_slice_free1 (sizeof (BackendX11), x11); | 686 | g_slice_free1 (sizeof (BackendX11), x11); |
454 | 671 | return NULL; | 687 | return NULL; |
455 | 672 | } | 688 | } |
456 | 689 | |||
457 | 690 | eglBindAPI(EGL_OPENGL_ES_API); | ||
458 | 691 | |||
459 | 673 | if (eglInitialize (x11->egldpy, NULL, NULL) == EGL_FALSE) | 692 | if (eglInitialize (x11->egldpy, NULL, NULL) == EGL_FALSE) |
460 | 674 | { | 693 | { |
461 | 675 | print_egl_error (x11->rdr, "eglInitialize"); | 694 | print_egl_error (x11->rdr, "eglInitialize"); |
462 | @@ -709,7 +728,8 @@ | |||
463 | 709 | g_slice_free1 (sizeof (BackendX11), x11); | 728 | g_slice_free1 (sizeof (BackendX11), x11); |
464 | 710 | return NULL; | 729 | return NULL; |
465 | 711 | } | 730 | } |
467 | 712 | x11->context = eglCreateContext (x11->egldpy, config, EGL_NO_CONTEXT, NULL); | 731 | x11->context = eglCreateContext (x11->egldpy, config, |
468 | 732 | EGL_NO_CONTEXT, context_attribs); | ||
469 | 713 | if (x11->context == EGL_NO_CONTEXT) | 733 | if (x11->context == EGL_NO_CONTEXT) |
470 | 714 | { | 734 | { |
471 | 715 | print_egl_error (x11->rdr, "eglCreateContext"); | 735 | print_egl_error (x11->rdr, "eglCreateContext"); |
472 | @@ -856,16 +876,17 @@ | |||
473 | 856 | { | 876 | { |
474 | 857 | case PGM_RENDERER_LEFT_ARROW: | 877 | case PGM_RENDERER_LEFT_ARROW: |
475 | 858 | XDefineCursor (x11->dpy, x11->win, XCreateFontCursor | 878 | XDefineCursor (x11->dpy, x11->win, XCreateFontCursor |
477 | 859 | (x11->dpy, XC_top_left_arrow)); | 879 | (x11->dpy, XC_left_ptr)); |
478 | 860 | break; | 880 | break; |
479 | 861 | 881 | ||
480 | 862 | case PGM_RENDERER_INHERIT: | 882 | case PGM_RENDERER_INHERIT: |
481 | 863 | XDefineCursor (x11->dpy, x11->win, XCreateFontCursor | 883 | XDefineCursor (x11->dpy, x11->win, XCreateFontCursor |
483 | 864 | (x11->dpy, XC_top_left_arrow)); | 884 | (x11->dpy, XC_left_ptr)); |
484 | 865 | break; | 885 | break; |
485 | 866 | 886 | ||
488 | 867 | case PGM_RENDERER_NONE: | 887 | case PGM_RENDERER_FLEUR: |
489 | 868 | XDefineCursor (x11->dpy, x11->win, x11->none_cursor); | 888 | XDefineCursor (x11->dpy, x11->win, |
490 | 889 | XCreateFontCursor (x11->dpy, XC_fleur)); | ||
491 | 869 | break; | 890 | break; |
492 | 870 | 891 | ||
493 | 871 | default: | 892 | default: |
494 | 872 | 893 | ||
495 | === added file 'src/renderers/opengles/plugin-opengles2.c' | |||
496 | --- src/renderers/opengles/plugin-opengles2.c 1970-01-01 00:00:00 +0000 | |||
497 | +++ src/renderers/opengles/plugin-opengles2.c 2010-05-19 17:34:31 +0000 | |||
498 | @@ -0,0 +1,838 @@ | |||
499 | 1 | /* | ||
500 | 2 | * Pigment 3D graphics engine | ||
501 | 3 | * Rendering plugin based on OpenGL ES 1 | ||
502 | 4 | * | ||
503 | 5 | * Copyright © 2006-2010 Fluendo Embedded S.L. | ||
504 | 6 | * | ||
505 | 7 | * This library is free software; you can redistribute it and/or modify it under | ||
506 | 8 | * the terms of the GNU Lesser General Public License as published by the Free | ||
507 | 9 | * Software Foundation; either version 2 of the License, or (at your option) any | ||
508 | 10 | * later version. This library is distributed in the hope that it will be | ||
509 | 11 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
510 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | ||
511 | 13 | * General Public License for more details. You should have received a copy of | ||
512 | 14 | * the GNU Lesser General Public License along with this library; if not, write | ||
513 | 15 | * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
514 | 16 | * MA 02111-1307, USA. | ||
515 | 17 | * | ||
516 | 18 | * Contributor(s): | ||
517 | 19 | * Loïc Molinari <loic@fluendo.com> | ||
518 | 20 | * Ahmed Ammar <ahmed.ammar@connecmetv.com> | ||
519 | 21 | */ | ||
520 | 22 | |||
521 | 23 | #ifdef HAVE_CONFIG_H | ||
522 | 24 | #include "config.h" | ||
523 | 25 | #endif /* HAVE_CONFIG_H */ | ||
524 | 26 | |||
525 | 27 | #include "backend.h" | ||
526 | 28 | #include <string.h> /* strlen */ | ||
527 | 29 | #include <ctype.h> /* isdigit */ | ||
528 | 30 | #include <stdio.h> | ||
529 | 31 | #include <stdlib.h> | ||
530 | 32 | #include <sys/ioctl.h> | ||
531 | 33 | #include <sys/mman.h> | ||
532 | 34 | #include <fcntl.h> | ||
533 | 35 | |||
534 | 36 | #define GL_GLEXT_PROTOTYPES | ||
535 | 37 | #include <GLES2/gl2.h> | ||
536 | 38 | #include <GLES2/gl2ext.h> | ||
537 | 39 | #undef GL_GLEXT_PROTOTYPES | ||
538 | 40 | |||
539 | 41 | /* Extension constants */ | ||
540 | 42 | enum { | ||
541 | 43 | EXT_BGRA = 0x80e1, | ||
542 | 44 | EXT_MIRRORED_REPEAT = 0x8370 | ||
543 | 45 | }; | ||
544 | 46 | |||
545 | 47 | /* Extension flags */ | ||
546 | 48 | enum { | ||
547 | 49 | FLAG_TEXTURE_FORMAT_BGRA8888 = (1 << 0) , | ||
548 | 50 | FLAG_TEXTURE_STREAM = (1 << 1) | ||
549 | 51 | /* FLAG_BLEND_FUNC_SEPARATE = (1 << 1) */ | ||
550 | 52 | }; | ||
551 | 53 | |||
552 | 54 | /* OpenGL ES 2 attributes */ | ||
553 | 55 | enum { | ||
554 | 56 | PGM_APOSITION = 0, | ||
555 | 57 | PGM_ACOLOR = 1, | ||
556 | 58 | PGM_ATEXCOORD = 2, | ||
557 | 59 | }; | ||
558 | 60 | |||
559 | 61 | /* IMG texture stream structure */ | ||
560 | 62 | typedef struct { | ||
561 | 63 | int number; | ||
562 | 64 | int width; | ||
563 | 65 | int height; | ||
564 | 66 | int format; | ||
565 | 67 | } PluginOpengles2TextureBuffer; | ||
566 | 68 | |||
567 | 69 | /* OpenGL ES 2 vertex shader */ | ||
568 | 70 | static const gchar *default_glslesvp = | ||
569 | 71 | "uniform mat4 pgm_projection;\n" | ||
570 | 72 | "uniform mat4 pgm_modelview;\n" | ||
571 | 73 | "attribute highp vec4 pgm_position;\n" | ||
572 | 74 | "attribute mediump vec4 pgm_color;\n" | ||
573 | 75 | "attribute mediump vec4 pgm_texcoord;\n" | ||
574 | 76 | "varying mediump vec2 frag_texcoord;\n" | ||
575 | 77 | "varying mediump vec4 frag_color;\n" | ||
576 | 78 | "void main() {\n" | ||
577 | 79 | " frag_texcoord = pgm_texcoord.xy;\n" | ||
578 | 80 | " frag_color = pgm_color/255.0;\n" | ||
579 | 81 | " gl_Position = pgm_projection * pgm_modelview * pgm_position;\n" | ||
580 | 82 | "}\n"; | ||
581 | 83 | static const gchar *default_glslesfp = | ||
582 | 84 | "uniform sampler2D pgm_texture0;\n" | ||
583 | 85 | "varying mediump vec2 frag_texcoord;\n" | ||
584 | 86 | "varying mediump vec4 frag_color;\n" | ||
585 | 87 | "void main() {\n" | ||
586 | 88 | " highp vec4 tex0 = texture2D(pgm_texture0, frag_texcoord);\n" | ||
587 | 89 | " gl_FragColor.rgb = frag_color.rgb + tex0.rgb;\n" | ||
588 | 90 | " gl_FragColor.a = frag_color.a * tex0.a;\n" | ||
589 | 91 | "}\n"; | ||
590 | 92 | |||
591 | 93 | /* Wrapper for the opaque PgmPluginTexture pointer */ | ||
592 | 94 | typedef struct { | ||
593 | 95 | GLenum type; | ||
594 | 96 | GLenum format; | ||
595 | 97 | GLuint id; | ||
596 | 98 | gfloat sx; | ||
597 | 99 | gfloat sy; | ||
598 | 100 | guint16 width; | ||
599 | 101 | guint16 height; | ||
600 | 102 | guint16 miplevels; | ||
601 | 103 | } PluginOpengles2Texture; | ||
602 | 104 | |||
603 | 105 | /* Wrapper for the opaque PgmPluginShader type */ | ||
604 | 106 | typedef struct { | ||
605 | 107 | GLuint vert_index, frag_index, prog_index; | ||
606 | 108 | GLint proj_index, modelview_index; | ||
607 | 109 | GLint texture0_index, texture1_index, texture2_index; | ||
608 | 110 | } PluginOpengles2Shader; | ||
609 | 111 | |||
610 | 112 | /* IMG texture stream functions */ | ||
611 | 113 | typedef void (*glGetTexAttrFunc) (GLenum target, GLenum pname, GLint *params); | ||
612 | 114 | typedef void (*glTexBindStreamFunc) (GLint device, GLint deviceoffset); | ||
613 | 115 | typedef const GLubyte *(*glGetTexDeviceFunc) (GLenum target); | ||
614 | 116 | |||
615 | 117 | /* Extension functions */ | ||
616 | 118 | typedef struct { | ||
617 | 119 | /* IMG texture stream functions */ | ||
618 | 120 | glTexBindStreamFunc glTexBindStreamIMG; | ||
619 | 121 | glGetTexAttrFunc glGetTexAttrIMG; | ||
620 | 122 | glGetTexDeviceFunc glGetTexDeviceIMG; | ||
621 | 123 | } Opengles2ExtensionFunctions; | ||
622 | 124 | |||
623 | 125 | /* Wrapper for the opaque PgmPlugin pointer */ | ||
624 | 126 | typedef struct { | ||
625 | 127 | PgmPluginFuncs *funcs; | ||
626 | 128 | PgmRendererCapabilities *caps; | ||
627 | 129 | PluginOpengles2Texture *default_texture; | ||
628 | 130 | PgmRenderer *rdr; | ||
629 | 131 | Backend *backend; | ||
630 | 132 | PluginOpengles2Texture *texture; | ||
631 | 133 | gint32 max_texture_units; | ||
632 | 134 | guint8 extension_flags; | ||
633 | 135 | /* GLES2 shader variables */ | ||
634 | 136 | PluginOpengles2Shader *shader; | ||
635 | 137 | GLfloat *proj_mat, *modelview_mat; | ||
636 | 138 | } PluginOpengles2; | ||
637 | 139 | |||
638 | 140 | /* Texture target look-up table */ | ||
639 | 141 | static const GLenum texture_target[] = { | ||
640 | 142 | GL_TEXTURE_2D, /* PGM_TEXTURE_2D */ | ||
641 | 143 | 0 /* PGM_TEXTURE_CUBE */ /* Not supported */ | ||
642 | 144 | }; | ||
643 | 145 | |||
644 | 146 | /* Texture format look-up table */ | ||
645 | 147 | static const GLenum texture_format[] = { | ||
646 | 148 | GL_LUMINANCE, /* PGM_TEXTURE_L8 */ | ||
647 | 149 | GL_LUMINANCE_ALPHA, /* PGM_TEXTURE_L8A8 */ | ||
648 | 150 | GL_RGB, /* PGM_TEXTURE_R8G8B8 */ | ||
649 | 151 | GL_RGB, /* PGM_TEXTURE_B8G8R8 */ /* Not supported */ | ||
650 | 152 | GL_RGBA, /* PGM_TEXTURE_R8G8B8A8 */ | ||
651 | 153 | GL_RGBA /* PGM_TEXTURE_B8G8R8A8 */ /* Not supported */ | ||
652 | 154 | }; | ||
653 | 155 | |||
654 | 156 | /* Plugin functions */ | ||
655 | 157 | static void | ||
656 | 158 | set_sync_to_vblank (PluginOpengles2 *plugin, | ||
657 | 159 | gboolean sync) | ||
658 | 160 | { | ||
659 | 161 | backend_set_sync_to_vblank (plugin->backend, sync); | ||
660 | 162 | } | ||
661 | 163 | |||
662 | 164 | static void | ||
663 | 165 | wait_for_vblank (PluginOpengles2 *plugin) | ||
664 | 166 | { | ||
665 | 167 | backend_wait_for_vblank (plugin->backend); | ||
666 | 168 | } | ||
667 | 169 | |||
668 | 170 | static void | ||
669 | 171 | clear_buffers (PluginOpengles2 *plugin, | ||
670 | 172 | PgmPluginClearBuffer flags) | ||
671 | 173 | { | ||
672 | 174 | /* Stencil buffer's not used in Pigment, but graphics hardware stores depth | ||
673 | 175 | * and stencil information in the same buffer so for best performance it's | ||
674 | 176 | * recommended that both depth and stencil be cleared together. As a side | ||
675 | 177 | * note, in the old times filling pixels was expensive and avoided as best | ||
676 | 178 | * as possible using convoluted tricks, nowadays this is not true anymore. | ||
677 | 179 | * Modern cards now support buffer compression and fast clearing of buffers | ||
678 | 180 | * using a constant color. More informations can be found in GPU | ||
679 | 181 | * manufacturer's architecture and performance papers. */ | ||
680 | 182 | |||
681 | 183 | /* FIXME: Is that valid for embedded GPUs? */ | ||
682 | 184 | |||
683 | 185 | const GLbitfield mask[] = { | ||
684 | 186 | 0, | ||
685 | 187 | GL_COLOR_BUFFER_BIT, | ||
686 | 188 | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, | ||
687 | 189 | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | ||
688 | 190 | }; | ||
689 | 191 | glClear (mask[flags]); | ||
690 | 192 | } | ||
691 | 193 | |||
692 | 194 | static void | ||
693 | 195 | set_clear_color (PluginOpengles2 *plugin, | ||
694 | 196 | PgmVec4 *color) | ||
695 | 197 | { | ||
696 | 198 | glClearColor (color->v[0], color->v[1], color->v[2], color->v[3]); | ||
697 | 199 | } | ||
698 | 200 | |||
699 | 201 | static void | ||
700 | 202 | set_viewport (PluginOpengles2 *plugin, | ||
701 | 203 | gint32 x, | ||
702 | 204 | gint32 y, | ||
703 | 205 | gint32 width, | ||
704 | 206 | gint32 height) | ||
705 | 207 | { | ||
706 | 208 | glViewport (x, y, width, height); | ||
707 | 209 | } | ||
708 | 210 | |||
709 | 211 | static void | ||
710 | 212 | set_projection_matrix (PluginOpengles2 *plugin, | ||
711 | 213 | PgmMat4x4 *matrix) | ||
712 | 214 | { | ||
713 | 215 | const GLfloat transpose[16] = { | ||
714 | 216 | matrix->m[0], matrix->m[4], matrix->m[8], matrix->m[12], | ||
715 | 217 | matrix->m[1], matrix->m[5], matrix->m[9], matrix->m[13], | ||
716 | 218 | matrix->m[2], matrix->m[6], matrix->m[10], matrix->m[14], | ||
717 | 219 | matrix->m[3], matrix->m[7], matrix->m[11], matrix->m[15] | ||
718 | 220 | }; | ||
719 | 221 | |||
720 | 222 | memcpy(plugin->proj_mat, transpose, 16*sizeof(GLfloat)); | ||
721 | 223 | glUniformMatrix4fv(plugin->shader->proj_index, 1, GL_FALSE, plugin->proj_mat); | ||
722 | 224 | } | ||
723 | 225 | |||
724 | 226 | static void | ||
725 | 227 | set_modelview_matrix (PluginOpengles2 *plugin, | ||
726 | 228 | PgmMat4x4 *matrix) | ||
727 | 229 | { | ||
728 | 230 | const GLfloat transpose[16] = { | ||
729 | 231 | matrix->m[0], matrix->m[4], matrix->m[8], matrix->m[12], | ||
730 | 232 | matrix->m[1], matrix->m[5], matrix->m[9], matrix->m[13], | ||
731 | 233 | matrix->m[2], matrix->m[6], matrix->m[10], matrix->m[14], | ||
732 | 234 | matrix->m[3], matrix->m[7], matrix->m[11], matrix->m[15] | ||
733 | 235 | }; | ||
734 | 236 | |||
735 | 237 | memcpy(plugin->modelview_mat, transpose, 16*sizeof(GLfloat)); | ||
736 | 238 | glUniformMatrix4fv(plugin->shader->modelview_index, 1, GL_FALSE, plugin->modelview_mat); | ||
737 | 239 | } | ||
738 | 240 | |||
739 | 241 | static void | ||
740 | 242 | draw_primitive (PluginOpengles2 *plugin, | ||
741 | 243 | gpointer positions, | ||
742 | 244 | PgmVertexBufferType position_type, | ||
743 | 245 | guint8 position_size, | ||
744 | 246 | gpointer colors, | ||
745 | 247 | PgmVertexBufferType color_type, | ||
746 | 248 | gpointer texcoords, | ||
747 | 249 | PgmVertexBufferType texcoord_type, | ||
748 | 250 | guint8 texcoord_size, | ||
749 | 251 | guint16 *indices, | ||
750 | 252 | PgmMeshPrimitiveType primitive_type, | ||
751 | 253 | guint16 index_count) | ||
752 | 254 | { | ||
753 | 255 | static const GLenum type[] = { | ||
754 | 256 | 0, /* PGM_VERTEX_BUFFER_NONE */ | ||
755 | 257 | GL_BYTE, /* PGM_VERTEX_BUFFER_INT8 */ | ||
756 | 258 | GL_UNSIGNED_BYTE, /* PGM_VERTEX_BUFFER_UINT8 */ | ||
757 | 259 | GL_SHORT, /* PGM_VERTEX_BUFFER_INT16 */ | ||
758 | 260 | GL_UNSIGNED_SHORT, /* PGM_VERTEX_BUFFER_UINT16 */ | ||
759 | 261 | 0, /* PGM_VERTEX_BUFFER_INT32 */ | ||
760 | 262 | 0, /* PGM_VERTEX_BUFFER_UINT32 */ | ||
761 | 263 | GL_FLOAT /* PGM_VERTEX_BUFFER_FLOAT */ | ||
762 | 264 | }; | ||
763 | 265 | static const GLenum mode[] = { | ||
764 | 266 | GL_LINES, /* PGM_MESH_LINE_LIST */ | ||
765 | 267 | GL_LINE_STRIP, /* PGM_MESH_LINE_STRIP */ | ||
766 | 268 | GL_TRIANGLES, /* PGM_MESH_TRIANGLE_LIST */ | ||
767 | 269 | GL_TRIANGLE_STRIP /* PGM_MESH_TRIANGLE_STRIP */ | ||
768 | 270 | }; | ||
769 | 271 | |||
770 | 272 | glVertexAttribPointer(PGM_APOSITION, position_size, type[position_type], GL_FALSE, 0, positions); | ||
771 | 273 | if (texcoord_type == PGM_VERTEX_BUFFER_NONE) { | ||
772 | 274 | glEnableVertexAttribArray(PGM_ACOLOR); | ||
773 | 275 | glVertexAttribPointer(PGM_ACOLOR, 4, type[color_type], GL_FALSE, 0, colors); | ||
774 | 276 | glDrawElements (mode[primitive_type], index_count, GL_UNSIGNED_SHORT, indices); | ||
775 | 277 | glDisableVertexAttribArray(PGM_ACOLOR); | ||
776 | 278 | } else { | ||
777 | 279 | glEnableVertexAttribArray(PGM_ATEXCOORD); | ||
778 | 280 | glVertexAttribPointer(PGM_ATEXCOORD, texcoord_size, type[texcoord_type], GL_FALSE, 0, texcoords); | ||
779 | 281 | glDrawElements (mode[primitive_type], index_count, GL_UNSIGNED_SHORT, indices); | ||
780 | 282 | glDisableVertexAttribArray(PGM_ATEXCOORD); | ||
781 | 283 | } | ||
782 | 284 | } | ||
783 | 285 | |||
784 | 286 | static PgmPluginTexture | ||
785 | 287 | create_texture (PluginOpengles2 *plugin, | ||
786 | 288 | PgmTextureTarget target, | ||
787 | 289 | PgmTextureFormat format, | ||
788 | 290 | guint16 width, | ||
789 | 291 | guint16 height) | ||
790 | 292 | { | ||
791 | 293 | PluginOpengles2Texture *texture = g_slice_new (PluginOpengles2Texture); | ||
792 | 294 | |||
793 | 295 | texture->type = texture_target[target]; | ||
794 | 296 | texture->format = texture_format[format]; | ||
795 | 297 | texture->width = width; | ||
796 | 298 | texture->height = height; | ||
797 | 299 | texture->miplevels = 0; | ||
798 | 300 | |||
799 | 301 | glGenTextures (1, &texture->id); | ||
800 | 302 | |||
801 | 303 | return (PgmPluginTexture) texture; | ||
802 | 304 | } | ||
803 | 305 | |||
804 | 306 | static void | ||
805 | 307 | delete_textures (PluginOpengles2 *plugin, | ||
806 | 308 | PluginOpengles2Texture **textures, | ||
807 | 309 | guint16 count) | ||
808 | 310 | { | ||
809 | 311 | guint32 i; | ||
810 | 312 | |||
811 | 313 | for (i = 0; i < count; i++) | ||
812 | 314 | { | ||
813 | 315 | glDeleteTextures (1, &textures[i]->id); | ||
814 | 316 | g_slice_free (PluginOpengles2Texture, textures[i]); | ||
815 | 317 | } | ||
816 | 318 | } | ||
817 | 319 | |||
818 | 320 | static void | ||
819 | 321 | bind_texture (PluginOpengles2 *plugin, | ||
820 | 322 | guint8 unit, | ||
821 | 323 | PluginOpengles2Texture *texture) | ||
822 | 324 | { | ||
823 | 325 | if (unit < plugin->max_texture_units) | ||
824 | 326 | { | ||
825 | 327 | glActiveTexture (GL_TEXTURE0 + unit); | ||
826 | 328 | if (texture != NULL) | ||
827 | 329 | glBindTexture (texture->type, texture->id); | ||
828 | 330 | else | ||
829 | 331 | glBindTexture (GL_TEXTURE_2D, 0); | ||
830 | 332 | plugin->texture = texture; | ||
831 | 333 | } | ||
832 | 334 | else | ||
833 | 335 | { | ||
834 | 336 | PGM_WARN_OBJECT (plugin->rdr, "texture unit %d not available on " | ||
835 | 337 | "that OpenGL ES 2 implementation", unit); | ||
836 | 338 | } | ||
837 | 339 | } | ||
838 | 340 | |||
839 | 341 | static void | ||
840 | 342 | upload_texture (PluginOpengles2 *plugin, | ||
841 | 343 | guint16 miplevel, | ||
842 | 344 | guint16 x_offset, | ||
843 | 345 | guint16 y_offset, | ||
844 | 346 | guint16 width, | ||
845 | 347 | guint16 height, | ||
846 | 348 | gpointer texels) | ||
847 | 349 | { | ||
848 | 350 | PluginOpengles2Texture *tex = plugin->texture; | ||
849 | 351 | |||
850 | 352 | static int idx = 0; | ||
851 | 353 | if (tex->miplevels & (1 << miplevel)) | ||
852 | 354 | { | ||
853 | 355 | glTexSubImage2D (tex->type, miplevel, x_offset, y_offset, width, | ||
854 | 356 | height, tex->format, GL_UNSIGNED_BYTE, texels); | ||
855 | 357 | } | ||
856 | 358 | else | ||
857 | 359 | { | ||
858 | 360 | glTexImage2D (tex->type, miplevel, tex->format, tex->width, tex->height, | ||
859 | 361 | 0, tex->format, GL_UNSIGNED_BYTE, NULL); | ||
860 | 362 | glTexSubImage2D (tex->type, miplevel, x_offset, y_offset, width, height, | ||
861 | 363 | tex->format, GL_UNSIGNED_BYTE, texels); | ||
862 | 364 | tex->miplevels |= 1 << miplevel; | ||
863 | 365 | } | ||
864 | 366 | } | ||
865 | 367 | |||
866 | 368 | static void | ||
867 | 369 | set_texture_states (PluginOpengles2 *plugin, | ||
868 | 370 | PgmTextureFilter min_filter, | ||
869 | 371 | PgmTextureFilter mag_filter, | ||
870 | 372 | PgmTextureFilter mip_filter, | ||
871 | 373 | PgmTextureWrapping wrap_u, | ||
872 | 374 | PgmTextureWrapping wrap_v) | ||
873 | 375 | { | ||
874 | 376 | static const GLenum map[] = { | ||
875 | 377 | 0, /* PGM_TEXTURE_NONE */ | ||
876 | 378 | GL_NEAREST, /* PGM_TEXTURE_NEAREST */ | ||
877 | 379 | GL_LINEAR, /* PGM_TEXTURE_LINEAR */ | ||
878 | 380 | GL_NEAREST_MIPMAP_NEAREST, | ||
879 | 381 | GL_LINEAR_MIPMAP_NEAREST, | ||
880 | 382 | GL_NEAREST_MIPMAP_LINEAR, | ||
881 | 383 | GL_LINEAR_MIPMAP_LINEAR | ||
882 | 384 | }; | ||
883 | 385 | static const GLenum wrap[] = { | ||
884 | 386 | GL_CLAMP_TO_EDGE, /* PGM_PLUGIN_CLAMP */ | ||
885 | 387 | GL_CLAMP_TO_EDGE, /* PGM_PLUGIN_BORDER */ | ||
886 | 388 | GL_REPEAT, /* PGM_PLUGIN_REPEAT */ | ||
887 | 389 | EXT_MIRRORED_REPEAT /* PGM_PLUGIN_MIRROR */ | ||
888 | 390 | }; | ||
889 | 391 | const GLenum type = plugin->texture->type; | ||
890 | 392 | glTexParameteri (type, GL_TEXTURE_MIN_FILTER, map[min_filter+mip_filter*2]); | ||
891 | 393 | glTexParameteri (type, GL_TEXTURE_MAG_FILTER, map[mag_filter]); | ||
892 | 394 | glTexParameteri (type, GL_TEXTURE_WRAP_S, wrap[wrap_u]); | ||
893 | 395 | glTexParameteri (type, GL_TEXTURE_WRAP_T, wrap[wrap_v]); | ||
894 | 396 | } | ||
895 | 397 | |||
896 | 398 | static PgmPluginShader | ||
897 | 399 | create_shader (PluginOpengles2 *plugin, | ||
898 | 400 | const gchar *language, | ||
899 | 401 | gpointer vertex_program, | ||
900 | 402 | gsize vertex_program_size, | ||
901 | 403 | gpointer geometry_program, | ||
902 | 404 | gsize geometry_program_size, | ||
903 | 405 | gpointer fragment_program, | ||
904 | 406 | gsize fragment_program_size, | ||
905 | 407 | PgmShaderUniformInfo *uniforms_info, | ||
906 | 408 | guint8 uniforms_count) | ||
907 | 409 | { | ||
908 | 410 | PluginOpengles2Shader *shader; | ||
909 | 411 | gint error_position = 0; | ||
910 | 412 | GLint success; | ||
911 | 413 | |||
912 | 414 | /* XXX Check language validity */ | ||
913 | 415 | |||
914 | 416 | shader = g_slice_new (PluginOpengles2Shader); | ||
915 | 417 | |||
916 | 418 | shader->prog_index = glCreateProgram(); | ||
917 | 419 | |||
918 | 420 | if ((vertex_program != NULL) || (fragment_program != NULL)) | ||
919 | 421 | { | ||
920 | 422 | if (vertex_program != NULL) | ||
921 | 423 | { | ||
922 | 424 | PGM_INFO_OBJECT(plugin->rdr, "%s: creating new vertex shader\n", __func__); | ||
923 | 425 | shader->vert_index = glCreateShader(GL_VERTEX_SHADER); | ||
924 | 426 | glShaderSource(shader->vert_index, 1, (const char**) &vertex_program, (GLint *) &vertex_program_size); | ||
925 | 427 | glCompileShader(shader->vert_index); | ||
926 | 428 | glGetShaderiv(shader->vert_index, GL_COMPILE_STATUS, &success); | ||
927 | 429 | if (!success) PGM_WARN_OBJECT (plugin->rdr, "%s: vertex shader compilation error\n", __func__); | ||
928 | 430 | else glAttachShader(shader->prog_index, shader->vert_index); | ||
929 | 431 | } | ||
930 | 432 | |||
931 | 433 | if (fragment_program != NULL) | ||
932 | 434 | { | ||
933 | 435 | PGM_INFO_OBJECT(plugin->rdr, "%s: creating new fragment shader\n", __func__); | ||
934 | 436 | shader->frag_index = glCreateShader(GL_FRAGMENT_SHADER); | ||
935 | 437 | glShaderSource(shader->frag_index, 1, (const char**) &fragment_program, (GLint *) &fragment_program_size); | ||
936 | 438 | glCompileShader(shader->frag_index); | ||
937 | 439 | glGetShaderiv(shader->frag_index, GL_COMPILE_STATUS, &success); | ||
938 | 440 | if (!success) PGM_WARN_OBJECT (plugin->rdr, "%s: fragment shader compilation error\n", __func__); | ||
939 | 441 | else glAttachShader(shader->prog_index, shader->frag_index); | ||
940 | 442 | } | ||
941 | 443 | |||
942 | 444 | /* Bind attributes */ | ||
943 | 445 | glBindAttribLocation(shader->prog_index, PGM_APOSITION, "pgm_position"); | ||
944 | 446 | glBindAttribLocation(shader->prog_index, PGM_ACOLOR, "pgm_color"); | ||
945 | 447 | glBindAttribLocation(shader->prog_index, PGM_ATEXCOORD, "pgm_texcoord"); | ||
946 | 448 | |||
947 | 449 | glLinkProgram(shader->prog_index); | ||
948 | 450 | glGetProgramiv(shader->prog_index, GL_LINK_STATUS, &success); | ||
949 | 451 | if (success) | ||
950 | 452 | { | ||
951 | 453 | glUseProgram(shader->prog_index); | ||
952 | 454 | /* Get uniform locations */ | ||
953 | 455 | shader->proj_index = glGetUniformLocation(shader->prog_index, "pgm_projection"); | ||
954 | 456 | shader->modelview_index = glGetUniformLocation(shader->prog_index, "pgm_modelview"); | ||
955 | 457 | |||
956 | 458 | shader->texture0_index = glGetUniformLocation(shader->prog_index,"pgm_texture0"); | ||
957 | 459 | glUniform1i(shader->texture0_index, 0); | ||
958 | 460 | shader->texture1_index = glGetUniformLocation(shader->prog_index,"pgm_texture1"); | ||
959 | 461 | glUniform1i(shader->texture1_index, 1); | ||
960 | 462 | shader->texture2_index = glGetUniformLocation(shader->prog_index,"pgm_texture2"); | ||
961 | 463 | glUniform1i(shader->texture2_index, 2); | ||
962 | 464 | } | ||
963 | 465 | else | ||
964 | 466 | PGM_WARN_OBJECT (plugin->rdr, "program linking error\n"); | ||
965 | 467 | } | ||
966 | 468 | return (PgmPluginShader) shader; | ||
967 | 469 | } | ||
968 | 470 | |||
969 | 471 | static void | ||
970 | 472 | delete_shaders (PluginOpengles2 *plugin, | ||
971 | 473 | PluginOpengles2Shader *shaders, | ||
972 | 474 | guint16 count) | ||
973 | 475 | { | ||
974 | 476 | guint32 i; | ||
975 | 477 | for (i = 0; i < count; i++) | ||
976 | 478 | { | ||
977 | 479 | glDetachShader(shaders[i].prog_index, shaders[i].vert_index); | ||
978 | 480 | glDetachShader(shaders[i].prog_index, shaders[i].frag_index); | ||
979 | 481 | glDeleteProgram(shaders[i].prog_index); | ||
980 | 482 | g_slice_free (PluginOpengles2Shader, &(shaders[i])); | ||
981 | 483 | } | ||
982 | 484 | |||
983 | 485 | } | ||
984 | 486 | |||
985 | 487 | static void | ||
986 | 488 | bind_shader (PluginOpengles2 *plugin, | ||
987 | 489 | PluginOpengles2Shader *shader) | ||
988 | 490 | { | ||
989 | 491 | GLint success; | ||
990 | 492 | |||
991 | 493 | if (shader != NULL) { | ||
992 | 494 | glUseProgram(shader->prog_index); | ||
993 | 495 | glUniformMatrix4fv(plugin->shader->proj_index, 1, GL_FALSE, plugin->proj_mat); | ||
994 | 496 | glUniformMatrix4fv(plugin->shader->modelview_index, 1, GL_FALSE, plugin->modelview_mat); | ||
995 | 497 | } | ||
996 | 498 | plugin->shader = shader; | ||
997 | 499 | } | ||
998 | 500 | |||
999 | 501 | static void | ||
1000 | 502 | set_shader_uniforms (PluginOpengles2 *plugin, | ||
1001 | 503 | PgmShaderUniformData *uniforms) | ||
1002 | 504 | { | ||
1003 | 505 | /* Not used, we have some predefined uniforms, have a look at the default shaders */ | ||
1004 | 506 | PGM_INFO_OBJECT(plugin->rdr, "%s: set shader uniforms\n", __func__); | ||
1005 | 507 | } | ||
1006 | 508 | |||
1007 | 509 | static void | ||
1008 | 510 | swap_buffers (PluginOpengles2 *plugin) | ||
1009 | 511 | { | ||
1010 | 512 | backend_swap_buffers (plugin->backend); | ||
1011 | 513 | } | ||
1012 | 514 | |||
1013 | 515 | static void | ||
1014 | 516 | get_screen_size (PluginOpengles2 *plugin, | ||
1015 | 517 | guint32 *width, | ||
1016 | 518 | guint32 *height) | ||
1017 | 519 | { | ||
1018 | 520 | backend_get_screen_size (plugin->backend, width, height); | ||
1019 | 521 | } | ||
1020 | 522 | |||
1021 | 523 | static void | ||
1022 | 524 | get_screen_resolution (PluginOpengles2 *plugin, | ||
1023 | 525 | guint32 *width, | ||
1024 | 526 | guint32 *height) | ||
1025 | 527 | { | ||
1026 | 528 | backend_get_screen_resolution (plugin->backend, width, height); | ||
1027 | 529 | } | ||
1028 | 530 | |||
1029 | 531 | static void | ||
1030 | 532 | set_window_title (PluginOpengles2 *plugin, | ||
1031 | 533 | const gchar *title) | ||
1032 | 534 | { | ||
1033 | 535 | backend_set_window_title (plugin->backend, title); | ||
1034 | 536 | } | ||
1035 | 537 | |||
1036 | 538 | static void | ||
1037 | 539 | set_window_visible (PluginOpengles2 *plugin, | ||
1038 | 540 | gboolean visible) | ||
1039 | 541 | { | ||
1040 | 542 | backend_set_window_visible (plugin->backend, visible); | ||
1041 | 543 | } | ||
1042 | 544 | |||
1043 | 545 | static void | ||
1044 | 546 | set_window_decorated (PluginOpengles2 *plugin, | ||
1045 | 547 | gboolean decorated) | ||
1046 | 548 | { | ||
1047 | 549 | backend_set_window_decorated (plugin->backend, decorated); | ||
1048 | 550 | } | ||
1049 | 551 | |||
1050 | 552 | static void | ||
1051 | 553 | set_window_fullscreen (PluginOpengles2 *plugin, | ||
1052 | 554 | gboolean fullscreen) | ||
1053 | 555 | { | ||
1054 | 556 | backend_set_window_fullscreen (plugin->backend, fullscreen); | ||
1055 | 557 | } | ||
1056 | 558 | |||
1057 | 559 | static void | ||
1058 | 560 | set_window_iconified (PluginOpengles2 *plugin, | ||
1059 | 561 | gboolean iconified) | ||
1060 | 562 | { | ||
1061 | 563 | backend_set_window_iconified (plugin->backend, iconified); | ||
1062 | 564 | } | ||
1063 | 565 | |||
1064 | 566 | static void | ||
1065 | 567 | set_window_cursor (PluginOpengles2 *plugin, | ||
1066 | 568 | PgmRendererCursor cursor) | ||
1067 | 569 | { | ||
1068 | 570 | backend_set_window_cursor (plugin->backend, cursor); | ||
1069 | 571 | } | ||
1070 | 572 | |||
1071 | 573 | /* static void */ | ||
1072 | 574 | /* set_window_icon (PluginOpengles2 *plugin, */ | ||
1073 | 575 | /* GdkPixbuf *icon) */ | ||
1074 | 576 | /* { */ | ||
1075 | 577 | /* backend_set_window_icon (plugin->backend, icon); */ | ||
1076 | 578 | /* } */ | ||
1077 | 579 | |||
1078 | 580 | static void | ||
1079 | 581 | set_window_size (PluginOpengles2 *plugin, | ||
1080 | 582 | guint32 width, | ||
1081 | 583 | guint32 height) | ||
1082 | 584 | { | ||
1083 | 585 | backend_set_window_size (plugin->backend, width, height); | ||
1084 | 586 | } | ||
1085 | 587 | |||
1086 | 588 | static void | ||
1087 | 589 | set_window_message_filter (PluginOpengles2 *plugin, | ||
1088 | 590 | GList *filter) | ||
1089 | 591 | { | ||
1090 | 592 | backend_set_window_message_filter (plugin->backend, filter); | ||
1091 | 593 | } | ||
1092 | 594 | |||
1093 | 595 | static void | ||
1094 | 596 | window_focus (PluginOpengles2 *plugin) | ||
1095 | 597 | { | ||
1096 | 598 | backend_window_focus (plugin->backend); | ||
1097 | 599 | } | ||
1098 | 600 | |||
1099 | 601 | static guint32 | ||
1100 | 602 | get_window_id (PluginOpengles2 *plugin) | ||
1101 | 603 | { | ||
1102 | 604 | return backend_get_window_id (plugin->backend); | ||
1103 | 605 | } | ||
1104 | 606 | |||
1105 | 607 | static void | ||
1106 | 608 | set_window_drag_status (PluginOpengles2 *plugin, | ||
1107 | 609 | gboolean accept) | ||
1108 | 610 | { | ||
1109 | 611 | backend_set_window_drag_status (plugin->backend, accept); | ||
1110 | 612 | } | ||
1111 | 613 | |||
1112 | 614 | /* Plugin */ | ||
1113 | 615 | |||
1114 | 616 | static gboolean | ||
1115 | 617 | is_extension_supported (const gchar *extensions, | ||
1116 | 618 | const gchar *extension) | ||
1117 | 619 | { | ||
1118 | 620 | if (extensions != NULL && extension != NULL) | ||
1119 | 621 | { | ||
1120 | 622 | const gsize len = strlen (extension); | ||
1121 | 623 | gchar *p = (gchar*) extensions; | ||
1122 | 624 | gchar *end = p + strlen (p); | ||
1123 | 625 | |||
1124 | 626 | while (p < end) | ||
1125 | 627 | { | ||
1126 | 628 | const gsize size = strcspn (p, " "); | ||
1127 | 629 | if (len == size && strncmp (extension, p, size) == 0) | ||
1128 | 630 | return TRUE; | ||
1129 | 631 | p += size + 1; | ||
1130 | 632 | } | ||
1131 | 633 | } | ||
1132 | 634 | |||
1133 | 635 | return FALSE; | ||
1134 | 636 | } | ||
1135 | 637 | |||
1136 | 638 | static gboolean | ||
1137 | 639 | init_plugin (PluginOpengles2 *plugin, | ||
1138 | 640 | guint32 options) | ||
1139 | 641 | { | ||
1140 | 642 | const struct { | ||
1141 | 643 | const gchar *name; guint8 flag; | ||
1142 | 644 | } extension_map[] = { | ||
1143 | 645 | { "GL_IMG_texture_format_BGRA8888", FLAG_TEXTURE_FORMAT_BGRA8888 }, | ||
1144 | 646 | { NULL, 0 } | ||
1145 | 647 | }; | ||
1146 | 648 | const gchar *vendor, *renderer, *version, *extensions; | ||
1147 | 649 | PluginOpengles2Texture *texture; | ||
1148 | 650 | PgmRendererCapabilities *caps; | ||
1149 | 651 | PgmPluginFuncs *funcs; | ||
1150 | 652 | guint8 extension_flags = 0; | ||
1151 | 653 | guint8 caps_flags = 0; | ||
1152 | 654 | guint32 i; | ||
1153 | 655 | |||
1154 | 656 | |||
1155 | 657 | /* Get the information strings */ | ||
1156 | 658 | version = (const gchar*) glGetString (GL_VERSION); | ||
1157 | 659 | vendor = (const gchar*) glGetString (GL_VENDOR); | ||
1158 | 660 | renderer = (const gchar*) glGetString (GL_RENDERER); | ||
1159 | 661 | extensions = (const gchar*) glGetString (GL_EXTENSIONS); | ||
1160 | 662 | PGM_INFO_OBJECT (plugin->rdr, "OpenGL ES vendor: %s", vendor); | ||
1161 | 663 | PGM_INFO_OBJECT (plugin->rdr, "OpenGL ES renderer: %s", renderer); | ||
1162 | 664 | PGM_INFO_OBJECT (plugin->rdr, "OpenGL ES version: %s", version); | ||
1163 | 665 | PGM_DEBUG_OBJECT (plugin->rdr, "OpenGL ES extensions: %s", extensions); | ||
1164 | 666 | |||
1165 | 667 | /* Store the supported extensions in a bitfield */ | ||
1166 | 668 | for (i = 0; extension_map[i].name != NULL; i++) | ||
1167 | 669 | if (is_extension_supported (extensions, extension_map[i].name) == TRUE) | ||
1168 | 670 | extension_flags |= extension_map[i].flag; | ||
1169 | 671 | plugin->extension_flags = extension_flags; | ||
1170 | 672 | |||
1171 | 673 | /* Set initial states */ | ||
1172 | 674 | /* XXX: Some of these must be set from the core with dedicated functions */ | ||
1173 | 675 | glEnableVertexAttribArray(PGM_APOSITION); | ||
1174 | 676 | glEnable (GL_BLEND); | ||
1175 | 677 | glDepthFunc (GL_LEQUAL); | ||
1176 | 678 | glEnable (GL_DEPTH_TEST); | ||
1177 | 679 | |||
1178 | 680 | glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); | ||
1179 | 681 | glEnable (GL_TEXTURE_2D); | ||
1180 | 682 | |||
1181 | 683 | /* Fill the default texture */ | ||
1182 | 684 | texture = g_slice_alloc (sizeof (PluginOpengles2Texture)); | ||
1183 | 685 | texture->type = GL_TEXTURE_2D; | ||
1184 | 686 | texture->id = 0; | ||
1185 | 687 | plugin->default_texture = texture; | ||
1186 | 688 | |||
1187 | 689 | /* Allocate memory for modelview/projection matrices */ | ||
1188 | 690 | plugin->proj_mat = (GLfloat*) malloc (16*sizeof(GLfloat)); | ||
1189 | 691 | plugin->modelview_mat = (GLfloat*) malloc (16*sizeof(GLfloat)); | ||
1190 | 692 | |||
1191 | 693 | /* Fill the caps */ | ||
1192 | 694 | caps = pgm_renderer_capabilities_new (); | ||
1193 | 695 | caps->device_vendor = g_strdup (vendor); | ||
1194 | 696 | caps->device_description = g_strconcat (renderer, " (", version, ")", NULL); | ||
1195 | 697 | if (backend_is_window_pluggable (plugin->backend)) | ||
1196 | 698 | caps_flags |= PGM_RENDERER_PLUGGABLE_WINDOW; | ||
1197 | 699 | if (backend_is_window_layered (plugin->backend)) | ||
1198 | 700 | caps_flags |= PGM_RENDERER_LAYERED_WINDOW; | ||
1199 | 701 | caps->flags = caps_flags; | ||
1200 | 702 | |||
1201 | 703 | /* Store supported shading languages */ | ||
1202 | 704 | caps->shading_languages = g_list_prepend | ||
1203 | 705 | (NULL, pgm_renderer_shading_language_new ("glsles", "1.0", PGM_RENDERER_FRAGMENT_PROGRAM | PGM_RENDERER_VERTEX_PROGRAM )); | ||
1204 | 706 | |||
1205 | 707 | /* Store limits */ | ||
1206 | 708 | glGetIntegerv (GL_MAX_TEXTURE_SIZE, &caps->max_texture_size); | ||
1207 | 709 | plugin->max_texture_units = caps->max_texture_units = 3; | ||
1208 | 710 | caps->max_lights = 0; | ||
1209 | 711 | plugin->caps = caps; | ||
1210 | 712 | |||
1211 | 713 | /* Fill the funcs */ | ||
1212 | 714 | funcs = g_slice_alloc (sizeof (PgmPluginFuncs)); | ||
1213 | 715 | funcs->set_sync_to_vblank = | ||
1214 | 716 | (PgmPluginSetSyncToVBlankFunc) set_sync_to_vblank; | ||
1215 | 717 | funcs->wait_for_vblank = (PgmPluginWaitForVBlankFunc) wait_for_vblank; | ||
1216 | 718 | funcs->clear_buffers = (PgmPluginClearBuffersFunc) clear_buffers; | ||
1217 | 719 | funcs->set_clear_color = (PgmPluginSetClearColorFunc) set_clear_color; | ||
1218 | 720 | funcs->set_viewport = (PgmPluginSetViewportFunc) set_viewport; | ||
1219 | 721 | funcs->set_projection_matrix = | ||
1220 | 722 | (PgmPluginSetProjectionMatrixFunc) set_projection_matrix; | ||
1221 | 723 | funcs->set_modelview_matrix = | ||
1222 | 724 | (PgmPluginSetModelviewMatrixFunc) set_modelview_matrix; | ||
1223 | 725 | funcs->draw_primitive = (PgmPluginDrawPrimitiveFunc) draw_primitive; | ||
1224 | 726 | funcs->create_texture = (PgmPluginCreateTextureFunc) create_texture; | ||
1225 | 727 | funcs->delete_textures = (PgmPluginDeleteTexturesFunc) delete_textures; | ||
1226 | 728 | funcs->bind_texture = (PgmPluginBindTextureFunc) bind_texture; | ||
1227 | 729 | funcs->upload_texture = (PgmPluginUploadTextureFunc) upload_texture; | ||
1228 | 730 | funcs->set_texture_states = | ||
1229 | 731 | (PgmPluginSetTextureStatesFunc) set_texture_states; | ||
1230 | 732 | funcs->create_shader = (PgmPluginCreateShaderFunc) create_shader; | ||
1231 | 733 | funcs->delete_shaders = (PgmPluginDeleteShadersFunc) delete_shaders; | ||
1232 | 734 | funcs->bind_shader = (PgmPluginBindShaderFunc) bind_shader; | ||
1233 | 735 | funcs->set_shader_uniforms = | ||
1234 | 736 | (PgmPluginSetShaderUniformsFunc) set_shader_uniforms; | ||
1235 | 737 | funcs->swap_buffers = (PgmPluginSwapBuffersFunc) swap_buffers; | ||
1236 | 738 | funcs->get_screen_size = (PgmPluginGetScreenSizeFunc) get_screen_size; | ||
1237 | 739 | funcs->get_screen_resolution = | ||
1238 | 740 | (PgmPluginGetScreenResolutionFunc) get_screen_resolution; | ||
1239 | 741 | funcs->read_pixels = NULL; | ||
1240 | 742 | funcs->set_window_title = (PgmPluginSetWindowTitleFunc) set_window_title; | ||
1241 | 743 | funcs->set_window_visible = | ||
1242 | 744 | (PgmPluginSetWindowVisibleFunc) set_window_visible; | ||
1243 | 745 | funcs->set_window_decorated = | ||
1244 | 746 | (PgmPluginSetWindowDecoratedFunc) set_window_decorated; | ||
1245 | 747 | funcs->set_window_fullscreen = | ||
1246 | 748 | (PgmPluginSetWindowFullscreenFunc) set_window_fullscreen; | ||
1247 | 749 | funcs->set_window_iconified = | ||
1248 | 750 | (PgmPluginSetWindowIconifiedFunc) set_window_iconified; | ||
1249 | 751 | funcs->set_window_cursor = | ||
1250 | 752 | (PgmPluginSetWindowCursorFunc) set_window_cursor; | ||
1251 | 753 | /* funcs->set_window_icon = (PgmPluginSetWindowIconFunc) set_window_icon; */ | ||
1252 | 754 | funcs->set_window_size = (PgmPluginSetWindowSizeFunc) set_window_size; | ||
1253 | 755 | funcs->set_window_message_filter = | ||
1254 | 756 | (PgmPluginSetWindowMessageFilterFunc) set_window_message_filter; | ||
1255 | 757 | funcs->window_focus = (PgmPluginWindowFocusFunc) window_focus; | ||
1256 | 758 | funcs->get_window_id = (PgmPluginGetWindowIdFunc) get_window_id; | ||
1257 | 759 | funcs->set_window_drag_status = | ||
1258 | 760 | (PgmPluginSetWindowDragStatusFunc) set_window_drag_status; | ||
1259 | 761 | plugin->funcs = funcs; | ||
1260 | 762 | |||
1261 | 763 | return TRUE; | ||
1262 | 764 | } | ||
1263 | 765 | |||
1264 | 766 | static PgmPlugin | ||
1265 | 767 | construct (PgmRenderer *renderer, | ||
1266 | 768 | GMainContext *context, | ||
1267 | 769 | guint32 options, | ||
1268 | 770 | PgmPluginFuncs **funcs, | ||
1269 | 771 | PgmRendererCapabilities **caps, | ||
1270 | 772 | PgmPluginTexture *texture, | ||
1271 | 773 | PgmPluginShader *shader) | ||
1272 | 774 | { | ||
1273 | 775 | PluginOpengles2 *plugin = g_slice_alloc0 (sizeof (PluginOpengles2)); | ||
1274 | 776 | Backend backend = backend_new (renderer, context, options); | ||
1275 | 777 | |||
1276 | 778 | if (backend != NULL) | ||
1277 | 779 | { | ||
1278 | 780 | plugin->rdr = renderer; | ||
1279 | 781 | plugin->backend = backend; | ||
1280 | 782 | |||
1281 | 783 | plugin->shader = (PluginOpengles2Shader*) create_shader(plugin, "glsles", (gpointer)default_glslesvp, | ||
1282 | 784 | strlen(default_glslesvp), NULL, 0, | ||
1283 | 785 | (gpointer) default_glslesfp, | ||
1284 | 786 | strlen(default_glslesfp), NULL, 0); | ||
1285 | 787 | |||
1286 | 788 | if (init_plugin (plugin, options) == TRUE) | ||
1287 | 789 | { | ||
1288 | 790 | *funcs = plugin->funcs; | ||
1289 | 791 | *caps = plugin->caps; | ||
1290 | 792 | *texture = plugin->default_texture; | ||
1291 | 793 | *shader = plugin->shader; | ||
1292 | 794 | return (PgmPlugin) plugin; | ||
1293 | 795 | } | ||
1294 | 796 | else | ||
1295 | 797 | { | ||
1296 | 798 | backend_free (backend); | ||
1297 | 799 | g_slice_free1 (sizeof (PluginOpengles2), plugin); | ||
1298 | 800 | PGM_ERROR_OBJECT (renderer, "can't initialize OpenGL ES plugin"); | ||
1299 | 801 | return NULL; | ||
1300 | 802 | } | ||
1301 | 803 | } | ||
1302 | 804 | else | ||
1303 | 805 | { | ||
1304 | 806 | PGM_ERROR_OBJECT (renderer, "can't create OpenGL ES context"); | ||
1305 | 807 | return NULL; | ||
1306 | 808 | } | ||
1307 | 809 | } | ||
1308 | 810 | |||
1309 | 811 | static void | ||
1310 | 812 | destruct (PluginOpengles2 *plugin) | ||
1311 | 813 | { | ||
1312 | 814 | /* XXX destruct shaders? */ | ||
1313 | 815 | g_slice_free1 (sizeof (PgmPluginFuncs), plugin->funcs); | ||
1314 | 816 | g_slice_free1 (sizeof (PluginOpengles2Texture), plugin->default_texture); | ||
1315 | 817 | pgm_renderer_capabilities_free (plugin->caps); | ||
1316 | 818 | backend_free (plugin->backend); | ||
1317 | 819 | g_slice_free1 (sizeof (PluginOpengles2), plugin); | ||
1318 | 820 | } | ||
1319 | 821 | |||
1320 | 822 | #if defined (HAVE_EGL2_NATIVE) | ||
1321 | 823 | #define description "a plugin based on OpenGL ES 2 (native)" | ||
1322 | 824 | #elif defined (HAVE_EGL2_X11) | ||
1323 | 825 | #define description "a plugin based on OpenGL ES 2 (X11)" | ||
1324 | 826 | #endif | ||
1325 | 827 | |||
1326 | 828 | PGM_PLUGIN_DEFINE ( | ||
1327 | 829 | "opengles2", /* Name */ | ||
1328 | 830 | VERSION, /* Version */ | ||
1329 | 831 | description, /* Description */ | ||
1330 | 832 | "LGPL", /* License */ | ||
1331 | 833 | "https://code.fluendo.com/pigment", /* Origin */ | ||
1332 | 834 | "Ahmed Ammar <ahmed.ammar@connectmetv.com>", /* Author */ | ||
1333 | 835 | (PgmPluginConstructFunc) construct, /* Constructor */ | ||
1334 | 836 | (PgmPluginDestructFunc) destruct, /* Destructor */ | ||
1335 | 837 | PGM_PLUGIN_SECONDARY /* Rank */ | ||
1336 | 838 | ) | ||
1337 | 0 | 839 | ||
1338 | === modified file 'tests/manual/test-geometry-sorting.c' | |||
1339 | --- tests/manual/test-geometry-sorting.c 2010-05-07 16:58:25 +0000 | |||
1340 | +++ tests/manual/test-geometry-sorting.c 2010-05-19 17:34:31 +0000 | |||
1341 | @@ -447,7 +447,7 @@ | |||
1342 | 447 | pgm_init (&argc, &argv); | 447 | pgm_init (&argc, &argv); |
1343 | 448 | 448 | ||
1344 | 449 | /* OpenGL renderer creation */ | 449 | /* OpenGL renderer creation */ |
1346 | 450 | renderer = pgm_renderer_factory_make ("opengl", 1); | 450 | renderer = pgm_renderer_factory_make_auto (); |
1347 | 451 | if (!renderer) | 451 | if (!renderer) |
1348 | 452 | { | 452 | { |
1349 | 453 | g_print ("Cannot create a renderer\n"); | 453 | g_print ("Cannot create a renderer\n"); |
1350 | 454 | 454 | ||
1351 | === modified file 'tests/manual/test-gst-image.c' | |||
1352 | --- tests/manual/test-gst-image.c 2010-05-07 16:46:26 +0000 | |||
1353 | +++ tests/manual/test-gst-image.c 2010-05-19 17:34:31 +0000 | |||
1354 | @@ -78,7 +78,7 @@ | |||
1355 | 78 | pgm_init (&argc, &argv); | 78 | pgm_init (&argc, &argv); |
1356 | 79 | gst_init (&argc, &argv); | 79 | gst_init (&argc, &argv); |
1357 | 80 | 80 | ||
1359 | 81 | renderer = pgm_renderer_factory_make ("opengl", 0); | 81 | renderer = pgm_renderer_factory_make_auto (); |
1360 | 82 | if (!renderer) | 82 | if (!renderer) |
1361 | 83 | { | 83 | { |
1362 | 84 | g_print ("Cannot create the OpenGL renderer\n"); | 84 | g_print ("Cannot create the OpenGL renderer\n"); |