From 223e14811c101e8c5821ffb21c0b7978bd8f9c24 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 5 May 2011 20:56:44 +0100 Subject: [PATCH] Removes Cogl from the repository Cogl has now been split out into a standalone project with a separate repository at git://git.gnome.org/cogl. From now on the Clutter build will now simply look for a cogl-1.0 pkg-config file to find a suitable Cogl library to link against at build time. --- .gitignore | 46 - README.in | 35 +- clutter/Makefile.am | 75 +- clutter/clutter-main.c | 5 - clutter/clutter-private.h | 4 - clutter/cogl/Makefile.am | 7 - clutter/cogl/autogen.sh | 73 - clutter/cogl/build/autotools/Makefile.am.enums | 51 - clutter/cogl/build/autotools/Makefile.am.silent | 19 - clutter/cogl/build/autotools/as-compiler-flag.m4 | 62 - clutter/cogl/build/autotools/as-linguas.m4 | 24 - clutter/cogl/build/autotools/introspection.m4 | 94 - clutter/cogl/cogl/Makefile.am | 419 -- clutter/cogl/cogl/cogl-1.0-clutter.pc.in | 17 - clutter/cogl/cogl/cogl-1.0.pc.in | 13 - clutter/cogl/cogl/cogl-atlas-texture-private.h | 80 - clutter/cogl/cogl/cogl-atlas-texture.c | 806 --- clutter/cogl/cogl/cogl-atlas.c | 589 -- clutter/cogl/cogl/cogl-atlas.h | 97 - clutter/cogl/cogl/cogl-attribute-private.h | 103 - clutter/cogl/cogl/cogl-attribute.c | 1280 ---- clutter/cogl/cogl/cogl-attribute.h | 182 - clutter/cogl/cogl/cogl-bitmap-fallback.c | 582 -- clutter/cogl/cogl/cogl-bitmap-pixbuf.c | 331 - clutter/cogl/cogl/cogl-bitmap-private.h | 214 - clutter/cogl/cogl/cogl-bitmap.c | 498 -- clutter/cogl/cogl/cogl-bitmap.h | 131 - clutter/cogl/cogl/cogl-bitmask.c | 257 - clutter/cogl/cogl/cogl-bitmask.h | 227 - clutter/cogl/cogl/cogl-blend-string.c | 984 --- clutter/cogl/cogl/cogl-blend-string.h | 137 - clutter/cogl/cogl/cogl-blit.c | 395 -- clutter/cogl/cogl/cogl-blit.h | 89 - clutter/cogl/cogl/cogl-buffer-private.h | 163 - clutter/cogl/cogl/cogl-buffer.c | 556 -- clutter/cogl/cogl/cogl-buffer.h | 242 - clutter/cogl/cogl/cogl-clip-stack.c | 748 --- clutter/cogl/cogl/cogl-clip-stack.h | 192 - clutter/cogl/cogl/cogl-clip-state-private.h | 53 - clutter/cogl/cogl/cogl-clip-state.c | 255 - clutter/cogl/cogl/cogl-clip-state.h | 50 - clutter/cogl/cogl/cogl-clutter.c | 79 - clutter/cogl/cogl/cogl-clutter.h | 57 - clutter/cogl/cogl/cogl-color-private.h | 45 - clutter/cogl/cogl/cogl-color.c | 313 - clutter/cogl/cogl/cogl-color.h | 544 -- clutter/cogl/cogl/cogl-context-private.h | 282 - clutter/cogl/cogl/cogl-context.c | 501 -- clutter/cogl/cogl/cogl-context.h | 84 - clutter/cogl/cogl/cogl-debug-options.h | 187 - clutter/cogl/cogl/cogl-debug.c | 248 - clutter/cogl/cogl/cogl-debug.h | 121 - clutter/cogl/cogl/cogl-defines.h.in | 36 - clutter/cogl/cogl/cogl-deprecated.h | 36 - clutter/cogl/cogl/cogl-display-glx-private.h | 57 - clutter/cogl/cogl/cogl-display-private.h | 48 - clutter/cogl/cogl/cogl-display-xlib-private.h | 35 - clutter/cogl/cogl/cogl-display.c | 135 - clutter/cogl/cogl/cogl-display.h | 100 - clutter/cogl/cogl/cogl-enum-types.c.in | 41 - clutter/cogl/cogl/cogl-enum-types.h.in | 25 - clutter/cogl/cogl/cogl-feature-private.c | 144 - clutter/cogl/cogl/cogl-feature-private.h | 81 - clutter/cogl/cogl/cogl-fixed.c | 950 --- clutter/cogl/cogl/cogl-fixed.h | 804 --- clutter/cogl/cogl/cogl-flags.h | 89 - clutter/cogl/cogl/cogl-framebuffer-private.h | 358 - clutter/cogl/cogl/cogl-framebuffer.c | 1731 ----- clutter/cogl/cogl/cogl-framebuffer.h | 226 - clutter/cogl/cogl/cogl-gtype-private.h | 48 - clutter/cogl/cogl/cogl-handle.h | 35 - clutter/cogl/cogl/cogl-index-array-private.h | 39 - clutter/cogl/cogl/cogl-index-array.c | 131 - clutter/cogl/cogl/cogl-index-array.h | 79 - clutter/cogl/cogl/cogl-indices-private.h | 54 - clutter/cogl/cogl/cogl-indices.c | 253 - clutter/cogl/cogl/cogl-indices.h | 77 - clutter/cogl/cogl/cogl-internal.h | 135 - clutter/cogl/cogl/cogl-journal-private.h | 93 - clutter/cogl/cogl/cogl-journal.c | 1805 ------ clutter/cogl/cogl/cogl-material-compat.c | 495 -- clutter/cogl/cogl/cogl-material-compat.h | 1397 ---- clutter/cogl/cogl/cogl-matrix-mesa.c | 1700 ----- clutter/cogl/cogl/cogl-matrix-mesa.h | 226 - clutter/cogl/cogl/cogl-matrix-private.h | 47 - clutter/cogl/cogl/cogl-matrix-stack.c | 550 -- clutter/cogl/cogl/cogl-matrix-stack.h | 130 - clutter/cogl/cogl/cogl-matrix.c | 673 -- clutter/cogl/cogl/cogl-matrix.h | 589 -- clutter/cogl/cogl/cogl-object-private.h | 276 - clutter/cogl/cogl/cogl-object.c | 249 - clutter/cogl/cogl/cogl-object.h | 127 - clutter/cogl/cogl/cogl-offscreen.h | 105 - clutter/cogl/cogl/cogl-onscreen-template-private.h | 37 - clutter/cogl/cogl/cogl-onscreen-template.c | 62 - clutter/cogl/cogl/cogl-onscreen-template.h | 48 - clutter/cogl/cogl/cogl-path-private.h | 115 - clutter/cogl/cogl/cogl-path.c | 303 - clutter/cogl/cogl/cogl-path.h | 491 -- .../cogl/cogl-pipeline-fragend-arbfp-private.h | 43 - clutter/cogl/cogl/cogl-pipeline-fragend-arbfp.c | 1109 ---- .../cogl/cogl-pipeline-fragend-fixed-private.h | 36 - clutter/cogl/cogl/cogl-pipeline-fragend-fixed.c | 366 -- .../cogl/cogl/cogl-pipeline-fragend-glsl-private.h | 39 - clutter/cogl/cogl/cogl-pipeline-fragend-glsl.c | 899 --- clutter/cogl/cogl/cogl-pipeline-opengl-private.h | 155 - clutter/cogl/cogl/cogl-pipeline-opengl.c | 1332 ---- clutter/cogl/cogl/cogl-pipeline-private.h | 1258 ---- .../cogl/cogl/cogl-pipeline-progend-glsl-private.h | 54 - clutter/cogl/cogl/cogl-pipeline-progend-glsl.c | 949 --- .../cogl/cogl-pipeline-vertend-fixed-private.h | 36 - clutter/cogl/cogl/cogl-pipeline-vertend-fixed.c | 125 - .../cogl/cogl/cogl-pipeline-vertend-glsl-private.h | 39 - clutter/cogl/cogl/cogl-pipeline-vertend-glsl.c | 420 -- clutter/cogl/cogl/cogl-pipeline.c | 6854 -------------------- clutter/cogl/cogl/cogl-pipeline.h | 1256 ---- clutter/cogl/cogl/cogl-pixel-array-private.h | 55 - clutter/cogl/cogl/cogl-pixel-array.c | 148 - clutter/cogl/cogl/cogl-pixel-array.h | 131 - clutter/cogl/cogl/cogl-point-in-poly-private.h | 40 - clutter/cogl/cogl/cogl-point-in-poly.c | 100 - clutter/cogl/cogl/cogl-primitive-private.h | 54 - clutter/cogl/cogl/cogl-primitive.c | 553 -- clutter/cogl/cogl/cogl-primitive.h | 674 -- clutter/cogl/cogl/cogl-primitives-private.h | 43 - clutter/cogl/cogl/cogl-primitives.c | 1178 ---- clutter/cogl/cogl/cogl-primitives.h | 190 - clutter/cogl/cogl/cogl-private.h | 53 - clutter/cogl/cogl/cogl-profile.c | 78 - clutter/cogl/cogl/cogl-profile.h | 61 - clutter/cogl/cogl/cogl-program-private.h | 84 - clutter/cogl/cogl/cogl-program.c | 633 -- clutter/cogl/cogl/cogl-rectangle-map.c | 752 --- clutter/cogl/cogl/cogl-rectangle-map.h | 78 - clutter/cogl/cogl/cogl-renderer-glx-private.h | 61 - clutter/cogl/cogl/cogl-renderer-private.h | 47 - clutter/cogl/cogl/cogl-renderer-x11-private.h | 32 - clutter/cogl/cogl/cogl-renderer-xlib-private.h | 76 - clutter/cogl/cogl/cogl-renderer-xlib.c | 200 - clutter/cogl/cogl/cogl-renderer.c | 285 - clutter/cogl/cogl/cogl-renderer.h | 164 - clutter/cogl/cogl/cogl-shader-boilerplate.h | 127 - clutter/cogl/cogl/cogl-shader-private.h | 65 - clutter/cogl/cogl/cogl-shader.c | 534 -- clutter/cogl/cogl/cogl-shader.h | 453 -- clutter/cogl/cogl/cogl-spans.c | 132 - clutter/cogl/cogl/cogl-spans.h | 70 - clutter/cogl/cogl/cogl-sub-texture-private.h | 70 - clutter/cogl/cogl/cogl-sub-texture.c | 473 -- clutter/cogl/cogl/cogl-swap-chain-private.h | 38 - clutter/cogl/cogl/cogl-swap-chain.c | 74 - clutter/cogl/cogl/cogl-swap-chain.h | 51 - clutter/cogl/cogl/cogl-texture-2d-private.h | 115 - clutter/cogl/cogl/cogl-texture-2d-sliced-private.h | 71 - clutter/cogl/cogl/cogl-texture-2d-sliced.c | 1397 ---- clutter/cogl/cogl/cogl-texture-2d.c | 741 --- clutter/cogl/cogl/cogl-texture-3d-private.h | 98 - clutter/cogl/cogl/cogl-texture-3d.c | 681 -- clutter/cogl/cogl/cogl-texture-3d.h | 154 - clutter/cogl/cogl/cogl-texture-driver.h | 213 - clutter/cogl/cogl/cogl-texture-private.h | 303 - clutter/cogl/cogl/cogl-texture-rectangle-private.h | 75 - clutter/cogl/cogl/cogl-texture-rectangle.c | 652 -- clutter/cogl/cogl/cogl-texture.c | 1533 ----- clutter/cogl/cogl/cogl-texture.h | 464 -- clutter/cogl/cogl/cogl-types.h | 674 -- clutter/cogl/cogl/cogl-util.c | 240 - clutter/cogl/cogl/cogl-util.h | 106 - clutter/cogl/cogl/cogl-vector.c | 284 - clutter/cogl/cogl/cogl-vector.h | 389 -- clutter/cogl/cogl/cogl-vertex-array-private.h | 39 - clutter/cogl/cogl/cogl-vertex-array.c | 77 - clutter/cogl/cogl/cogl-vertex-array.h | 82 - clutter/cogl/cogl/cogl-vertex-buffer-private.h | 164 - clutter/cogl/cogl/cogl-vertex-buffer.c | 1772 ----- clutter/cogl/cogl/cogl-vertex-buffer.h | 409 -- clutter/cogl/cogl/cogl-xlib-private.h | 76 - clutter/cogl/cogl/cogl-xlib.c | 184 - clutter/cogl/cogl/cogl-xlib.h | 84 - clutter/cogl/cogl/cogl.c | 1114 ---- clutter/cogl/cogl/cogl.h | 1262 ---- clutter/cogl/cogl/cogl.pc.in | 13 - clutter/cogl/cogl/cogl2-clip-state.c | 49 - clutter/cogl/cogl/cogl2-clip-state.h | 52 - clutter/cogl/cogl/cogl2-path.c | 1572 ----- clutter/cogl/cogl/cogl2-path.h | 506 -- clutter/cogl/cogl/driver/Makefile.am | 7 - .../cogl/cogl/driver/gl/cogl-context-driver-gl.h | 53 - .../cogl/driver/gl/cogl-feature-functions-gl.h | 423 -- clutter/cogl/cogl/driver/gl/cogl-gl.c | 233 - .../cogl/cogl/driver/gl/cogl-texture-driver-gl.c | 522 -- .../cogl/driver/gles/cogl-context-driver-gles.h | 52 - .../cogl/driver/gles/cogl-feature-functions-gles.h | 141 - clutter/cogl/cogl/driver/gles/cogl-gles.c | 150 - .../cogl/driver/gles/cogl-texture-driver-gles.c | 511 -- clutter/cogl/cogl/stb_image.c | 3891 ----------- clutter/cogl/cogl/tesselator/GL/glu.h | 40 - clutter/cogl/cogl/tesselator/README | 446 -- clutter/cogl/cogl/tesselator/dict-list.h | 100 - clutter/cogl/cogl/tesselator/dict.c | 111 - clutter/cogl/cogl/tesselator/dict.h | 100 - clutter/cogl/cogl/tesselator/geom.c | 264 - clutter/cogl/cogl/tesselator/geom.h | 84 - clutter/cogl/cogl/tesselator/gluos.h | 1 - clutter/cogl/cogl/tesselator/memalloc.h | 42 - clutter/cogl/cogl/tesselator/mesh.c | 798 --- clutter/cogl/cogl/tesselator/mesh.h | 266 - clutter/cogl/cogl/tesselator/normal.c | 257 - clutter/cogl/cogl/tesselator/normal.h | 45 - clutter/cogl/cogl/tesselator/priorityq-heap.c | 256 - clutter/cogl/cogl/tesselator/priorityq-heap.h | 107 - clutter/cogl/cogl/tesselator/priorityq-sort.h | 117 - clutter/cogl/cogl/tesselator/priorityq.c | 260 - clutter/cogl/cogl/tesselator/priorityq.h | 117 - clutter/cogl/cogl/tesselator/render.c | 502 -- clutter/cogl/cogl/tesselator/render.h | 52 - clutter/cogl/cogl/tesselator/sweep.c | 1361 ---- clutter/cogl/cogl/tesselator/sweep.h | 77 - clutter/cogl/cogl/tesselator/tess.c | 632 -- clutter/cogl/cogl/tesselator/tess.h | 165 - clutter/cogl/cogl/tesselator/tesselator.h | 121 - clutter/cogl/cogl/tesselator/tessmono.c | 201 - clutter/cogl/cogl/tesselator/tessmono.h | 71 - .../cogl/winsys/cogl-texture-pixmap-x11-private.h | 87 - clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c | 972 --- clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h | 155 - .../winsys/cogl-winsys-egl-feature-functions.h | 57 - clutter/cogl/cogl/winsys/cogl-winsys-egl.c | 1282 ---- .../winsys/cogl-winsys-glx-feature-functions.h | 105 - clutter/cogl/cogl/winsys/cogl-winsys-glx.c | 1959 ------ clutter/cogl/cogl/winsys/cogl-winsys-private.h | 154 - clutter/cogl/cogl/winsys/cogl-winsys-sdl.c | 35 - clutter/cogl/cogl/winsys/cogl-winsys-stub.c | 112 - clutter/cogl/cogl/winsys/cogl-winsys.c | 45 - clutter/cogl/configure.ac | 769 --- clutter/cogl/doc/CODING_STYLE | 49 - clutter/cogl/examples/Makefile.am | 31 - clutter/cogl/examples/hello.c | 49 - clutter/cogl/examples/x11-foreign.c | 156 - clutter/cogl/pango/Makefile.am | 56 - clutter/cogl/pango/cogl-pango-display-list.c | 444 -- clutter/cogl/pango/cogl-pango-display-list.h | 69 - clutter/cogl/pango/cogl-pango-fontmap.c | 209 - clutter/cogl/pango/cogl-pango-glyph-cache.c | 414 -- clutter/cogl/pango/cogl-pango-glyph-cache.h | 93 - clutter/cogl/pango/cogl-pango-pipeline-cache.c | 238 - clutter/cogl/pango/cogl-pango-pipeline-cache.h | 53 - clutter/cogl/pango/cogl-pango-private.h | 38 - clutter/cogl/pango/cogl-pango-render.c | 836 --- clutter/cogl/pango/cogl-pango.h | 85 - clutter/cogl/po/ChangeLog | 12 - clutter/cogl/po/Makevars | 41 - clutter/cogl/po/POTFILES.in | 1 - clutter/cogl/po/Rules-quot | 47 - clutter/cogl/po/boldquot.sed | 10 - clutter/cogl/po/en@boldquot.header | 25 - clutter/cogl/po/en@quot.header | 22 - clutter/cogl/po/insert-header.sin | 23 - clutter/cogl/po/quot.sed | 6 - clutter/cogl/po/remove-potcdate.sin | 19 - clutter/glx/clutter-glx-texture-pixmap.c | 4 - clutter/wayland/clutter-backend-wayland.c | 16 +- clutter/x11/clutter-x11-texture-pixmap.c | 6 +- configure.ac | 373 +- doc/reference/Makefile.am | 4 +- doc/reference/cogl/Makefile.am | 151 - doc/reference/cogl/blend-strings.xml | 129 - doc/reference/cogl/cogl-docs.xml.in | 206 - doc/reference/cogl/cogl-sections.txt | 660 -- doc/reference/cogl/cogl_ortho.png | Bin 12650 -> 0 bytes doc/reference/cogl/fill-rule-even-odd.png | Bin 3121 -> 0 bytes doc/reference/cogl/fill-rule-non-zero.png | Bin 3143 -> 0 bytes doc/reference/cogl/quad-indices-order.png | Bin 2620 -> 0 bytes doc/reference/cogl/quad-indices-triangles.png | Bin 8018 -> 0 bytes tests/conform/test-cogl-texture-pixmap-x11.c | 4 +- tests/interactive/test-box-layout.c | 2 +- tests/interactive/test-table-layout.c | 2 +- 277 files changed, 25 insertions(+), 89249 deletions(-) delete mode 100644 clutter/cogl/Makefile.am delete mode 100755 clutter/cogl/autogen.sh delete mode 100644 clutter/cogl/build/autotools/Makefile.am.enums delete mode 100644 clutter/cogl/build/autotools/Makefile.am.silent delete mode 100644 clutter/cogl/build/autotools/as-compiler-flag.m4 delete mode 100644 clutter/cogl/build/autotools/as-linguas.m4 delete mode 100644 clutter/cogl/build/autotools/introspection.m4 delete mode 100644 clutter/cogl/cogl/Makefile.am delete mode 100644 clutter/cogl/cogl/cogl-1.0-clutter.pc.in delete mode 100644 clutter/cogl/cogl/cogl-1.0.pc.in delete mode 100644 clutter/cogl/cogl/cogl-atlas-texture-private.h delete mode 100644 clutter/cogl/cogl/cogl-atlas-texture.c delete mode 100644 clutter/cogl/cogl/cogl-atlas.c delete mode 100644 clutter/cogl/cogl/cogl-atlas.h delete mode 100644 clutter/cogl/cogl/cogl-attribute-private.h delete mode 100644 clutter/cogl/cogl/cogl-attribute.c delete mode 100644 clutter/cogl/cogl/cogl-attribute.h delete mode 100644 clutter/cogl/cogl/cogl-bitmap-fallback.c delete mode 100644 clutter/cogl/cogl/cogl-bitmap-pixbuf.c delete mode 100644 clutter/cogl/cogl/cogl-bitmap-private.h delete mode 100644 clutter/cogl/cogl/cogl-bitmap.c delete mode 100644 clutter/cogl/cogl/cogl-bitmap.h delete mode 100644 clutter/cogl/cogl/cogl-bitmask.c delete mode 100644 clutter/cogl/cogl/cogl-bitmask.h delete mode 100644 clutter/cogl/cogl/cogl-blend-string.c delete mode 100644 clutter/cogl/cogl/cogl-blend-string.h delete mode 100644 clutter/cogl/cogl/cogl-blit.c delete mode 100644 clutter/cogl/cogl/cogl-blit.h delete mode 100644 clutter/cogl/cogl/cogl-buffer-private.h delete mode 100644 clutter/cogl/cogl/cogl-buffer.c delete mode 100644 clutter/cogl/cogl/cogl-buffer.h delete mode 100644 clutter/cogl/cogl/cogl-clip-stack.c delete mode 100644 clutter/cogl/cogl/cogl-clip-stack.h delete mode 100644 clutter/cogl/cogl/cogl-clip-state-private.h delete mode 100644 clutter/cogl/cogl/cogl-clip-state.c delete mode 100644 clutter/cogl/cogl/cogl-clip-state.h delete mode 100644 clutter/cogl/cogl/cogl-clutter.c delete mode 100644 clutter/cogl/cogl/cogl-clutter.h delete mode 100644 clutter/cogl/cogl/cogl-color-private.h delete mode 100644 clutter/cogl/cogl/cogl-color.c delete mode 100644 clutter/cogl/cogl/cogl-color.h delete mode 100644 clutter/cogl/cogl/cogl-context-private.h delete mode 100644 clutter/cogl/cogl/cogl-context.c delete mode 100644 clutter/cogl/cogl/cogl-context.h delete mode 100644 clutter/cogl/cogl/cogl-debug-options.h delete mode 100644 clutter/cogl/cogl/cogl-debug.c delete mode 100644 clutter/cogl/cogl/cogl-debug.h delete mode 100644 clutter/cogl/cogl/cogl-defines.h.in delete mode 100644 clutter/cogl/cogl/cogl-deprecated.h delete mode 100644 clutter/cogl/cogl/cogl-display-glx-private.h delete mode 100644 clutter/cogl/cogl/cogl-display-private.h delete mode 100644 clutter/cogl/cogl/cogl-display-xlib-private.h delete mode 100644 clutter/cogl/cogl/cogl-display.c delete mode 100644 clutter/cogl/cogl/cogl-display.h delete mode 100644 clutter/cogl/cogl/cogl-enum-types.c.in delete mode 100644 clutter/cogl/cogl/cogl-enum-types.h.in delete mode 100644 clutter/cogl/cogl/cogl-feature-private.c delete mode 100644 clutter/cogl/cogl/cogl-feature-private.h delete mode 100644 clutter/cogl/cogl/cogl-fixed.c delete mode 100644 clutter/cogl/cogl/cogl-fixed.h delete mode 100644 clutter/cogl/cogl/cogl-flags.h delete mode 100644 clutter/cogl/cogl/cogl-framebuffer-private.h delete mode 100644 clutter/cogl/cogl/cogl-framebuffer.c delete mode 100644 clutter/cogl/cogl/cogl-framebuffer.h delete mode 100644 clutter/cogl/cogl/cogl-gtype-private.h delete mode 100644 clutter/cogl/cogl/cogl-handle.h delete mode 100644 clutter/cogl/cogl/cogl-index-array-private.h delete mode 100644 clutter/cogl/cogl/cogl-index-array.c delete mode 100644 clutter/cogl/cogl/cogl-index-array.h delete mode 100644 clutter/cogl/cogl/cogl-indices-private.h delete mode 100644 clutter/cogl/cogl/cogl-indices.c delete mode 100644 clutter/cogl/cogl/cogl-indices.h delete mode 100644 clutter/cogl/cogl/cogl-internal.h delete mode 100644 clutter/cogl/cogl/cogl-journal-private.h delete mode 100644 clutter/cogl/cogl/cogl-journal.c delete mode 100644 clutter/cogl/cogl/cogl-material-compat.c delete mode 100644 clutter/cogl/cogl/cogl-material-compat.h delete mode 100644 clutter/cogl/cogl/cogl-matrix-mesa.c delete mode 100644 clutter/cogl/cogl/cogl-matrix-mesa.h delete mode 100644 clutter/cogl/cogl/cogl-matrix-private.h delete mode 100644 clutter/cogl/cogl/cogl-matrix-stack.c delete mode 100644 clutter/cogl/cogl/cogl-matrix-stack.h delete mode 100644 clutter/cogl/cogl/cogl-matrix.c delete mode 100644 clutter/cogl/cogl/cogl-matrix.h delete mode 100644 clutter/cogl/cogl/cogl-object-private.h delete mode 100644 clutter/cogl/cogl/cogl-object.c delete mode 100644 clutter/cogl/cogl/cogl-object.h delete mode 100644 clutter/cogl/cogl/cogl-offscreen.h delete mode 100644 clutter/cogl/cogl/cogl-onscreen-template-private.h delete mode 100644 clutter/cogl/cogl/cogl-onscreen-template.c delete mode 100644 clutter/cogl/cogl/cogl-onscreen-template.h delete mode 100644 clutter/cogl/cogl/cogl-path-private.h delete mode 100644 clutter/cogl/cogl/cogl-path.c delete mode 100644 clutter/cogl/cogl/cogl-path.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-fragend-arbfp-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-fragend-arbfp.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline-fragend-fixed-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-fragend-fixed.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline-fragend-glsl-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-fragend-glsl.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline-opengl-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-opengl.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-progend-glsl-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-progend-glsl.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline-vertend-fixed-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-vertend-fixed.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline-vertend-glsl-private.h delete mode 100644 clutter/cogl/cogl/cogl-pipeline-vertend-glsl.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline.c delete mode 100644 clutter/cogl/cogl/cogl-pipeline.h delete mode 100644 clutter/cogl/cogl/cogl-pixel-array-private.h delete mode 100644 clutter/cogl/cogl/cogl-pixel-array.c delete mode 100644 clutter/cogl/cogl/cogl-pixel-array.h delete mode 100644 clutter/cogl/cogl/cogl-point-in-poly-private.h delete mode 100644 clutter/cogl/cogl/cogl-point-in-poly.c delete mode 100644 clutter/cogl/cogl/cogl-primitive-private.h delete mode 100644 clutter/cogl/cogl/cogl-primitive.c delete mode 100644 clutter/cogl/cogl/cogl-primitive.h delete mode 100644 clutter/cogl/cogl/cogl-primitives-private.h delete mode 100644 clutter/cogl/cogl/cogl-primitives.c delete mode 100644 clutter/cogl/cogl/cogl-primitives.h delete mode 100644 clutter/cogl/cogl/cogl-private.h delete mode 100644 clutter/cogl/cogl/cogl-profile.c delete mode 100644 clutter/cogl/cogl/cogl-profile.h delete mode 100644 clutter/cogl/cogl/cogl-program-private.h delete mode 100644 clutter/cogl/cogl/cogl-program.c delete mode 100644 clutter/cogl/cogl/cogl-rectangle-map.c delete mode 100644 clutter/cogl/cogl/cogl-rectangle-map.h delete mode 100644 clutter/cogl/cogl/cogl-renderer-glx-private.h delete mode 100644 clutter/cogl/cogl/cogl-renderer-private.h delete mode 100644 clutter/cogl/cogl/cogl-renderer-x11-private.h delete mode 100644 clutter/cogl/cogl/cogl-renderer-xlib-private.h delete mode 100644 clutter/cogl/cogl/cogl-renderer-xlib.c delete mode 100644 clutter/cogl/cogl/cogl-renderer.c delete mode 100644 clutter/cogl/cogl/cogl-renderer.h delete mode 100644 clutter/cogl/cogl/cogl-shader-boilerplate.h delete mode 100644 clutter/cogl/cogl/cogl-shader-private.h delete mode 100644 clutter/cogl/cogl/cogl-shader.c delete mode 100644 clutter/cogl/cogl/cogl-shader.h delete mode 100644 clutter/cogl/cogl/cogl-spans.c delete mode 100644 clutter/cogl/cogl/cogl-spans.h delete mode 100644 clutter/cogl/cogl/cogl-sub-texture-private.h delete mode 100644 clutter/cogl/cogl/cogl-sub-texture.c delete mode 100644 clutter/cogl/cogl/cogl-swap-chain-private.h delete mode 100644 clutter/cogl/cogl/cogl-swap-chain.c delete mode 100644 clutter/cogl/cogl/cogl-swap-chain.h delete mode 100644 clutter/cogl/cogl/cogl-texture-2d-private.h delete mode 100644 clutter/cogl/cogl/cogl-texture-2d-sliced-private.h delete mode 100644 clutter/cogl/cogl/cogl-texture-2d-sliced.c delete mode 100644 clutter/cogl/cogl/cogl-texture-2d.c delete mode 100644 clutter/cogl/cogl/cogl-texture-3d-private.h delete mode 100644 clutter/cogl/cogl/cogl-texture-3d.c delete mode 100644 clutter/cogl/cogl/cogl-texture-3d.h delete mode 100644 clutter/cogl/cogl/cogl-texture-driver.h delete mode 100644 clutter/cogl/cogl/cogl-texture-private.h delete mode 100644 clutter/cogl/cogl/cogl-texture-rectangle-private.h delete mode 100644 clutter/cogl/cogl/cogl-texture-rectangle.c delete mode 100644 clutter/cogl/cogl/cogl-texture.c delete mode 100644 clutter/cogl/cogl/cogl-texture.h delete mode 100644 clutter/cogl/cogl/cogl-types.h delete mode 100644 clutter/cogl/cogl/cogl-util.c delete mode 100644 clutter/cogl/cogl/cogl-util.h delete mode 100644 clutter/cogl/cogl/cogl-vector.c delete mode 100644 clutter/cogl/cogl/cogl-vector.h delete mode 100644 clutter/cogl/cogl/cogl-vertex-array-private.h delete mode 100644 clutter/cogl/cogl/cogl-vertex-array.c delete mode 100644 clutter/cogl/cogl/cogl-vertex-array.h delete mode 100644 clutter/cogl/cogl/cogl-vertex-buffer-private.h delete mode 100644 clutter/cogl/cogl/cogl-vertex-buffer.c delete mode 100644 clutter/cogl/cogl/cogl-vertex-buffer.h delete mode 100644 clutter/cogl/cogl/cogl-xlib-private.h delete mode 100644 clutter/cogl/cogl/cogl-xlib.c delete mode 100644 clutter/cogl/cogl/cogl-xlib.h delete mode 100644 clutter/cogl/cogl/cogl.c delete mode 100644 clutter/cogl/cogl/cogl.h delete mode 100644 clutter/cogl/cogl/cogl.pc.in delete mode 100644 clutter/cogl/cogl/cogl2-clip-state.c delete mode 100644 clutter/cogl/cogl/cogl2-clip-state.h delete mode 100644 clutter/cogl/cogl/cogl2-path.c delete mode 100644 clutter/cogl/cogl/cogl2-path.h delete mode 100644 clutter/cogl/cogl/driver/Makefile.am delete mode 100644 clutter/cogl/cogl/driver/gl/cogl-context-driver-gl.h delete mode 100644 clutter/cogl/cogl/driver/gl/cogl-feature-functions-gl.h delete mode 100644 clutter/cogl/cogl/driver/gl/cogl-gl.c delete mode 100644 clutter/cogl/cogl/driver/gl/cogl-texture-driver-gl.c delete mode 100644 clutter/cogl/cogl/driver/gles/cogl-context-driver-gles.h delete mode 100644 clutter/cogl/cogl/driver/gles/cogl-feature-functions-gles.h delete mode 100644 clutter/cogl/cogl/driver/gles/cogl-gles.c delete mode 100644 clutter/cogl/cogl/driver/gles/cogl-texture-driver-gles.c delete mode 100644 clutter/cogl/cogl/stb_image.c delete mode 100644 clutter/cogl/cogl/tesselator/GL/glu.h delete mode 100644 clutter/cogl/cogl/tesselator/README delete mode 100644 clutter/cogl/cogl/tesselator/dict-list.h delete mode 100644 clutter/cogl/cogl/tesselator/dict.c delete mode 100644 clutter/cogl/cogl/tesselator/dict.h delete mode 100644 clutter/cogl/cogl/tesselator/geom.c delete mode 100644 clutter/cogl/cogl/tesselator/geom.h delete mode 100644 clutter/cogl/cogl/tesselator/gluos.h delete mode 100644 clutter/cogl/cogl/tesselator/memalloc.h delete mode 100644 clutter/cogl/cogl/tesselator/mesh.c delete mode 100644 clutter/cogl/cogl/tesselator/mesh.h delete mode 100644 clutter/cogl/cogl/tesselator/normal.c delete mode 100644 clutter/cogl/cogl/tesselator/normal.h delete mode 100644 clutter/cogl/cogl/tesselator/priorityq-heap.c delete mode 100644 clutter/cogl/cogl/tesselator/priorityq-heap.h delete mode 100644 clutter/cogl/cogl/tesselator/priorityq-sort.h delete mode 100644 clutter/cogl/cogl/tesselator/priorityq.c delete mode 100644 clutter/cogl/cogl/tesselator/priorityq.h delete mode 100644 clutter/cogl/cogl/tesselator/render.c delete mode 100644 clutter/cogl/cogl/tesselator/render.h delete mode 100644 clutter/cogl/cogl/tesselator/sweep.c delete mode 100644 clutter/cogl/cogl/tesselator/sweep.h delete mode 100644 clutter/cogl/cogl/tesselator/tess.c delete mode 100644 clutter/cogl/cogl/tesselator/tess.h delete mode 100644 clutter/cogl/cogl/tesselator/tesselator.h delete mode 100644 clutter/cogl/cogl/tesselator/tessmono.c delete mode 100644 clutter/cogl/cogl/tesselator/tessmono.h delete mode 100644 clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h delete mode 100644 clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c delete mode 100644 clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys-egl.c delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys-glx.c delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys-private.h delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys-sdl.c delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys-stub.c delete mode 100644 clutter/cogl/cogl/winsys/cogl-winsys.c delete mode 100644 clutter/cogl/configure.ac delete mode 100644 clutter/cogl/doc/CODING_STYLE delete mode 100644 clutter/cogl/examples/Makefile.am delete mode 100644 clutter/cogl/examples/hello.c delete mode 100644 clutter/cogl/examples/x11-foreign.c delete mode 100644 clutter/cogl/pango/Makefile.am delete mode 100644 clutter/cogl/pango/cogl-pango-display-list.c delete mode 100644 clutter/cogl/pango/cogl-pango-display-list.h delete mode 100644 clutter/cogl/pango/cogl-pango-fontmap.c delete mode 100644 clutter/cogl/pango/cogl-pango-glyph-cache.c delete mode 100644 clutter/cogl/pango/cogl-pango-glyph-cache.h delete mode 100644 clutter/cogl/pango/cogl-pango-pipeline-cache.c delete mode 100644 clutter/cogl/pango/cogl-pango-pipeline-cache.h delete mode 100644 clutter/cogl/pango/cogl-pango-private.h delete mode 100644 clutter/cogl/pango/cogl-pango-render.c delete mode 100644 clutter/cogl/pango/cogl-pango.h delete mode 100644 clutter/cogl/po/ChangeLog delete mode 100644 clutter/cogl/po/Makevars delete mode 100644 clutter/cogl/po/POTFILES.in delete mode 100644 clutter/cogl/po/Rules-quot delete mode 100644 clutter/cogl/po/boldquot.sed delete mode 100644 clutter/cogl/po/en@boldquot.header delete mode 100644 clutter/cogl/po/en@quot.header delete mode 100644 clutter/cogl/po/insert-header.sin delete mode 100644 clutter/cogl/po/quot.sed delete mode 100644 clutter/cogl/po/remove-potcdate.sin delete mode 100644 doc/reference/cogl/Makefile.am delete mode 100644 doc/reference/cogl/blend-strings.xml delete mode 100644 doc/reference/cogl/cogl-docs.xml.in delete mode 100644 doc/reference/cogl/cogl-sections.txt delete mode 100644 doc/reference/cogl/cogl_ortho.png delete mode 100644 doc/reference/cogl/fill-rule-even-odd.png delete mode 100644 doc/reference/cogl/fill-rule-non-zero.png delete mode 100644 doc/reference/cogl/quad-indices-order.png delete mode 100644 doc/reference/cogl/quad-indices-triangles.png diff --git a/.gitignore b/.gitignore index 50016d0..6c0b564 100644 --- a/.gitignore +++ b/.gitignore @@ -22,15 +22,8 @@ stamp-marshal /clutter/clutter-version.h /clutter/gcov-report.txt /clutter/clutter-json.h -/clutter/cogl/cogl/cogl-defines.h -/clutter/cogl/cogl/cogl-enum-types.[ch] -/clutter/cogl/cogl/driver/gl/cogl-defines.h -/clutter/cogl/cogl/driver/gles/cogl-defines.h -/clutter/cogl/cogl/cogl-fixed-vertex-shader.[ch] -/clutter/cogl/cogl/cogl-fixed-fragment-shader.[ch] /clutter/egl/clutter-cex100.h /build/autotools/*.m4 -/clutter/cogl/build/autotools/*.m4 !/build/autotools/introspection.m4 !/build/autotools/as-linguas.m4 !/build/autotools/as-compiler-flag.m4 @@ -61,32 +54,6 @@ doc/reference/clutter/clutter.signals doc/reference/clutter/clutter-docs.xml doc/reference/clutter/*.stamp doc/reference/clutter/*.bak -doc/reference/cogl/cogl-*.txt -!/doc/reference/cogl/cogl-sections.txt -doc/reference/cogl/html -doc/reference/cogl/tmpl -doc/reference/cogl/xml -doc/reference/cogl/cogl.args -doc/reference/cogl/cogl.hierarchy -doc/reference/cogl/cogl.interfaces -doc/reference/cogl/cogl.prerequisites -doc/reference/cogl/cogl.signals -doc/reference/cogl/cogl-docs.xml -doc/reference/cogl/*.stamp -doc/reference/cogl/*.bak -doc/reference/cogl-2.0/cogl-*.txt -!/doc/reference/cogl-2.0/cogl-sections.txt -doc/reference/cogl-2.0/html -doc/reference/cogl-2.0/tmpl -doc/reference/cogl-2.0/xml -doc/reference/cogl-2.0/cogl.args -doc/reference/cogl-2.0/cogl.hierarchy -doc/reference/cogl-2.0/cogl.interfaces -doc/reference/cogl-2.0/cogl.prerequisites -doc/reference/cogl-2.0/cogl.signals -doc/reference/cogl-2.0/cogl-docs.xml -doc/reference/cogl-2.0/*.stamp -doc/reference/cogl-2.0/*.bak doc/reference/cally/cally-*.txt !/doc/reference/cally/cally-sections.txt doc/reference/cally/html @@ -124,19 +91,6 @@ TAGS /po/remove-potcdate.sin /po/remove-potcdate.sed /po/stamp-po -/clutter/cogl/po/POTFILES -/clutter/cogl/po/*.gmo -/clutter/cogl/po/Makefile.in.in -/clutter/cogl/po/Makevars.template -/clutter/cogl/po/Rules-quot -/clutter/cogl/po/boldquot.sed -/clutter/cogl/po/en@boldquot.header -/clutter/cogl/po/en@quot.header -/clutter/cogl/po/insert-header.sin -/clutter/cogl/po/quot.sed -/clutter/cogl/po/remove-potcdate.sin -/clutter/cogl/po/remove-potcdate.sed -/clutter/cogl/po/stamp-po *.swn *.swo *.swp diff --git a/README.in b/README.in index 4444be8..9b8b33c 100644 --- a/README.in +++ b/README.in @@ -10,12 +10,11 @@ REQUIREMENTS Clutter currently requires: • GLib ≥ @GLIB_REQ_VERSION@ + • Cogl ≥ @COGL_REQ_VERSION@ • JSON-GLib ≥ @JSON_GLIB_REQ_VERSION@ • Atk ≥ @ATK_REQ_VERSION@ • Cairo ≥ @CAIRO_REQ_VERSION@ • PangoCairo ≥ @PANGO_REQ_VERSION@ - • OpenGL ≥ 1.3 (or 1.2 + multitexturing), or OpenGL ES 2.0 (or 1.1) - • GLX, AGL, WGL or an EGL implementation Clutter also has optional dependencies: @@ -137,21 +136,6 @@ Clutter has additional command line options for the configure script: debugging notes. Only use in extreme performance and/or size optimization cases, though it is strongly discouraged. - --enable-cogl-debug=[no/minimum/yes] - Controls COGL debugging level (default=minimum): - - yes: - Support for COGL debugging notes through COGL_DEBUG and - error checking for each GL primitive. This is useful mostly - to debug COGL itself. - - minimum: - Support for COGL debugging notes through COGL_DEBUG. This is - the default for developers snapshots. - - no: - Disable support for COGL runtime debugging notes. - --enable-maintainer-flags=[no/yes/error] Use strict compiler flags. This defaults to 'yes' for building from Git to 'no' for tarball releases. If 'error' is used, then -Werror @@ -209,23 +193,6 @@ Clutter has additional command line options for the configure script: win32: Microsoft Windows(tm) WGL backend. - --with-imagebackend=[gdk-pixbuf/quartz/internal] - Select the image loading backend used by COGL - - gdk-pixbuf: - Depend on gdk-pixbuf-2.0 (default for the glx, eglx, - eglnative, win32 flavours and recommended). - - quartz: - Depend on CoreGraphics (default for the osx flavour). - - internal: - Internal JPEG and PNG loader. Should only be used - for testing on new platforms - - --with-gles=[1.1/2.0] - Select the GLES version (for EGL backends) (default=1.1) - See also the INSTALL file generated by autotools for further information. VERSIONING diff --git a/clutter/Makefile.am b/clutter/Makefile.am index f037d12..3a931da 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -3,11 +3,6 @@ include $(top_srcdir)/build/autotools/Makefile.am.silent # preamble NULL = -# we recurse only into Cogl -if !USE_SYSTEM_COGL -SUBDIRS = cogl -endif - # common definitions CLEANFILES = DISTCLEANFILES = @@ -27,14 +22,6 @@ INCLUDES = \ -I$(top_builddir)/clutter \ $(NULL) -if !USE_SYSTEM_COGL -INCLUDES += \ - -I$(top_srcdir)/clutter/cogl \ - -I$(top_srcdir)/clutter/cogl/pango \ - -I$(top_builddir)/clutter/cogl \ - $(NULL) -endif - AM_CPPFLAGS = \ -DCLUTTER_PREFIX=\""$(prefix)"\" \ -DCLUTTER_LIBDIR=\""$(libdir)"\" \ @@ -633,15 +620,6 @@ libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_LIBADD = \ libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_DEPENDENCIES = \ $(win32_resources) -if !USE_SYSTEM_COGL -libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_LIBADD += \ - $(top_builddir)/clutter/cogl/cogl/libcogl.la \ - $(top_builddir)/clutter/cogl/pango/libcoglpango.la -libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_DEPENDENCIES += \ - $(top_builddir)/clutter/cogl/cogl/libcogl.la \ - $(top_builddir)/clutter/cogl/pango/libcoglpango.la -endif - libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_SOURCES = \ $(backend_source_c) \ $(backend_source_h) \ @@ -666,7 +644,7 @@ libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_LDFLAGS = \ $(CLUTTER_LT_LDFLAGS) \ $(GCOV_LDFLAGS) \ -export-dynamic \ - -export-symbols-regex "^(clutter|cogl|cally).*" \ + -export-symbols-regex "^(clutter|cally).*" \ -rpath $(libdir) \ $(win32_resources_ldflag) \ $(NULL) @@ -689,36 +667,9 @@ Clutter_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \ --warn-all \ --c-include='clutter/clutter.h' \ --pkg-export=clutter-@CLUTTER_API_VERSION@ -if USE_SYSTEM_COGL Clutter_@CLUTTER_API_VERSION_AM@_gir_INCLUDES += Cogl-1.0 -else -Clutter_@CLUTTER_API_VERSION_AM@_gir_LIBS += \ - $(top_builddir)/clutter/cogl/cogl/libcogl.la \ - $(top_builddir)/clutter/cogl/pango/libcoglpango.la -Clutter_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS += \ - --include-uninstalled=$(top_builddir)/clutter/cogl/cogl/Cogl-1.0.gir -COGL_GIR_DEP=Cogl-1.0.gir -endif - -if !USE_SYSTEM_COGL -# Cogl.gir is used included into Clutter.gir, so it needs to be built -# before the typelib is generated -Clutter-@CLUTTER_API_VERSION@.typelib: Cogl-1.0.gir - -# We build Cogl.gir in the cogl/ subdir, but it needs to reference the shared -# library that it's built into, so we delay compiling the gir into typelib -# until after we've built the shared library. To create the final Cogl.gir -# that we compile and install, we transfer the shared-library="" line from -# Clutter.gir to Cogl.gir -Cogl-1.0.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir cogl/cogl/Cogl-1.0.gir - $(QUIET_GEN) \ - shlib=`sed -n 's/.*shared-library="\([^"]*\)".*/\1/p' < Clutter-@CLUTTER_API_VERSION@.gir` ; \ - sed "s/shared-library=\"[^\"]*\"/shared-library=\"$$shlib\"/"< $(top_builddir)/clutter/cogl/cogl/Cogl-1.0.gir > $@ - -BUILT_GIRSOURCES += Cogl-1.0.gir -endif - -Cally-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir $(COGL_GIR_DEP) + +Cally-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir Cally_@CLUTTER_API_VERSION_AM@_gir_NAMESPACE = Cally Cally_@CLUTTER_API_VERSION_AM@_gir_VERSION = @CLUTTER_API_VERSION@ @@ -733,22 +684,13 @@ Cally_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \ # Note: it's important to pass --include-uninstalled for the Cogl-1.0.gir # before the Clutter gir otherwise g-ir-scanner can get upset as it # immediatly scans the Clutter gir file and may fail to find a Cogl-1.0.gir -if USE_SYSTEM_COGL Cally_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS += \ --include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir -else -Cally_@CLUTTER_API_VERSION_AM@_gir_LIBS += \ - $(top_builddir)/clutter/cogl/cogl/libcogl.la \ - $(top_builddir)/clutter/cogl/pango/libcoglpango.la -Cally_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS += \ - --include-uninstalled=$(top_builddir)/clutter/Cogl-1.0.gir \ - --include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir -endif INTROSPECTION_GIRS += Cally-@CLUTTER_API_VERSION@.gir if SUPPORT_X11 -ClutterX11-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir $(COGL_GIR_DEP) +ClutterX11-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir ClutterX11_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \ --identifier-prefix=ClutterX11 \ @@ -763,17 +705,8 @@ ClutterX11_@CLUTTER_API_VERSION_AM@_gir_CFLAGS = $(INCLUDES) $(CLUTTER_CFLAGS) $ # Note: it's important to pass --include-uninstalled for the Cogl-1.0.gir # before the Clutter gir otherwise g-ir-scanner can get upset as it # immediatly scans the Clutter gir file and may fail to find a Cogl-1.0.gir -if USE_SYSTEM_COGL -ClutterX11_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS += \ - --include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir -else ClutterX11_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS += \ - --include-uninstalled=$(top_builddir)/clutter/Cogl-1.0.gir \ --include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir -ClutterX11_@CLUTTER_API_VERSION_AM@_gir_LIBS += \ - $(top_builddir)/clutter/cogl/cogl/libcogl.la \ - $(top_builddir)/clutter/cogl/pango/libcoglpango.la -endif INTROSPECTION_GIRS += ClutterX11-@CLUTTER_API_VERSION@.gir endif # SUPPORT_X11 diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index c7d2f30..5373027 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -110,12 +110,7 @@ #include "clutter-version.h" /* For flavour define */ #include - -#ifdef CLUTTER_USING_SYSTEM_COGL #include -#else -#include "pango/cogl-pango.h" -#endif #include "cally.h" /* For accessibility support */ diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 7476f0e..6854700 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -30,11 +30,7 @@ #include -#ifdef CLUTTER_USING_SYSTEM_COGL #include -#else -#include "pango/cogl-pango.h" -#endif #include "clutter-backend.h" #include "clutter-effect.h" diff --git a/clutter/cogl/Makefile.am b/clutter/cogl/Makefile.am deleted file mode 100644 index 3d7dd3e..0000000 --- a/clutter/cogl/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -SUBDIRS = cogl pango - -if COGL_STANDALONE_BUILD -SUBDIRS += po examples -endif - -ACLOCAL_AMFLAGS = -I build/autotools ${ACLOCAL_FLAGS} diff --git a/clutter/cogl/autogen.sh b/clutter/cogl/autogen.sh deleted file mode 100755 index 6ca0de2..0000000 --- a/clutter/cogl/autogen.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh -# Run this to generate all the initial makefiles, etc. - -srcdir=`dirname $0` -test -z "$srcdir" && srcdir=. - -ORIGDIR=`pwd` - -cd $srcdir -PROJECT=Cogl -TEST_TYPE=-f -FILE=cogl/cogl.h - -test $TEST_TYPE $FILE || { - echo "You must run this script in the top-level $PROJECT directory" - exit 1 -} - -if automake-1.11 --version < /dev/null > /dev/null 2>&1 ; then - AUTOMAKE=automake-1.11 - ACLOCAL=aclocal-1.11 - export AUTOMAKE ACLOCAL -else - echo - echo "You must have automake 1.11.x installed to compile $PROJECT -ECT." - echo "Install the appropriate package for your distribution," - echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/" - exit 1 -fi - -(gtkdocize --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "You must have gtk-doc installed to compile $PROJECT." - echo "Install the appropriate package for your distribution," - echo "or get the source tarball at http://ftp.gnome.org/pub/GNOME/sources/gtk-doc/" - exit 1 -} - -# NOCONFIGURE is used by gnome-common -if test -z "$NOCONFIGURE"; then - if test -z "$*"; then - echo "I am going to run ./configure with no arguments - if you wish " - echo "to pass any to it, please specify them on the $0 command line." - fi -fi - -if test -z "$ACLOCAL_FLAGS"; then - acdir=`$ACLOCAL --print-ac-dir` - m4list="glib-2.0.m4" - for file in $m4list; do - if [ ! -f "$acdir/$file" ]; then - echo "WARNING: aclocal's directory is $acdir, but..." - echo " no file $acdir/$file" - echo " You may see fatal macro warnings below." - echo " If these files are installed in /some/dir, set the ACLOCAL_FLAGS " - echo " environment variable to \"-I /some/dir\", or install" - echo " $acdir/$file." - echo "" - fi - done -fi - -rm -rf autom4te.cache - -gtkdocize || exit $? -autoreconf -vfi || exit $? -cd $ORIGDIR || exit $? - -if test -z "$NOCONFIGURE"; then - $srcdir/configure $AUTOGEN_CONFIGURE_ARGS "$@" || exit $? - echo "Now type 'make' to compile $PROJECT." -fi diff --git a/clutter/cogl/build/autotools/Makefile.am.enums b/clutter/cogl/build/autotools/Makefile.am.enums deleted file mode 100644 index d3dc742..0000000 --- a/clutter/cogl/build/autotools/Makefile.am.enums +++ /dev/null @@ -1,51 +0,0 @@ -# Rules for generating enumeration types using glib-mkenums -# -# Define: -# glib_enum_h = header template file -# glib_enum_c = source template file -# glib_enum_headers = list of headers to parse -# -# before including Makefile.am.enums. You will also need to have -# the following targets already defined: -# -# CLEANFILES -# DISTCLEANFILES -# BUILT_SOURCES -# EXTRA_DIST -# -# Author: Emmanuele Bassi - -# Basic sanity checks -$(if $(GLIB_MKENUMS),,$(error Need to define GLIB_MKENUMS)) - -$(if $(or $(glib_enum_h), \ - $(glib_enum_c)),, \ - $(error Need to define glib_enum_h and glib_enum_c)) - -$(if $(glib_enum_headers),,$(error Need to define glib_enum_headers)) - -enum_tmpl_h=$(addprefix $(srcdir)/, $(glib_enum_h:.h=.h.in)) -enum_tmpl_c=$(addprefix $(srcdir)/, $(glib_enum_c:.c=.c.in)) - -CLEANFILES += stamp-enum-types -DISTCLEANFILES += $(glib_enum_h) $(glib_enum_c) -BUILT_SOURCES += $(glib_enum_h) $(glib_enum_c) -EXTRA_DIST += $(enum_tmpl_h) $(enum_tmpl_c) - -stamp-enum-types: $(glib_enum_headers) $(enum_tmpl_h) - $(AM_V_GEN)$(GLIB_MKENUMS) \ - --template $(enum_tmpl_h) \ - $(glib_enum_headers) > xgen-eh \ - && (cmp -s xgen-eh $(glib_enum_h) || cp -f xgen-eh $(glib_enum_h)) \ - && rm -f xgen-eh \ - && echo timestamp > $(@F) - -$(glib_enum_h): stamp-enum-types - @true - -$(glib_enum_c): $(glib_enum_headers) $(glib_enum_h) $(enum_tmpl_c) - $(AM_V_GEN)$(GLIB_MKENUMS) \ - --template $(enum_tmpl_c) \ - $(glib_enum_headers) > xgen-ec \ - && cp -f xgen-ec $(glib_enum_c) \ - && rm -f xgen-ec diff --git a/clutter/cogl/build/autotools/Makefile.am.silent b/clutter/cogl/build/autotools/Makefile.am.silent deleted file mode 100644 index ca46592..0000000 --- a/clutter/cogl/build/autotools/Makefile.am.silent +++ /dev/null @@ -1,19 +0,0 @@ -# custom rules for quiet builds - -QUIET_GEN = $(AM_V_GEN) - -QUIET_LN = $(QUIET_LN_$(V)) -QUIET_LN_ = $(QUIET_LN_$(AM_DEFAULT_VERBOSITY)) -QUIET_LN_0 = @echo ' LN '$@; - -QUIET_RM = $(QUIET_RM_$(V)) -QUIET_RM_ = $(QUIET_RM_$(AM_DEFAULT_VERBOSITY)) -QUIET_RM_0 = @echo ' RM '$@; - -QUIET_SCAN = $(QUIET_SCAN_$(V)) -QUIET_SCAN_ = $(QUIET_SCAN_$(AM_DEFAULT_VERBOSITY)) -QUIET_SCAN_0 = @echo ' GISCAN '$@; - -QUIET_COMP = $(QUIET_COMP_$(V)) -QUIET_COMP_ = $(QUIET_COMP_$(AM_DEFAULT_VERBOSITY)) -QUIET_COMP_0 = @echo ' GICOMP '$@; diff --git a/clutter/cogl/build/autotools/as-compiler-flag.m4 b/clutter/cogl/build/autotools/as-compiler-flag.m4 deleted file mode 100644 index 0f660cf..0000000 --- a/clutter/cogl/build/autotools/as-compiler-flag.m4 +++ /dev/null @@ -1,62 +0,0 @@ -dnl as-compiler-flag.m4 0.1.0 - -dnl autostars m4 macro for detection of compiler flags - -dnl David Schleef - -dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $ - -dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) -dnl Tries to compile with the given CFLAGS. -dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, -dnl and ACTION-IF-NOT-ACCEPTED otherwise. - -AC_DEFUN([AS_COMPILER_FLAG], -[ - AC_MSG_CHECKING([to see if compiler understands $1]) - - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $1" - - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - m4_ifvaln([$2],[$2]) - true - else - m4_ifvaln([$3],[$3]) - true - fi - AC_MSG_RESULT([$flag_ok]) -]) - -dnl AS_COMPILER_FLAGS(VAR, FLAGS) -dnl Tries to compile with the given CFLAGS. - -AC_DEFUN([AS_COMPILER_FLAGS], -[ - list=$2 - flags_supported="" - flags_unsupported="" - AC_MSG_CHECKING([for supported compiler flags]) - for each in $list - do - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $each" - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - flags_supported="$flags_supported $each" - else - flags_unsupported="$flags_unsupported $each" - fi - done - AC_MSG_RESULT([$flags_supported]) - if test "X$flags_unsupported" != X ; then - AC_MSG_WARN([unsupported compiler flags: $flags_unsupported]) - fi - $1="$$1 $flags_supported" -]) - diff --git a/clutter/cogl/build/autotools/as-linguas.m4 b/clutter/cogl/build/autotools/as-linguas.m4 deleted file mode 100644 index 92b28f7..0000000 --- a/clutter/cogl/build/autotools/as-linguas.m4 +++ /dev/null @@ -1,24 +0,0 @@ -# Set ALL_ALL_LINGUAS based on the .po files present. Optional argument is the -# name of the po directory. $podir/LINGUAS.ignore can be used to ignore a -# subset of the po files. - -AC_DEFUN([AS_ALL_LINGUAS], -[ - AC_MSG_CHECKING([for linguas]) - podir="m4_default([$1],[$srcdir/po])" - linguas=`cd $podir && ls *.po 2>/dev/null | awk 'BEGIN { FS="."; ORS=" " } { print $[]1 }'` - if test -f "$podir/LINGUAS.ignore"; then - ALL_LINGUAS=""; - ignore_linguas=`sed -n -e 's/^\s\+\|\s\+$//g' -e '/^#/b' -e '/\S/!b' \ - -e 's/\s\+/\n/g' -e p "$podir/LINGUAS.ignore"`; - for lang in $linguas; do - if ! echo "$ignore_linguas" | grep -q "^${lang}$"; then - ALL_LINGUAS="$ALL_LINGUAS $lang"; - fi; - done; - else - ALL_LINGUAS="$linguas"; - fi; - AC_SUBST([ALL_LINGUAS]) - AC_MSG_RESULT($ALL_LINGUAS) -]) diff --git a/clutter/cogl/build/autotools/introspection.m4 b/clutter/cogl/build/autotools/introspection.m4 deleted file mode 100644 index 589721c..0000000 --- a/clutter/cogl/build/autotools/introspection.m4 +++ /dev/null @@ -1,94 +0,0 @@ -dnl -*- mode: autoconf -*- -dnl Copyright 2009 Johan Dahlin -dnl -dnl This file is free software; the author(s) gives unlimited -dnl permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl - -# serial 1 - -m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL], -[ - AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first - AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first - AC_BEFORE([LT_INIT],[$0])dnl setup libtool first - - dnl enable/disable introspection - m4_if([$2], [require], - [dnl - enable_introspection=yes - ],[dnl - AC_ARG_ENABLE(introspection, - AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]], - [Enable introspection for this build]),, - [enable_introspection=auto]) - ])dnl - - AC_MSG_CHECKING([for gobject-introspection]) - - dnl presence/version checking - AS_CASE([$enable_introspection], - [no], [dnl - found_introspection="no (disabled, use --enable-introspection to enable)" - ],dnl - [yes],[dnl - PKG_CHECK_EXISTS([gobject-introspection-1.0],, - AC_MSG_ERROR([gobject-introspection-1.0 is not installed])) - PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], - found_introspection=yes, - AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME])) - ],dnl - [auto],[dnl - PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no) - ],dnl - [dnl - AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@]) - ])dnl - - AC_MSG_RESULT([$found_introspection]) - - INTROSPECTION_SCANNER= - INTROSPECTION_COMPILER= - INTROSPECTION_GENERATE= - INTROSPECTION_GIRDIR= - INTROSPECTION_TYPELIBDIR= - if test "x$found_introspection" = "xyes"; then - INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` - INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` - INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` - INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` - INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" - INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` - INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` - INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection - fi - AC_SUBST(INTROSPECTION_SCANNER) - AC_SUBST(INTROSPECTION_COMPILER) - AC_SUBST(INTROSPECTION_GENERATE) - AC_SUBST(INTROSPECTION_GIRDIR) - AC_SUBST(INTROSPECTION_TYPELIBDIR) - AC_SUBST(INTROSPECTION_CFLAGS) - AC_SUBST(INTROSPECTION_LIBS) - AC_SUBST(INTROSPECTION_MAKEFILE) - - AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes") -]) - - -dnl Usage: -dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version]) - -AC_DEFUN([GOBJECT_INTROSPECTION_CHECK], -[ - _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1]) -]) - -dnl Usage: -dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version]) - - -AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE], -[ - _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require]) -]) diff --git a/clutter/cogl/cogl/Makefile.am b/clutter/cogl/cogl/Makefile.am deleted file mode 100644 index 8b1d9c9..0000000 --- a/clutter/cogl/cogl/Makefile.am +++ /dev/null @@ -1,419 +0,0 @@ -include $(top_srcdir)/build/autotools/Makefile.am.silent - -# preamble - -NULL = - -SUBDIRS = - -BUILT_SOURCES = - -EXTRA_DIST = -CLEANFILES = -DISTCLEANFILES = - -noinst_LTLIBRARIES = -lib_LTLIBRARIES = - -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(srcdir)/tesselator \ - -I$(srcdir)/winsys \ - -I$(srcdir)/driver/$(COGL_DRIVER) \ - $(NULL) - -if COGL_STANDALONE_BUILD -INCLUDES += \ - -I$(top_srcdir)/clutter/cogl \ - -I$(top_builddir)/clutter/cogl \ - $(NULL) -else -INCLUDES += \ - -I$(top_srcdir)/clutter/cogl \ - -I$(top_builddir)/clutter/cogl \ - $(NULL) -endif - -AM_CPPFLAGS = \ - -DG_DISABLE_SINGLE_INCLUDES \ - -DG_DISABLE_DEPRECATED \ - -DG_LOG_DOMAIN=\"Cogl\" \ - -DCLUTTER_COMPILATION \ - $(NULL) - -AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) - -BUILT_SOURCES += cogl-defines.h -DISTCLEANFILES += cogl-defines.h -EXTRA_DIST += cogl-defines.h.in - -# Note: The cogl-1.0/cogl-gl-1.0 files are essentially for -# compatability only. I'm not really sure who could possibly be using -# them so we may decide to remove them entirely at some point. -pc_files = \ - cogl-1.0.pc \ - cogl-gl-1.0.pc - -if COGL_STANDALONE_BUILD -pc_files += cogl-$(COGL_API_VERSION).pc -endif - -cogl-gl-1.0.pc: cogl-1.0.pc - $(QUIET_GEN)cp -f $< $(@F) - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(pc_files) - -EXTRA_DIST += cogl.pc.in -DISTCLEANFILES += $(pc_files) - -# public headers -cogl_public_h = \ - $(srcdir)/cogl-object.h \ - $(srcdir)/cogl-bitmap.h \ - $(srcdir)/cogl-buffer.h \ - $(srcdir)/cogl-color.h \ - $(srcdir)/cogl-fixed.h \ - $(srcdir)/cogl-material-compat.h \ - $(srcdir)/cogl-pipeline.h \ - $(srcdir)/cogl-vector.h \ - $(srcdir)/cogl-matrix.h \ - $(srcdir)/cogl-offscreen.h \ - $(srcdir)/cogl-primitives.h \ - $(srcdir)/cogl-path.h \ - $(srcdir)/cogl-pixel-array.h \ - $(srcdir)/cogl-shader.h \ - $(srcdir)/cogl-texture.h \ - $(srcdir)/cogl-texture-3d.h \ - $(srcdir)/cogl-types.h \ - $(srcdir)/cogl-vertex-buffer.h \ - $(srcdir)/cogl-index-array.h \ - $(srcdir)/cogl-vertex-array.h \ - $(srcdir)/cogl-indices.h \ - $(srcdir)/cogl-attribute.h \ - $(srcdir)/cogl-primitive.h \ - $(srcdir)/cogl-clip-state.h \ - $(srcdir)/cogl-framebuffer.h \ - $(srcdir)/cogl-clutter.h \ - $(srcdir)/cogl.h \ - $(NULL) - -cogl_experimental_h = \ - $(srcdir)/cogl-renderer.h \ - $(srcdir)/cogl-swap-chain.h \ - $(srcdir)/cogl-onscreen-template.h \ - $(srcdir)/cogl-display.h \ - $(srcdir)/cogl-context.h \ - $(srcdir)/cogl2-path.h \ - $(srcdir)/cogl2-clip-state.h \ - $(NULL) - -# driver sources -cogl_driver_sources = - -if COGL_DRIVER_GL -cogl_driver_sources += \ - $(srcdir)/driver/gl/cogl-feature-functions-gl.h \ - $(srcdir)/driver/gl/cogl-gl.c \ - $(srcdir)/driver/gl/cogl-texture-driver-gl.c \ - $(NULL) -endif - -if COGL_DRIVER_GLES -cogl_driver_sources += \ - $(srcdir)/driver/gles/cogl-feature-functions-gles.h \ - $(srcdir)/driver/gles/cogl-gles.c \ - $(srcdir)/driver/gles/cogl-texture-driver-gles.c \ - $(NULL) - -endif # COGL_DRIVER_GLES - -# winsys sources, common to all backends -cogl_winsys_common_sources = \ - $(srcdir)/winsys/cogl-winsys-private.h \ - $(srcdir)/winsys/cogl-winsys.c \ - $(NULL) - -# tesselator sources -cogl_tesselator_sources = \ - $(srcdir)/tesselator/dict-list.h \ - $(srcdir)/tesselator/dict.c \ - $(srcdir)/tesselator/dict.h \ - $(srcdir)/tesselator/geom.c \ - $(srcdir)/tesselator/geom.h \ - $(srcdir)/tesselator/gluos.h \ - $(srcdir)/tesselator/memalloc.h \ - $(srcdir)/tesselator/mesh.c \ - $(srcdir)/tesselator/mesh.h \ - $(srcdir)/tesselator/normal.c \ - $(srcdir)/tesselator/normal.h \ - $(srcdir)/tesselator/priorityq-heap.h \ - $(srcdir)/tesselator/priorityq-sort.h \ - $(srcdir)/tesselator/priorityq.c \ - $(srcdir)/tesselator/priorityq.h \ - $(srcdir)/tesselator/render.c \ - $(srcdir)/tesselator/render.h \ - $(srcdir)/tesselator/sweep.c \ - $(srcdir)/tesselator/sweep.h \ - $(srcdir)/tesselator/tess.c \ - $(srcdir)/tesselator/tess.h \ - $(srcdir)/tesselator/tesselator.h \ - $(srcdir)/tesselator/tessmono.c \ - $(srcdir)/tesselator/tessmono.h \ - $(srcdir)/tesselator/GL/glu.h \ - $(NULL) - -EXTRA_DIST += \ - $(srcdir)/tesselator/README \ - $(srcdir)/tesselator/priorityq-heap.c \ - $(NULL) - -# sources -cogl_sources_c = \ - $(cogl_driver_sources) \ - $(cogl_winsys_common_sources) \ - $(cogl_tesselator_sources) \ - $(srcdir)/cogl-private.h \ - $(srcdir)/cogl-debug.h \ - $(srcdir)/cogl-debug-options.h \ - $(srcdir)/cogl-handle.h \ - $(srcdir)/cogl-context-private.h \ - $(srcdir)/cogl-context.c \ - $(srcdir)/cogl-renderer-private.h \ - $(srcdir)/cogl-renderer.h \ - $(srcdir)/cogl-renderer.c \ - $(srcdir)/cogl-swap-chain-private.h \ - $(srcdir)/cogl-swap-chain.h \ - $(srcdir)/cogl-swap-chain.c \ - $(srcdir)/cogl-onscreen-template-private.h \ - $(srcdir)/cogl-onscreen-template.h \ - $(srcdir)/cogl-onscreen-template.c \ - $(srcdir)/cogl-display-private.h \ - $(srcdir)/cogl-display.h \ - $(srcdir)/cogl-display.c \ - $(srcdir)/cogl-internal.h \ - $(srcdir)/cogl.c \ - $(srcdir)/cogl-object-private.h \ - $(srcdir)/cogl-object.h \ - $(srcdir)/cogl-object.c \ - $(srcdir)/cogl-util.h \ - $(srcdir)/cogl-util.c \ - $(srcdir)/cogl-bitmap-private.h \ - $(srcdir)/cogl-bitmap.c \ - $(srcdir)/cogl-bitmap-fallback.c \ - $(srcdir)/cogl-primitives-private.h \ - $(srcdir)/cogl-primitives.h \ - $(srcdir)/cogl-primitives.c \ - $(srcdir)/cogl-path-private.h \ - $(srcdir)/cogl-path.h \ - $(srcdir)/cogl-path.c \ - $(srcdir)/cogl2-path.h \ - $(srcdir)/cogl2-path.c \ - $(srcdir)/cogl-bitmap-pixbuf.c \ - $(srcdir)/cogl-clip-stack.h \ - $(srcdir)/cogl-clip-stack.c \ - $(srcdir)/cogl-clip-state-private.h \ - $(srcdir)/cogl-clip-state.h \ - $(srcdir)/cogl-clip-state.c \ - $(srcdir)/cogl2-clip-state.h \ - $(srcdir)/cogl2-clip-state.c \ - $(srcdir)/cogl-feature-private.h \ - $(srcdir)/cogl-feature-private.c \ - $(srcdir)/cogl-fixed.c \ - $(srcdir)/cogl-color-private.h \ - $(srcdir)/cogl-color.c \ - $(srcdir)/cogl-buffer-private.h \ - $(srcdir)/cogl-buffer.c \ - $(srcdir)/cogl-pixel-array-private.h \ - $(srcdir)/cogl-pixel-array.c \ - $(srcdir)/cogl-vertex-buffer-private.h \ - $(srcdir)/cogl-vertex-buffer.c \ - $(srcdir)/cogl-index-array-private.h \ - $(srcdir)/cogl-index-array.c \ - $(srcdir)/cogl-vertex-array-private.h \ - $(srcdir)/cogl-vertex-array.c \ - $(srcdir)/cogl-indices-private.h \ - $(srcdir)/cogl-indices.c \ - $(srcdir)/cogl-attribute-private.h \ - $(srcdir)/cogl-attribute.c \ - $(srcdir)/cogl-primitive-private.h \ - $(srcdir)/cogl-primitive.c \ - $(srcdir)/cogl-matrix.c \ - $(srcdir)/cogl-vector.c \ - $(srcdir)/cogl-matrix-private.h \ - $(srcdir)/cogl-matrix-stack.c \ - $(srcdir)/cogl-matrix-stack.h \ - $(srcdir)/cogl-pipeline.c \ - $(srcdir)/cogl-pipeline-private.h \ - $(srcdir)/cogl-pipeline-opengl.c \ - $(srcdir)/cogl-pipeline-opengl-private.h \ - $(srcdir)/cogl-pipeline-fragend-glsl.c \ - $(srcdir)/cogl-pipeline-fragend-glsl-private.h \ - $(srcdir)/cogl-pipeline-fragend-arbfp.c \ - $(srcdir)/cogl-pipeline-fragend-arbfp-private.h \ - $(srcdir)/cogl-pipeline-fragend-fixed.c \ - $(srcdir)/cogl-pipeline-fragend-fixed-private.h \ - $(srcdir)/cogl-pipeline-vertend-glsl.c \ - $(srcdir)/cogl-pipeline-vertend-glsl-private.h \ - $(srcdir)/cogl-pipeline-vertend-fixed.c \ - $(srcdir)/cogl-pipeline-vertend-fixed-private.h \ - $(srcdir)/cogl-pipeline-progend-glsl.c \ - $(srcdir)/cogl-pipeline-progend-glsl-private.h \ - $(srcdir)/cogl-material-compat.c \ - $(srcdir)/cogl-program.c \ - $(srcdir)/cogl-program-private.h \ - $(srcdir)/cogl-blend-string.c \ - $(srcdir)/cogl-blend-string.h \ - $(srcdir)/cogl-debug.c \ - $(srcdir)/cogl-sub-texture-private.h \ - $(srcdir)/cogl-texture-private.h \ - $(srcdir)/cogl-texture-2d-private.h \ - $(srcdir)/cogl-texture-2d-sliced-private.h \ - $(srcdir)/cogl-texture-3d-private.h \ - $(srcdir)/cogl-texture-driver.h \ - $(srcdir)/cogl-sub-texture.c \ - $(srcdir)/cogl-texture.c \ - $(srcdir)/cogl-texture-2d.c \ - $(srcdir)/cogl-texture-2d-sliced.c \ - $(srcdir)/cogl-texture-3d.c \ - $(srcdir)/cogl-texture-rectangle-private.h \ - $(srcdir)/cogl-texture-rectangle.c \ - $(srcdir)/cogl-rectangle-map.h \ - $(srcdir)/cogl-rectangle-map.c \ - $(srcdir)/cogl-atlas.h \ - $(srcdir)/cogl-atlas.c \ - $(srcdir)/cogl-atlas-texture-private.h \ - $(srcdir)/cogl-atlas-texture.c \ - $(srcdir)/cogl-blit.h \ - $(srcdir)/cogl-blit.c \ - $(srcdir)/cogl-spans.h \ - $(srcdir)/cogl-spans.c \ - $(srcdir)/cogl-journal-private.h \ - $(srcdir)/cogl-journal.c \ - $(srcdir)/cogl-framebuffer-private.h \ - $(srcdir)/cogl-framebuffer.c \ - $(srcdir)/cogl-matrix-mesa.h \ - $(srcdir)/cogl-matrix-mesa.c \ - $(srcdir)/cogl-profile.h \ - $(srcdir)/cogl-profile.c \ - $(srcdir)/cogl-flags.h \ - $(srcdir)/cogl-bitmask.h \ - $(srcdir)/cogl-bitmask.c \ - $(srcdir)/cogl-shader-boilerplate.h \ - $(srcdir)/cogl-shader-private.h \ - $(srcdir)/cogl-shader.c \ - $(srcdir)/cogl-gtype-private.h \ - $(srcdir)/cogl-point-in-poly-private.h \ - $(srcdir)/cogl-point-in-poly.c \ - $(srcdir)/cogl-clutter.c \ - $(NULL) - -if SUPPORT_XLIB -cogl_experimental_h += \ - $(srcdir)/winsys/cogl-texture-pixmap-x11.h \ - $(srcdir)/cogl-xlib.h - -cogl_sources_c += \ - $(srcdir)/cogl-renderer-x11-private.h \ - $(srcdir)/cogl-renderer-xlib-private.h \ - $(srcdir)/cogl-renderer-xlib.c \ - $(srcdir)/cogl-display-xlib-private.h \ - $(srcdir)/cogl-xlib.c \ - $(srcdir)/winsys/cogl-texture-pixmap-x11.c \ - $(srcdir)/winsys/cogl-texture-pixmap-x11-private.h -endif -if SUPPORT_GLX -cogl_sources_c += \ - $(srcdir)/cogl-renderer-glx-private.h \ - $(srcdir)/cogl-display-glx-private.h \ - $(srcdir)/winsys/cogl-winsys-glx-feature-functions.h \ - $(srcdir)/winsys/cogl-winsys-glx.c -endif -if SUPPORT_EGL_PLATFORM_POWERVR_X11 -cogl_sources_c += \ - $(srcdir)/winsys/cogl-winsys-egl.c -endif -if SUPPORT_EGL_PLATFORM_POWERVR_NULL -cogl_sources_c += \ - $(srcdir)/winsys/cogl-winsys-egl.c -endif -if SUPPORT_EGL_PLATFORM_GDL -cogl_sources_c += \ - $(srcdir)/winsys/cogl-winsys-egl.c -endif -if SUPPORT_STUB -cogl_sources_c += \ - $(srcdir)/winsys/cogl-winsys-stub.c -endif - -EXTRA_DIST += stb_image.c - -# glib-mkenums rules -glib_enum_h = cogl-enum-types.h -glib_enum_c = cogl-enum-types.c -glib_enum_headers = $(cogl_public_h) -include $(top_srcdir)/build/autotools/Makefile.am.enums - -if COGL_STANDALONE_BUILD -lib_LTLIBRARIES += libcogl.la -else -noinst_LTLIBRARIES += libcogl.la -endif - -libcogl_la_LIBADD = -lm $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) -if SUPPORT_GLX -libcogl_la_LIBADD += -ldl -endif -if COGL_STANDALONE_BUILD -# XXX: The aim is to eventually get rid of all private API exports -# for coglpango. -libcogl_la_LDFLAGS = \ - -no-undefined \ - -version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ \ - -export-dynamic \ - -export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly).*" -endif - -libcogl_la_SOURCES = $(cogl_sources_c) -nodist_libcogl_la_SOURCES = $(BUILT_SOURCES) - -# Cogl installed headers -cogl_headers = \ - $(cogl_public_h) \ - $(srcdir)/cogl-deprecated.h \ - $(NULL) - -if COGL_STANDALONE_BUILD -coglincludedir = $(includedir)/cogl/cogl -coglinclude_HEADERS = $(cogl_headers) $(cogl_experimental_h) -nodist_coglinclude_HEADERS = cogl-defines.h cogl-enum-types.h -else -coglincludedir = $(includedir)/clutter-@CLUTTER_API_VERSION@/cogl -coglinclude_HEADERS = $(cogl_headers) $(cogl_experimental_h) -nodist_coglinclude_HEADERS = cogl-defines.h cogl-enum-types.h -endif - --include $(INTROSPECTION_MAKEFILE) - -INTROSPECTION_GIRS = - -if HAVE_INTROSPECTION -Cogl-1.0.gir: libcogl.la Makefile - -Cogl_1_0_gir_NAMESPACE = Cogl -Cogl_1_0_gir_VERSION = 1.0 -Cogl_1_0_gir_LIBS = libcogl.la -Cogl_1_0_gir_FILES = $(cogl_headers) cogl-enum-types.h -Cogl_1_0_gir_CFLAGS = $(INCLUDES) $(AM_CPPFLAGS) -Cogl_1_0_gir_INCLUDES = GL-1.0 GObject-2.0 -Cogl_1_0_gir_EXPORT_PACKAGES = cogl-1.0 -Cogl_1_0_gir_SCANNERFLAGS = --warn-all --c-include='cogl/cogl.h' - -INTROSPECTION_GIRS += Cogl-1.0.gir - -girdir = $(datadir)/gir-1.0 -gir_DATA = $(INTROSPECTION_GIRS) - -CLEANFILES += $(INTROSPECTION_GIRS) -endif diff --git a/clutter/cogl/cogl/cogl-1.0-clutter.pc.in b/clutter/cogl/cogl/cogl-1.0-clutter.pc.in deleted file mode 100644 index f95a217..0000000 --- a/clutter/cogl/cogl/cogl-1.0-clutter.pc.in +++ /dev/null @@ -1,17 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -apiversion=1.0 -requires=@COGL_PKG_REQUIRES@ -backend=none #only kept for backward compatability -winsys=none -cogl=none #only kept for backward compatability -driver=none - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @COGL_1_VERSION@ -Libs: -L${libdir} -lcogl -lcoglpango -Cflags: -I${includedir}/clutter-${apiversion} -Requires: ${requires} diff --git a/clutter/cogl/cogl/cogl-1.0.pc.in b/clutter/cogl/cogl/cogl-1.0.pc.in deleted file mode 100644 index 6e34bf5..0000000 --- a/clutter/cogl/cogl/cogl-1.0.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -apiversion=1.0 -requires=@COGL_PKG_REQUIRES@ - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @COGL_1_VERSION@ -Libs: -L${libdir} -lcogl -lcoglpango -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/clutter/cogl/cogl/cogl-atlas-texture-private.h b/clutter/cogl/cogl/cogl-atlas-texture-private.h deleted file mode 100644 index b7f7b03..0000000 --- a/clutter/cogl/cogl/cogl-atlas-texture-private.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_ATLAS_TEXTURE_H -#define __COGL_ATLAS_TEXTURE_H - -#include "cogl-handle.h" -#include "cogl-texture-private.h" -#include "cogl-rectangle-map.h" -#include "cogl-atlas.h" - -#define COGL_ATLAS_TEXTURE(tex) ((CoglAtlasTexture *) tex) - -typedef struct _CoglAtlasTexture CoglAtlasTexture; - -struct _CoglAtlasTexture -{ - CoglTexture _parent; - - /* The format that the texture is in. This isn't necessarily the - same format as the atlas texture because we can store - pre-multiplied and non-pre-multiplied textures together */ - CoglPixelFormat format; - - /* The rectangle that was used to add this texture to the - atlas. This includes the 1-pixel border */ - CoglRectangleMapEntry rectangle; - - /* The atlas that this texture is in. If the texture is no longer in - an atlas then this will be NULL. A reference is taken on the - atlas by the texture (but not vice versa so there is no cycle) */ - CoglAtlas *atlas; - - /* A CoglSubTexture representing the region for easy rendering */ - CoglHandle sub_texture; -}; - -GQuark -_cogl_handle_atlas_texture_get_type (void); - -CoglHandle -_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -CoglHandle -_cogl_atlas_texture_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -void -_cogl_atlas_texture_add_reorganize_callback (GHookFunc callback, - void *user_data); - -void -_cogl_atlas_texture_remove_reorganize_callback (GHookFunc callback, - void *user_data); - -#endif /* __COGL_ATLAS_TEXTURE_H */ diff --git a/clutter/cogl/cogl/cogl-atlas-texture.c b/clutter/cogl/cogl/cogl-atlas-texture.c deleted file mode 100644 index 3b87d4c..0000000 --- a/clutter/cogl/cogl/cogl-atlas-texture.c +++ /dev/null @@ -1,806 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009,2010,2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-atlas-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-sub-texture-private.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-texture-driver.h" -#include "cogl-rectangle-map.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-atlas.h" - -#include - -static void _cogl_atlas_texture_free (CoglAtlasTexture *sub_tex); - -COGL_TEXTURE_INTERNAL_DEFINE (AtlasTexture, atlas_texture); - -static const CoglTextureVtable cogl_atlas_texture_vtable; - -static CoglHandle -_cogl_atlas_texture_create_sub_texture (CoglHandle full_texture, - const CoglRectangleMapEntry *rectangle) -{ - /* Create a subtexture for the given rectangle not including the - 1-pixel border */ - return _cogl_sub_texture_new (full_texture, - rectangle->x + 1, - rectangle->y + 1, - rectangle->width - 2, - rectangle->height - 2); -} - -static void -_cogl_atlas_texture_update_position_cb (gpointer user_data, - CoglHandle new_texture, - const CoglRectangleMapEntry *rectangle) -{ - CoglAtlasTexture *atlas_tex = user_data; - - /* Update the sub texture */ - if (atlas_tex->sub_texture) - cogl_handle_unref (atlas_tex->sub_texture); - atlas_tex->sub_texture = - _cogl_atlas_texture_create_sub_texture (new_texture, rectangle); - - /* Update the position */ - atlas_tex->rectangle = *rectangle; -} - -static void -_cogl_atlas_texture_pre_reorganize_foreach_cb - (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data) -{ - CoglAtlasTexture *atlas_tex = rectangle_data; - - /* Keep a reference to the texture because we don't want it to be - destroyed during the reorganization */ - cogl_handle_ref (atlas_tex); - - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (atlas_tex)); -} - -static void -_cogl_atlas_texture_pre_reorganize_cb (void *data) -{ - CoglAtlas *atlas = data; - - /* We don't know if any journal entries currently depend on OpenGL - * texture coordinates that would be invalidated by reorganizing - * this atlas so we flush all journals before migrating. - * - * We are assuming that texture atlas migration never happens - * during a flush so we don't have to consider recursion here. - */ - cogl_flush (); - - if (atlas->map) - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_texture_pre_reorganize_foreach_cb, - NULL); -} - -typedef struct -{ - CoglAtlasTexture **textures; - /* Number of textures found so far */ - unsigned int n_textures; -} CoglAtlasTextureGetRectanglesData; - -static void -_cogl_atlas_texture_get_rectangles_cb (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data) -{ - CoglAtlasTextureGetRectanglesData *data = user_data; - - data->textures[data->n_textures++] = rectangle_data; -} - -static void -_cogl_atlas_texture_post_reorganize_cb (void *user_data) -{ - CoglAtlas *atlas = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (atlas->map) - { - CoglAtlasTextureGetRectanglesData data; - unsigned int i; - - data.textures = g_new (CoglAtlasTexture *, - _cogl_rectangle_map_get_n_rectangles (atlas->map)); - data.n_textures = 0; - - /* We need to remove all of the references that we took during - the preorganize callback. We have to get a separate array of - the textures because CoglRectangleMap doesn't support - removing rectangles during iteration */ - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_texture_get_rectangles_cb, - &data); - - for (i = 0; i < data.n_textures; i++) - { - /* Ignore textures that don't have an atlas yet. This will - happen when a new texture is added because we allocate - the structure for the texture so that it can get stored - in the atlas but it isn't a valid object yet */ - if (data.textures[i]->atlas) - cogl_object_unref (data.textures[i]); - } - - g_free (data.textures); - } - - /* Notify any listeners that an atlas has changed */ - g_hook_list_invoke (&ctx->atlas_reorganize_callbacks, FALSE); -} - -static void -_cogl_atlas_texture_atlas_destroyed_cb (void *user_data) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Remove the atlas from the global list */ - ctx->atlases = g_slist_remove (ctx->atlases, user_data); -} - -static CoglAtlas * -_cogl_atlas_texture_create_atlas (void) -{ - static CoglUserDataKey atlas_private_key; - - CoglAtlas *atlas; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - atlas = _cogl_atlas_new (COGL_PIXEL_FORMAT_RGBA_8888, - 0, - _cogl_atlas_texture_update_position_cb); - - _cogl_atlas_add_reorganize_callback (atlas, - _cogl_atlas_texture_pre_reorganize_cb, - _cogl_atlas_texture_post_reorganize_cb, - atlas); - - ctx->atlases = g_slist_prepend (ctx->atlases, atlas); - - /* Set some data on the atlas so we can get notification when it is - destroyed in order to remove it from the list. ctx->atlases - effectively holds a weak reference. We don't need a strong - reference because the atlas textures take a reference on the - atlas so it will stay alive */ - cogl_object_set_user_data (COGL_OBJECT (atlas), &atlas_private_key, atlas, - _cogl_atlas_texture_atlas_destroyed_cb); - - return atlas; -} - -static void -_cogl_atlas_texture_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_foreach_sub_texture_in_region (atlas_tex->sub_texture, - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - callback, - user_data); -} - -static void -_cogl_atlas_texture_set_wrap_mode_parameters (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_set_wrap_mode_parameters (atlas_tex->sub_texture, - wrap_mode_s, - wrap_mode_t, - wrap_mode_p); -} - -static void -_cogl_atlas_texture_remove_from_atlas (CoglAtlasTexture *atlas_tex) -{ - if (atlas_tex->atlas) - { - _cogl_atlas_remove (atlas_tex->atlas, - &atlas_tex->rectangle); - - cogl_object_unref (atlas_tex->atlas); - atlas_tex->atlas = NULL; - } -} - -static void -_cogl_atlas_texture_free (CoglAtlasTexture *atlas_tex) -{ - _cogl_atlas_texture_remove_from_atlas (atlas_tex); - - cogl_handle_unref (atlas_tex->sub_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (atlas_tex)); -} - -static int -_cogl_atlas_texture_get_max_waste (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_max_waste (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_is_sliced (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_is_sliced (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_can_hardware_repeat (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_can_hardware_repeat (atlas_tex->sub_texture); -} - -static void -_cogl_atlas_texture_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_transform_coords_to_gl (atlas_tex->sub_texture, s, t); -} - -static CoglTransformResult -_cogl_atlas_texture_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_transform_quad_coords_to_gl (atlas_tex->sub_texture, - coords); -} - -static gboolean -_cogl_atlas_texture_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_gl_texture (atlas_tex->sub_texture, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_atlas_texture_set_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_set_filters (atlas_tex->sub_texture, min_filter, mag_filter); -} - -static void -_cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex) -{ - /* Make sure this texture is not in the atlas */ - if (atlas_tex->atlas) - { - CoglHandle sub_texture; - - COGL_NOTE (ATLAS, "Migrating texture out of the atlas"); - - /* We don't know if any journal entries currently depend on - * OpenGL texture coordinates that would be invalidated by - * migrating textures in this atlas so we flush all journals - * before migrating. - * - * We are assuming that texture atlas migration never happens - * during a flush so we don't have to consider recursion here. - */ - cogl_flush (); - - sub_texture = - _cogl_atlas_copy_rectangle (atlas_tex->atlas, - atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y + 1, - atlas_tex->rectangle.width - 2, - atlas_tex->rectangle.height - 2, - COGL_TEXTURE_NO_ATLAS, - atlas_tex->format); - - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (atlas_tex); - - /* We need to unref the sub texture after doing the copy because - the copy can involve rendering which might cause the texture - to be used if it is used from a layer that is left in a - texture unit */ - cogl_handle_unref (atlas_tex->sub_texture); - atlas_tex->sub_texture = sub_texture; - - _cogl_atlas_texture_remove_from_atlas (atlas_tex); - } -} - -static void -_cogl_atlas_texture_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP)) - /* Mipmaps do not work well with the current atlas so instead - we'll just migrate the texture out and use a regular texture */ - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* Forward on to the sub texture */ - _cogl_texture_pre_paint (atlas_tex->sub_texture, flags); -} - -static void -_cogl_atlas_texture_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Sub textures can't support non-quad rendering so we'll just - migrate the texture out */ - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* Forward on to the sub texture */ - _cogl_texture_ensure_non_quad_rendering (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - CoglAtlas *atlas = atlas_tex->atlas; - - /* Copy the central data */ - if (!_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - dst_x + atlas_tex->rectangle.x + 1, - dst_y + atlas_tex->rectangle.y + 1, - dst_width, - dst_height, - bmp)) - return FALSE; - - /* Update the left edge pixels */ - if (dst_x == 0 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - atlas_tex->rectangle.x, - dst_y + atlas_tex->rectangle.y + 1, - 1, dst_height, - bmp)) - return FALSE; - /* Update the right edge pixels */ - if (dst_x + dst_width == atlas_tex->rectangle.width - 2 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x + dst_width - 1, src_y, - atlas_tex->rectangle.x + - atlas_tex->rectangle.width - 1, - dst_y + atlas_tex->rectangle.y + 1, - 1, dst_height, - bmp)) - return FALSE; - /* Update the top edge pixels */ - if (dst_y == 0 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - dst_x + atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y, - dst_width, 1, - bmp)) - return FALSE; - /* Update the bottom edge pixels */ - if (dst_y + dst_height == atlas_tex->rectangle.height - 2 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y + dst_height - 1, - dst_x + atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y + - atlas_tex->rectangle.height - 1, - dst_width, 1, - bmp)) - return FALSE; - - return TRUE; -} - -static gboolean -_cogl_atlas_texture_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* If the texture is in the atlas then we need to copy the edge - pixels to the border */ - if (atlas_tex->atlas) - { - gboolean ret; - - bmp = _cogl_bitmap_new_shared (bmp, - _cogl_bitmap_get_format (bmp) & - ~COGL_PREMULT_BIT, - _cogl_bitmap_get_width (bmp), - _cogl_bitmap_get_height (bmp), - _cogl_bitmap_get_rowstride (bmp)); - - /* Upload the data ignoring the premult bit */ - ret = _cogl_atlas_texture_set_region_with_border (atlas_tex, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - bmp); - - cogl_object_unref (bmp); - - return ret; - } - else - /* Otherwise we can just forward on to the sub texture */ - return _cogl_texture_set_region_from_bitmap (atlas_tex->sub_texture, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - bmp); -} - -static CoglPixelFormat -_cogl_atlas_texture_get_format (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* We don't want to forward this on the sub-texture because it isn't - the necessarily the same format. This will happen if the texture - isn't pre-multiplied */ - return atlas_tex->format; -} - -static GLenum -_cogl_atlas_texture_get_gl_format (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_get_gl_format (atlas_tex->sub_texture); -} - -static int -_cogl_atlas_texture_get_width (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_width (atlas_tex->sub_texture); -} - -static int -_cogl_atlas_texture_get_height (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_height (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_can_use_format (CoglPixelFormat format) -{ - /* We don't care about the ordering or the premult status and we can - accept RGBA or RGB textures. Although we could also accept - luminance and alpha only textures or 16-bit formats it seems that - if the application is explicitly using these formats then they've - got a reason to want the lower memory requirements so putting - them in the atlas might not be a good idea */ - format &= ~(COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT); - return (format == COGL_PIXEL_FORMAT_RGB_888 || - format == COGL_PIXEL_FORMAT_RGBA_8888); -} - -CoglHandle -_cogl_atlas_texture_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglAtlasTexture *atlas_tex; - CoglAtlas *atlas; - GSList *l; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - /* Don't put textures in the atlas if the user has explicitly - requested to disable it */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS))) - return COGL_INVALID_HANDLE; - - /* We can't put the texture in the atlas if there are any special - flags. This precludes textures with COGL_TEXTURE_NO_ATLAS and - COGL_TEXTURE_NO_SLICING from being atlased */ - if (flags) - return COGL_INVALID_HANDLE; - - /* We can't atlas zero-sized textures because it breaks the atlas - data structure */ - if (width < 1 || height < 1) - return COGL_INVALID_HANDLE; - - /* If we can't use FBOs then it will be too slow to migrate textures - and we shouldn't use the atlas */ - if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) - return COGL_INVALID_HANDLE; - - COGL_NOTE (ATLAS, "Adding texture of size %ix%i", width, height); - - /* If the texture is in a strange format then we won't use it */ - if (!_cogl_atlas_texture_can_use_format (internal_format)) - { - COGL_NOTE (ATLAS, "Texture can not be added because the " - "format is unsupported"); - - return COGL_INVALID_HANDLE; - } - - /* We need to allocate the texture now because we need the pointer - to set as the data for the rectangle in the atlas */ - atlas_tex = g_new (CoglAtlasTexture, 1); - /* Mark it as having no atlas so we don't try to unref it in - _cogl_atlas_texture_post_reorganize_cb */ - atlas_tex->atlas = NULL; - - _cogl_texture_init (COGL_TEXTURE (atlas_tex), - &cogl_atlas_texture_vtable); - - atlas_tex->sub_texture = COGL_INVALID_HANDLE; - - /* Look for an existing atlas that can hold the texture */ - for (l = ctx->atlases; l; l = l->next) - /* Try to make some space in the atlas for the texture */ - if (_cogl_atlas_reserve_space (atlas = l->data, - /* Add two pixels for the border */ - width + 2, height + 2, - atlas_tex)) - { - cogl_object_ref (atlas); - break; - } - - /* If we couldn't find a suitable atlas then start another */ - if (l == NULL) - { - atlas = _cogl_atlas_texture_create_atlas (); - COGL_NOTE (ATLAS, "Created new atlas for textures: %p", atlas); - if (!_cogl_atlas_reserve_space (atlas, - /* Add two pixels for the border */ - width + 2, height + 2, - atlas_tex)) - { - /* Ok, this means we really can't add it to the atlas */ - cogl_object_unref (atlas); - g_free (atlas_tex); - return COGL_INVALID_HANDLE; - } - } - - atlas_tex->format = internal_format; - atlas_tex->atlas = atlas; - - return _cogl_atlas_texture_handle_new (atlas_tex); -} - -CoglHandle -_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglHandle atlas_tex_handle; - CoglAtlasTexture *atlas_tex; - CoglBitmap *dst_bmp; - CoglBitmap *override_bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - int bmp_width; - int bmp_height; - CoglPixelFormat bmp_format; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - g_return_val_if_fail (cogl_is_bitmap (bmp), COGL_INVALID_HANDLE); - - bmp_width = _cogl_bitmap_get_width (bmp); - bmp_height = _cogl_bitmap_get_height (bmp); - bmp_format = _cogl_bitmap_get_format (bmp); - - internal_format = _cogl_texture_determine_internal_format (bmp_format, - internal_format); - - atlas_tex_handle = _cogl_atlas_texture_new_with_size (bmp_width, bmp_height, - flags, internal_format); - - if (atlas_tex_handle == COGL_INVALID_HANDLE) - return COGL_INVALID_HANDLE; - - atlas_tex = atlas_tex_handle; - - dst_bmp = _cogl_texture_prepare_for_upload (bmp, - internal_format, - &internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - if (dst_bmp == NULL) - { - cogl_handle_unref (atlas_tex_handle); - return COGL_INVALID_HANDLE; - } - - /* Make another bitmap so that we can override the format */ - override_bmp = _cogl_bitmap_new_shared (dst_bmp, - _cogl_bitmap_get_format (dst_bmp) & - ~COGL_PREMULT_BIT, - _cogl_bitmap_get_width (dst_bmp), - _cogl_bitmap_get_height (dst_bmp), - _cogl_bitmap_get_rowstride (dst_bmp)); - cogl_object_unref (dst_bmp); - - /* Defer to set_region so that we can share the code for copying the - edge pixels to the border. We don't want to pass the actual - format of the converted texture because otherwise it will get - unpremultiplied. */ - _cogl_atlas_texture_set_region_with_border (atlas_tex, - 0, /* src_x */ - 0, /* src_y */ - 0, /* dst_x */ - 0, /* dst_y */ - bmp_width, /* dst_width */ - bmp_height, /* dst_height */ - override_bmp); - - cogl_object_unref (override_bmp); - - return atlas_tex_handle; -} - -void -_cogl_atlas_texture_add_reorganize_callback (GHookFunc callback, - void *user_data) -{ - GHook *hook; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - hook = g_hook_alloc (&ctx->atlas_reorganize_callbacks); - hook->func = callback; - hook->data = user_data; - g_hook_prepend (&ctx->atlas_reorganize_callbacks, hook); -} - -void -_cogl_atlas_texture_remove_reorganize_callback (GHookFunc callback, - void *user_data) -{ - GHook *hook; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - hook = g_hook_find_func_data (&ctx->atlas_reorganize_callbacks, - FALSE, - callback, - user_data); - - if (hook) - g_hook_destroy_link (&ctx->atlas_reorganize_callbacks, hook); -} - -static const CoglTextureVtable -cogl_atlas_texture_vtable = - { - _cogl_atlas_texture_set_region, - NULL, /* get_data */ - _cogl_atlas_texture_foreach_sub_texture_in_region, - _cogl_atlas_texture_get_max_waste, - _cogl_atlas_texture_is_sliced, - _cogl_atlas_texture_can_hardware_repeat, - _cogl_atlas_texture_transform_coords_to_gl, - _cogl_atlas_texture_transform_quad_coords_to_gl, - _cogl_atlas_texture_get_gl_texture, - _cogl_atlas_texture_set_filters, - _cogl_atlas_texture_pre_paint, - _cogl_atlas_texture_ensure_non_quad_rendering, - _cogl_atlas_texture_set_wrap_mode_parameters, - _cogl_atlas_texture_get_format, - _cogl_atlas_texture_get_gl_format, - _cogl_atlas_texture_get_width, - _cogl_atlas_texture_get_height, - NULL /* is_foreign */ - }; diff --git a/clutter/cogl/cogl/cogl-atlas.c b/clutter/cogl/cogl/cogl-atlas.c deleted file mode 100644 index 9a75a60..0000000 --- a/clutter/cogl/cogl/cogl-atlas.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-atlas.h" -#include "cogl-rectangle-map.h" -#include "cogl-context-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-driver.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-debug.h" -#include "cogl-framebuffer-private.h" -#include "cogl-blit.h" - -#include - -static void _cogl_atlas_free (CoglAtlas *atlas); - -COGL_OBJECT_INTERNAL_DEFINE (Atlas, atlas); - -CoglAtlas * -_cogl_atlas_new (CoglPixelFormat texture_format, - CoglAtlasFlags flags, - CoglAtlasUpdatePositionCallback update_position_cb) -{ - CoglAtlas *atlas = g_new (CoglAtlas, 1); - - atlas->update_position_cb = update_position_cb; - atlas->map = NULL; - atlas->texture = NULL; - atlas->flags = flags; - atlas->texture_format = texture_format; - g_hook_list_init (&atlas->pre_reorganize_callbacks, sizeof (GHook)); - g_hook_list_init (&atlas->post_reorganize_callbacks, sizeof (GHook)); - - return _cogl_atlas_object_new (atlas); -} - -static void -_cogl_atlas_free (CoglAtlas *atlas) -{ - COGL_NOTE (ATLAS, "%p: Atlas destroyed", atlas); - - if (atlas->texture) - cogl_handle_unref (atlas->texture); - if (atlas->map) - _cogl_rectangle_map_free (atlas->map); - - g_hook_list_clear (&atlas->pre_reorganize_callbacks); - g_hook_list_clear (&atlas->post_reorganize_callbacks); - - g_free (atlas); -} - -typedef struct _CoglAtlasRepositionData -{ - /* The current user data for this texture */ - void *user_data; - /* The old and new positions of the texture */ - CoglRectangleMapEntry old_position; - CoglRectangleMapEntry new_position; -} CoglAtlasRepositionData; - -static void -_cogl_atlas_migrate (CoglAtlas *atlas, - unsigned int n_textures, - CoglAtlasRepositionData *textures, - CoglHandle old_texture, - CoglHandle new_texture, - void *skip_user_data) -{ - unsigned int i; - CoglBlitData blit_data; - - /* If the 'disable migrate' flag is set then we won't actually copy - the textures to their new location. Instead we'll just invoke the - callback to update the position */ - if ((atlas->flags & COGL_ATLAS_DISABLE_MIGRATION)) - for (i = 0; i < n_textures; i++) - /* Update the texture position */ - atlas->update_position_cb (textures[i].user_data, - new_texture, - &textures[i].new_position); - else - { - _cogl_blit_begin (&blit_data, new_texture, old_texture); - - for (i = 0; i < n_textures; i++) - { - /* Skip the texture that is being added because it doesn't contain - any data yet */ - if (textures[i].user_data != skip_user_data) - _cogl_blit (&blit_data, - textures[i].old_position.x, - textures[i].old_position.y, - textures[i].new_position.x, - textures[i].new_position.y, - textures[i].new_position.width, - textures[i].new_position.height); - - /* Update the texture position */ - atlas->update_position_cb (textures[i].user_data, - new_texture, - &textures[i].new_position); - } - - _cogl_blit_end (&blit_data); - } -} - -typedef struct _CoglAtlasGetRectanglesData -{ - CoglAtlasRepositionData *textures; - /* Number of textures found so far */ - unsigned int n_textures; -} CoglAtlasGetRectanglesData; - -static void -_cogl_atlas_get_rectangles_cb (const CoglRectangleMapEntry *rectangle, - void *rect_data, - void *user_data) -{ - CoglAtlasGetRectanglesData *data = user_data; - - data->textures[data->n_textures].old_position = *rectangle; - data->textures[data->n_textures++].user_data = rect_data; -} - -static void -_cogl_atlas_get_next_size (unsigned int *map_width, - unsigned int *map_height) -{ - /* Double the size of the texture by increasing whichever dimension - is smaller */ - if (*map_width < *map_height) - *map_width <<= 1; - else - *map_height <<= 1; -} - -static void -_cogl_atlas_get_initial_size (CoglPixelFormat format, - unsigned int *map_width, - unsigned int *map_height) -{ - unsigned int size; - GLenum gl_intformat; - GLenum gl_type; - - _cogl_pixel_format_to_gl (format, - &gl_intformat, - NULL, /* gl_format */ - &gl_type); - - /* At least on Intel hardware, the texture size will be rounded up - to at least 1MB so we might as well try to aim for that as an - initial minimum size. If the format is only 1 byte per pixel we - can use 1024x1024, otherwise we'll assume it will take 4 bytes - per pixel and use 512x512. */ - if (_cogl_get_format_bpp (format) == 1) - size = 1024; - else - size = 512; - - /* Some platforms might not support this large size so we'll - decrease the size until it can */ - while (size > 1 && - !_cogl_texture_driver_size_supported (GL_TEXTURE_2D, - gl_intformat, - gl_type, - size, size)) - size >>= 1; - - *map_width = size; - *map_height = size; -} - -static CoglRectangleMap * -_cogl_atlas_create_map (CoglPixelFormat format, - unsigned int map_width, - unsigned int map_height, - unsigned int n_textures, - CoglAtlasRepositionData *textures) -{ - GLenum gl_intformat; - GLenum gl_type; - - _cogl_pixel_format_to_gl (format, - &gl_intformat, - NULL, /* gl_format */ - &gl_type); - - /* Keep trying increasingly larger atlases until we can fit all of - the textures */ - while (_cogl_texture_driver_size_supported (GL_TEXTURE_2D, - gl_intformat, - gl_type, - map_width, map_height)) - { - CoglRectangleMap *new_atlas = _cogl_rectangle_map_new (map_width, - map_height, - NULL); - unsigned int i; - - COGL_NOTE (ATLAS, "Trying to resize the atlas to %ux%u", - map_width, map_height); - - /* Add all of the textures and keep track of the new position */ - for (i = 0; i < n_textures; i++) - if (!_cogl_rectangle_map_add (new_atlas, - textures[i].old_position.width, - textures[i].old_position.height, - textures[i].user_data, - &textures[i].new_position)) - break; - - /* If the atlas can contain all of the textures then we have a - winner */ - if (i >= n_textures) - return new_atlas; - else - COGL_NOTE (ATLAS, "Atlas size abandoned after trying " - "%u out of %u textures", - i, n_textures); - - _cogl_rectangle_map_free (new_atlas); - _cogl_atlas_get_next_size (&map_width, &map_height); - } - - /* If we get here then there's no atlas that can accommodate all of - the rectangles */ - - return NULL; -} - -static CoglHandle -_cogl_atlas_create_texture (CoglAtlas *atlas, - int width, - int height) -{ - CoglHandle tex; - - if ((atlas->flags & COGL_ATLAS_CLEAR_TEXTURE)) - { - guint8 *clear_data; - CoglBitmap *clear_bmp; - int bpp = _cogl_get_format_bpp (atlas->texture_format); - - /* Create a buffer of zeroes to initially clear the texture */ - clear_data = g_malloc0 (width * height * bpp); - clear_bmp = _cogl_bitmap_new_from_data (clear_data, - atlas->texture_format, - width, - height, - width * bpp, - (CoglBitmapDestroyNotify) g_free, - NULL); - - tex = _cogl_texture_2d_new_from_bitmap (clear_bmp, COGL_TEXTURE_NONE, - atlas->texture_format); - cogl_object_unref (clear_bmp); - } - else - tex = _cogl_texture_2d_new_with_size (width, height, COGL_TEXTURE_NONE, - atlas->texture_format); - - return tex; -} - -static int -_cogl_atlas_compare_size_cb (const void *a, - const void *b) -{ - const CoglAtlasRepositionData *ta = a; - const CoglAtlasRepositionData *tb = b; - unsigned int a_size, b_size; - - a_size = ta->old_position.width * ta->old_position.height; - b_size = tb->old_position.width * tb->old_position.height; - - return a_size < b_size ? 1 : a_size > b_size ? -1 : 0; -} - -static void -_cogl_atlas_notify_pre_reorganize (CoglAtlas *atlas) -{ - g_hook_list_invoke (&atlas->pre_reorganize_callbacks, FALSE); -} - -static void -_cogl_atlas_notify_post_reorganize (CoglAtlas *atlas) -{ - g_hook_list_invoke (&atlas->post_reorganize_callbacks, FALSE); -} - -gboolean -_cogl_atlas_reserve_space (CoglAtlas *atlas, - unsigned int width, - unsigned int height, - void *user_data) -{ - CoglAtlasGetRectanglesData data; - CoglRectangleMap *new_map; - CoglHandle new_tex; - unsigned int map_width, map_height; - gboolean ret; - CoglRectangleMapEntry new_position; - - /* Check if we can fit the rectangle into the existing map */ - if (atlas->map && - _cogl_rectangle_map_add (atlas->map, width, height, - user_data, - &new_position)) - { - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - /* waste as a percentage */ - _cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); - - atlas->update_position_cb (user_data, - atlas->texture, - &new_position); - - return TRUE; - } - - /* If we make it here then we need to reorganize the atlas. First - we'll notify any users of the atlas that this is going to happen - so that for example in CoglAtlasTexture it can notify that the - storage has changed and cause a flush */ - _cogl_atlas_notify_pre_reorganize (atlas); - - /* Get an array of all the textures currently in the atlas. */ - data.n_textures = 0; - if (atlas->map == NULL) - data.textures = g_malloc (sizeof (CoglAtlasRepositionData)); - else - { - unsigned int n_rectangles = - _cogl_rectangle_map_get_n_rectangles (atlas->map); - data.textures = g_malloc (sizeof (CoglAtlasRepositionData) * - (n_rectangles + 1)); - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_get_rectangles_cb, - &data); - } - - /* Add the new rectangle as a dummy texture so that it can be - positioned with the rest */ - data.textures[data.n_textures].old_position.x = 0; - data.textures[data.n_textures].old_position.y = 0; - data.textures[data.n_textures].old_position.width = width; - data.textures[data.n_textures].old_position.height = height; - data.textures[data.n_textures++].user_data = user_data; - - /* The atlasing algorithm works a lot better if the rectangles are - added in decreasing order of size so we'll first sort the - array */ - qsort (data.textures, data.n_textures, - sizeof (CoglAtlasRepositionData), - _cogl_atlas_compare_size_cb); - - /* Try to create a new atlas that can contain all of the textures */ - if (atlas->map) - { - map_width = _cogl_rectangle_map_get_width (atlas->map); - map_height = _cogl_rectangle_map_get_height (atlas->map); - - /* If there is enough space in for the new rectangle in the - existing atlas with at least 6% waste we'll start with the - same size, otherwise we'll immediately double it */ - if ((map_width * map_height - - _cogl_rectangle_map_get_remaining_space (atlas->map) + - width * height) * 53 / 50 > - map_width * map_height) - _cogl_atlas_get_next_size (&map_width, &map_height); - } - else - _cogl_atlas_get_initial_size (atlas->texture_format, - &map_width, &map_height); - - new_map = _cogl_atlas_create_map (atlas->texture_format, - map_width, map_height, - data.n_textures, data.textures); - - /* If we can't create a map with the texture then give up */ - if (new_map == NULL) - { - COGL_NOTE (ATLAS, "%p: Could not fit texture in the atlas", atlas); - ret = FALSE; - } - /* We need to migrate the existing textures into a new texture */ - else if ((new_tex = _cogl_atlas_create_texture - (atlas, - _cogl_rectangle_map_get_width (new_map), - _cogl_rectangle_map_get_height (new_map))) == COGL_INVALID_HANDLE) - { - COGL_NOTE (ATLAS, "%p: Could not create a CoglTexture2D", atlas); - _cogl_rectangle_map_free (new_map); - ret = FALSE; - } - else - { - int waste; - - COGL_NOTE (ATLAS, - "%p: Atlas %s with size %ix%i", - atlas, - atlas->map == NULL || - _cogl_rectangle_map_get_width (atlas->map) != - _cogl_rectangle_map_get_width (new_map) || - _cogl_rectangle_map_get_height (atlas->map) != - _cogl_rectangle_map_get_height (new_map) ? - "resized" : "reorganized", - _cogl_rectangle_map_get_width (new_map), - _cogl_rectangle_map_get_height (new_map)); - - if (atlas->map) - { - /* Move all the textures to the right position in the new - texture. This will also update the texture's rectangle */ - _cogl_atlas_migrate (atlas, - data.n_textures, - data.textures, - atlas->texture, - new_tex, - user_data); - _cogl_rectangle_map_free (atlas->map); - cogl_handle_unref (atlas->texture); - } - else - /* We know there's only one texture so we can just directly - update the rectangle from its new position */ - atlas->update_position_cb (data.textures[0].user_data, - new_tex, - &data.textures[0].new_position); - - atlas->map = new_map; - atlas->texture = new_tex; - - waste = (_cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); - - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - waste); - - ret = TRUE; - } - - g_free (data.textures); - - _cogl_atlas_notify_post_reorganize (atlas); - - return ret; -} - -void -_cogl_atlas_remove (CoglAtlas *atlas, - const CoglRectangleMapEntry *rectangle) -{ - _cogl_rectangle_map_remove (atlas->map, rectangle); - - COGL_NOTE (ATLAS, "%p: Removed rectangle sized %ix%i", - atlas, - rectangle->width, - rectangle->height); - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - _cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); -}; - -CoglHandle -_cogl_atlas_copy_rectangle (CoglAtlas *atlas, - unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat format) -{ - CoglHandle tex; - CoglBlitData blit_data; - - /* Create a new texture at the right size */ - tex = cogl_texture_new_with_size (width, height, flags, format); - - /* Blit the data out of the atlas to the new texture. If FBOs - aren't available this will end up having to copy the entire - atlas texture */ - _cogl_blit_begin (&blit_data, tex, atlas->texture); - _cogl_blit (&blit_data, - x, y, - 0, 0, - width, height); - _cogl_blit_end (&blit_data); - - return tex; -} - -void -_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data) -{ - if (pre_callback) - { - GHook *hook = g_hook_alloc (&atlas->post_reorganize_callbacks); - hook->func = pre_callback; - hook->data = user_data; - g_hook_prepend (&atlas->pre_reorganize_callbacks, hook); - } - if (post_callback) - { - GHook *hook = g_hook_alloc (&atlas->pre_reorganize_callbacks); - hook->func = post_callback; - hook->data = user_data; - g_hook_prepend (&atlas->post_reorganize_callbacks, hook); - } -} - -void -_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data) -{ - if (pre_callback) - { - GHook *hook = g_hook_find_func_data (&atlas->pre_reorganize_callbacks, - FALSE, - pre_callback, - user_data); - if (hook) - g_hook_destroy_link (&atlas->pre_reorganize_callbacks, hook); - } - if (post_callback) - { - GHook *hook = g_hook_find_func_data (&atlas->post_reorganize_callbacks, - FALSE, - post_callback, - user_data); - if (hook) - g_hook_destroy_link (&atlas->post_reorganize_callbacks, hook); - } -} diff --git a/clutter/cogl/cogl/cogl-atlas.h b/clutter/cogl/cogl/cogl-atlas.h deleted file mode 100644 index 7790cec..0000000 --- a/clutter/cogl/cogl/cogl-atlas.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __COGL_ATLAS_H -#define __COGL_ATLAS_H - -#include "cogl-rectangle-map.h" -#include "cogl-object-private.h" - -typedef void -(* CoglAtlasUpdatePositionCallback) (void *user_data, - CoglHandle new_texture, - const CoglRectangleMapEntry *rect); - -typedef enum -{ - COGL_ATLAS_CLEAR_TEXTURE = (1 << 0), - COGL_ATLAS_DISABLE_MIGRATION = (1 << 1) -} CoglAtlasFlags; - -typedef struct _CoglAtlas CoglAtlas; - -#define COGL_ATLAS(object) ((CoglAtlas *) object) - -struct _CoglAtlas -{ - CoglObject _parent; - - CoglRectangleMap *map; - - CoglHandle texture; - CoglPixelFormat texture_format; - CoglAtlasFlags flags; - - CoglAtlasUpdatePositionCallback update_position_cb; - - GHookList pre_reorganize_callbacks; - GHookList post_reorganize_callbacks; -}; - -CoglAtlas * -_cogl_atlas_new (CoglPixelFormat texture_format, - CoglAtlasFlags flags, - CoglAtlasUpdatePositionCallback update_position_cb); - -gboolean -_cogl_atlas_reserve_space (CoglAtlas *atlas, - unsigned int width, - unsigned int height, - void *user_data); - -void -_cogl_atlas_remove (CoglAtlas *atlas, - const CoglRectangleMapEntry *rectangle); - -CoglHandle -_cogl_atlas_copy_rectangle (CoglAtlas *atlas, - unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat format); - -void -_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data); - -void -_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data); - -#endif /* __COGL_ATLAS_H */ diff --git a/clutter/cogl/cogl/cogl-attribute-private.h b/clutter/cogl/cogl/cogl-attribute-private.h deleted file mode 100644 index d7acef6..0000000 --- a/clutter/cogl/cogl/cogl-attribute-private.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_ATTRIBUTE_PRIVATE_H -#define __COGL_ATTRIBUTE_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-attribute.h" - -typedef enum -{ - COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY, - COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY, - COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY, - COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY, - COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY -} CoglAttributeNameID; - -struct _CoglAttribute -{ - CoglObject _parent; - - CoglVertexArray *array; - char *name; - CoglAttributeNameID name_id; - gsize stride; - gsize offset; - int n_components; - CoglAttributeType type; - gboolean normalized; - unsigned int texture_unit; - - int immutable_ref; -}; - -typedef enum -{ - COGL_DRAW_SKIP_JOURNAL_FLUSH = 1 << 0, - COGL_DRAW_SKIP_PIPELINE_VALIDATION = 1 << 1, - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH = 1 << 2, - /* When flushing from the journal the logged pipeline will already - contain the legacy state overrides so we don't want to apply them - again when we flush the pipeline for drawing */ - COGL_DRAW_SKIP_LEGACY_STATE = 1 << 3, - /* By default the vertex attribute drawing code will assume that if - there is a color attribute array enabled then we can't determine - if the colors will be opaque so we need to enabling - blending. However when drawing from the journal we know what the - contents of the color array is so we can override this by passing - this flag. */ - COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 4 -} CoglDrawFlags; - -CoglAttribute * -_cogl_attribute_immutable_ref (CoglAttribute *attribute); - -void -_cogl_attribute_immutable_unref (CoglAttribute *attribute); - -void -_cogl_draw_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - CoglDrawFlags flags); - -void -_cogl_draw_indexed_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - CoglDrawFlags flags); - -void -_cogl_attribute_disable_cached_arrays (void); - -#endif /* __COGL_ATTRIBUTE_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-attribute.c b/clutter/cogl/cogl/cogl-attribute.c deleted file mode 100644 index 591313d..0000000 --- a/clutter/cogl/cogl/cogl-attribute.c +++ /dev/null @@ -1,1280 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-journal-private.h" -#include "cogl-attribute.h" -#include "cogl-attribute-private.h" -#include "cogl-pipeline.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-texture-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-indices-private.h" -#ifdef HAVE_COGL_GLES2 -#include "cogl-pipeline-progend-glsl-private.h" -#endif - -#include -#include - -#if defined (HAVE_COGL_GL) - -#define glGenBuffers ctx->drv.pf_glGenBuffers -#define glBindBuffer ctx->drv.pf_glBindBuffer -#define glBufferData ctx->drv.pf_glBufferData -#define glBufferSubData ctx->drv.pf_glBufferSubData -#define glGetBufferSubData ctx->drv.pf_glGetBufferSubData -#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers -#define glMapBuffer ctx->drv.pf_glMapBuffer -#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer -#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture -#ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB -#endif - -#define glVertexAttribPointer ctx->drv.pf_glVertexAttribPointer -#define glEnableVertexAttribArray ctx->drv.pf_glEnableVertexAttribArray -#define glDisableVertexAttribArray ctx->drv.pf_glDisableVertexAttribArray -#define MAY_HAVE_PROGRAMABLE_GL - -#define glDrawRangeElements(mode, start, end, count, type, indices) \ - ctx->drv.pf_glDrawRangeElements (mode, start, end, count, type, indices) - -#else /* GLES 1/2 */ - -/* GLES doesn't have glDrawRangeElements, so we simply pretend it does - * but that it makes no use of the start, end constraints: */ -#define glDrawRangeElements(mode, start, end, count, type, indices) \ - glDrawElements (mode, count, type, indices) - -/* This isn't defined in the GLES headers */ -#ifndef GL_UNSIGNED_INT -#define GL_UNSIGNED_INT 0x1405 -#endif - -#ifdef HAVE_COGL_GLES2 - -#define MAY_HAVE_PROGRAMABLE_GL - -#endif /* HAVE_COGL_GLES2 */ - -#endif - -static void _cogl_attribute_free (CoglAttribute *attribute); - -COGL_OBJECT_DEFINE (Attribute, attribute); - -#if 0 -gboolean -validate_gl_attribute (const char *name, - int n_components, - CoglAttributeNameID *name_id, - gboolean *normalized, - unsigned int *texture_unit) -{ - name = name + 3; /* skip past "gl_" */ - - *normalized = FALSE; - *texture_unit = 0; - - if (strcmp (name, "Vertex") == 0) - { - if (G_UNLIKELY (n_components == 1)) - { - g_critical ("glVertexPointer doesn't allow 1 component vertex " - "positions so we currently only support \"gl_Vertex\" " - "attributes where n_components == 2, 3 or 4"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY; - } - else if (strcmp (name, "Color") == 0) - { - if (G_UNLIKELY (n_components != 3 && n_components != 4)) - { - g_critical ("glColorPointer expects 3 or 4 component colors so we " - "currently only support \"gl_Color\" attributes where " - "n_components == 3 or 4"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY; - *normalized = TRUE; - } - else if (strncmp (name, "MultiTexCoord", strlen ("MultiTexCoord")) == 0) - { - if (sscanf (gl_attribute, "MultiTexCoord%u", texture_unit) != 1) - { - g_warning ("gl_MultiTexCoord attributes should include a\n" - "texture unit number, E.g. gl_MultiTexCoord0\n"); - unit = 0; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY; - } - else if (strncmp (name, "Normal") == 0) - { - if (G_UNLIKELY (n_components != 3)) - { - g_critical ("glNormalPointer expects 3 component normals so we " - "currently only support \"gl_Normal\" attributes where " - "n_components == 3"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY; - *normalized = TRUE; - } - else - { - g_warning ("Unknown gl_* attribute name gl_%s\n", name); - return FALSE; - } - - return TRUE; -} -#endif - -gboolean -validate_cogl_attribute (const char *name, - int n_components, - CoglAttributeNameID *name_id, - gboolean *normalized, - unsigned int *texture_unit) -{ - name = name + 5; /* skip "cogl_" */ - - *normalized = FALSE; - *texture_unit = 0; - - if (strcmp (name, "position_in") == 0) - { - if (G_UNLIKELY (n_components == 1)) - { - g_critical ("glVertexPointer doesn't allow 1 component vertex " - "positions so we currently only support \"cogl_vertex\" " - "attributes where n_components == 2, 3 or 4"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY; - } - else if (strcmp (name, "color_in") == 0) - { - if (G_UNLIKELY (n_components != 3 && n_components != 4)) - { - g_critical ("glColorPointer expects 3 or 4 component colors so we " - "currently only support \"cogl_color\" attributes where " - "n_components == 3 or 4"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY; - } - else if (strcmp (name, "tex_coord_in") == 0) - *name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY; - else if (strncmp (name, "tex_coord", strlen ("tex_coord")) == 0) - { - if (sscanf (name, "tex_coord%u_in", texture_unit) != 1) - { - g_warning ("Texture coordinate attributes should either be named " - "\"cogl_tex_coord\" or named with a texture unit index " - "like \"cogl_tex_coord2_in\"\n"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY; - } - else if (strcmp (name, "normal_in") == 0) - { - if (G_UNLIKELY (n_components != 3)) - { - g_critical ("glNormalPointer expects 3 component normals so we " - "currently only support \"cogl_normal\" attributes " - "where n_components == 3"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY; - *normalized = TRUE; - } - else - { - g_warning ("Unknown cogl_* attribute name cogl_%s\n", name); - return FALSE; - } - - return TRUE; -} - -CoglAttribute * -cogl_attribute_new (CoglVertexArray *array, - const char *name, - gsize stride, - gsize offset, - int n_components, - CoglAttributeType type) -{ - CoglAttribute *attribute = g_slice_new (CoglAttribute); - gboolean status; - - attribute->array = cogl_object_ref (array); - attribute->name = g_strdup (name); - attribute->stride = stride; - attribute->offset = offset; - attribute->n_components = n_components; - attribute->type = type; - attribute->immutable_ref = 0; - - if (strncmp (name, "cogl_", 5) == 0) - status = validate_cogl_attribute (attribute->name, - n_components, - &attribute->name_id, - &attribute->normalized, - &attribute->texture_unit); -#if 0 - else if (strncmp (name, "gl_", 3) == 0) - status = validate_gl_attribute (attribute->name, - n_components, - &attribute->name_id, - &attribute->normalized, - &attribute->texture_unit); -#endif - else - { - attribute->name_id = COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY; - attribute->normalized = FALSE; - attribute->texture_unit = 0; - status = TRUE; - } - - if (!status) - { - _cogl_attribute_free (attribute); - return NULL; - } - - return _cogl_attribute_object_new (attribute); -} - -gboolean -cogl_attribute_get_normalized (CoglAttribute *attribute) -{ - g_return_val_if_fail (cogl_is_attribute (attribute), FALSE); - - return attribute->normalized; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of attributes has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_attribute_set_normalized (CoglAttribute *attribute, - gboolean normalized) -{ - g_return_if_fail (cogl_is_attribute (attribute)); - - if (G_UNLIKELY (attribute->immutable_ref)) - warn_about_midscene_changes (); - - attribute->normalized = normalized; -} - -CoglVertexArray * -cogl_attribute_get_array (CoglAttribute *attribute) -{ - g_return_val_if_fail (cogl_is_attribute (attribute), NULL); - - return attribute->array; -} - -void -cogl_attribute_set_array (CoglAttribute *attribute, - CoglVertexArray *array) -{ - g_return_if_fail (cogl_is_attribute (attribute)); - - if (G_UNLIKELY (attribute->immutable_ref)) - warn_about_midscene_changes (); - - cogl_object_ref (array); - - cogl_object_unref (attribute->array); - attribute->array = array; -} - -CoglAttribute * -_cogl_attribute_immutable_ref (CoglAttribute *attribute) -{ - g_return_val_if_fail (cogl_is_attribute (attribute), NULL); - - attribute->immutable_ref++; - _cogl_buffer_immutable_ref (COGL_BUFFER (attribute->array)); - return attribute; -} - -void -_cogl_attribute_immutable_unref (CoglAttribute *attribute) -{ - g_return_if_fail (cogl_is_attribute (attribute)); - g_return_if_fail (attribute->immutable_ref > 0); - - attribute->immutable_ref--; - _cogl_buffer_immutable_unref (COGL_BUFFER (attribute->array)); -} - -static void -_cogl_attribute_free (CoglAttribute *attribute) -{ - g_free (attribute->name); - cogl_object_unref (attribute->array); - - g_slice_free (CoglAttribute, attribute); -} - -typedef struct -{ - int unit; - CoglPipelineFlushOptions options; - guint32 fallback_layers; -} ValidateLayerState; - -static gboolean -validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - CoglHandle texture = - _cogl_pipeline_get_layer_texture (pipeline, layer_index); - ValidateLayerState *state = user_data; - gboolean status = TRUE; - - /* invalid textures will be handled correctly in - * _cogl_pipeline_flush_layers_gl_state */ - if (texture == COGL_INVALID_HANDLE) - goto validated; - - _cogl_texture_flush_journal_rendering (texture); - - /* Give the texture a chance to know that we're rendering - non-quad shaped primitives. If the texture is in an atlas it - will be migrated */ - _cogl_texture_ensure_non_quad_rendering (texture); - - /* We need to ensure the mipmaps are ready before deciding - * anything else about the texture because the texture storate - * could completely change if it needs to be migrated out of the - * atlas and will affect how we validate the layer. - */ - _cogl_pipeline_pre_paint_for_layer (pipeline, layer_index); - - if (!_cogl_texture_can_hardware_repeat (texture)) - { - g_warning ("Disabling layer %d of the current source material, " - "because texturing with the vertex buffer API is not " - "currently supported using sliced textures, or textures " - "with waste\n", layer_index); - - /* XXX: maybe we can add a mechanism for users to forcibly use - * textures with waste where it would be their responsability to use - * texture coords in the range [0,1] such that sampling outside isn't - * required. We can then use a texture matrix (or a modification of - * the users own matrix) to map 1 to the edge of the texture data. - * - * Potentially, given the same guarantee as above we could also - * support a single sliced layer too. We would have to redraw the - * vertices once for each layer, each time with a fiddled texture - * matrix. - */ - state->fallback_layers |= (1 << state->unit); - state->options.flags |= COGL_PIPELINE_FLUSH_FALLBACK_MASK; - } - -validated: - state->unit++; - return status; -} - -static void -toggle_enabled_cb (int bit_num, void *user_data) -{ - const CoglBitmask *new_values = user_data; - gboolean enabled = _cogl_bitmask_get (new_values, bit_num); - -#ifdef HAVE_COGL_GLES2 - - if (enabled) - GE( glEnableVertexAttribArray (bit_num) ); - else - GE( glDisableVertexAttribArray (bit_num) ); - -#else /* HAVE_COGL_GLES2 */ - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - GE( glClientActiveTexture (GL_TEXTURE0 + bit_num) ); - - if (enabled) - GE( glEnableClientState (GL_TEXTURE_COORD_ARRAY) ); - else - GE( glDisableClientState (GL_TEXTURE_COORD_ARRAY) ); - -#endif /* HAVE_COGL_GLES2 */ -} - -static void -set_enabled_arrays (CoglBitmask *value_cache, - const CoglBitmask *new_values) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Get the list of bits that are different */ - _cogl_bitmask_clear_all (&ctx->arrays_to_change); - _cogl_bitmask_set_bits (&ctx->arrays_to_change, value_cache); - _cogl_bitmask_xor_bits (&ctx->arrays_to_change, new_values); - - /* Iterate over each bit to change */ - _cogl_bitmask_foreach (&ctx->arrays_to_change, - toggle_enabled_cb, - (void *) new_values); - - /* Store the new values */ - _cogl_bitmask_clear_all (value_cache); - _cogl_bitmask_set_bits (value_cache, new_values); -} - -static CoglHandle -enable_gl_state (CoglDrawFlags flags, - CoglAttribute **attributes, - ValidateLayerState *state) -{ - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - int i; -#ifdef MAY_HAVE_PROGRAMABLE_GL - GLuint generic_index = 0; -#endif - unsigned long enable_flags = 0; - gboolean skip_gl_color = FALSE; - CoglPipeline *source; - CoglPipeline *copy = NULL; - int n_tex_coord_attribs = 0; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - /* In cogl_read_pixels we have a fast-path when reading a single - * pixel and the scene is just comprised of simple rectangles still - * in the journal. For this optimization to work we need to track - * when the framebuffer really does get drawn to. */ - _cogl_framebuffer_dirty (framebuffer); - - source = cogl_get_source (); - - /* Iterate the attributes to work out whether blending needs to be - enabled and how many texture coords there are. We need to do this - before flushing the pipeline. */ - for (i = 0; attributes[i]; i++) - switch (attributes[i]->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 && - !_cogl_pipeline_get_real_blend_enabled (source)) - { - CoglPipelineBlendEnable blend_enable = - COGL_PIPELINE_BLEND_ENABLE_ENABLED; - copy = cogl_pipeline_copy (source); - _cogl_pipeline_set_blend_enabled (copy, blend_enable); - source = copy; - } - skip_gl_color = TRUE; - break; - - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: - n_tex_coord_attribs++; - break; - - default: - break; - } - - if (G_UNLIKELY (state->options.flags)) - { - /* If we haven't already created a derived pipeline... */ - if (!copy) - { - copy = cogl_pipeline_copy (source); - source = copy; - } - _cogl_pipeline_apply_overrides (source, &state->options); - - /* TODO: - * overrides = cogl_pipeline_get_data (pipeline, - * last_overrides_key); - * if (overrides) - * { - * age = cogl_pipeline_get_age (pipeline); - * XXX: actually we also need to check for legacy_state - * and blending overrides for use of glColorPointer... - * if (overrides->ags != age || - * memcmp (&overrides->options, &options, - * sizeof (options) != 0) - * { - * cogl_object_unref (overrides->weak_pipeline); - * g_slice_free (Overrides, overrides); - * overrides = NULL; - * } - * } - * if (!overrides) - * { - * overrides = g_slice_new (Overrides); - * overrides->weak_pipeline = - * cogl_pipeline_weak_copy (cogl_get_source ()); - * _cogl_pipeline_apply_overrides (overrides->weak_pipeline, - * &options); - * - * cogl_pipeline_set_data (pipeline, last_overrides_key, - * weak_overrides, - * free_overrides_cb, - * NULL); - * } - * source = overrides->weak_pipeline; - */ - } - - if (G_UNLIKELY (ctx->legacy_state_set) && - (flags & COGL_DRAW_SKIP_LEGACY_STATE) == 0) - { - /* If we haven't already created a derived pipeline... */ - if (!copy) - { - copy = cogl_pipeline_copy (source); - source = copy; - } - _cogl_pipeline_apply_legacy_state (source); - } - - _cogl_pipeline_flush_gl_state (source, skip_gl_color, n_tex_coord_attribs); - - if (ctx->enable_backface_culling) - enable_flags |= COGL_ENABLE_BACKFACE_CULLING; - - _cogl_bitmask_clear_all (&ctx->temp_bitmask); - - /* Bind the attribute pointers. We need to do this after the - pipeline is flushed because on GLES2 that is the only point when - we can determine the attribute locations */ - - for (i = 0; attributes[i]; i++) - { - CoglAttribute *attribute = attributes[i]; - CoglVertexArray *vertex_array; - CoglBuffer *buffer; - guint8 *base; -#ifdef HAVE_COGL_GLES2 - int attrib_location; -#endif - - vertex_array = cogl_attribute_get_array (attribute); - buffer = COGL_BUFFER (vertex_array); - base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_VERTEX_ARRAY); - - switch (attribute->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: -#ifdef HAVE_COGL_GLES2 - - attrib_location = - _cogl_pipeline_progend_glsl_get_color_attribute (source); - if (attrib_location != -1) - { - GE( glVertexAttribPointer (attrib_location, - attribute->n_components, - attribute->type, - TRUE, /* normalize */ - attribute->stride, - base + attribute->offset) ); - - _cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); - } - -#else - - enable_flags |= COGL_ENABLE_COLOR_ARRAY; - /* GE (glEnableClientState (GL_COLOR_ARRAY)); */ - GE (glColorPointer (attribute->n_components, - attribute->type, - attribute->stride, - base + attribute->offset)); - -#endif - - break; - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: -#ifdef HAVE_COGL_GLES2 - - attrib_location = - _cogl_pipeline_progend_glsl_get_normal_attribute (source); - if (attrib_location != -1) - { - GE( glVertexAttribPointer (attrib_location, - attribute->n_components, - attribute->type, - TRUE, /* normalize */ - attribute->stride, - base + attribute->offset) ); - _cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); - } - -#else - - /* FIXME: go through cogl cache to enable normal array */ - GE (glEnableClientState (GL_NORMAL_ARRAY)); - GE (glNormalPointer (attribute->type, - attribute->stride, - base + attribute->offset)); - -#endif - - break; - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: -#ifdef HAVE_COGL_GLES2 - - attrib_location = _cogl_pipeline_progend_glsl_get_tex_coord_attribute - (source, attribute->texture_unit); - if (attrib_location != -1) - { - GE( glVertexAttribPointer (attrib_location, - attribute->n_components, - attribute->type, - FALSE, /* normalize */ - attribute->stride, - base + attribute->offset) ); - _cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); - } -#else - - GE (glClientActiveTexture (GL_TEXTURE0 + - attribute->texture_unit)); - GE (glTexCoordPointer (attribute->n_components, - attribute->type, - attribute->stride, - base + attribute->offset)); - _cogl_bitmask_set (&ctx->temp_bitmask, - attribute->texture_unit, TRUE); - -#endif - break; - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: -#ifdef HAVE_COGL_GLES2 - - attrib_location = - _cogl_pipeline_progend_glsl_get_position_attribute (source); - if (attrib_location != -1) - { - GE( glVertexAttribPointer (attrib_location, - attribute->n_components, - attribute->type, - FALSE, /* normalize */ - attribute->stride, - base + attribute->offset) ); - _cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE); - } - -#else - - enable_flags |= COGL_ENABLE_VERTEX_ARRAY; - /* GE (glEnableClientState (GL_VERTEX_ARRAY)); */ - GE (glVertexPointer (attribute->n_components, - attribute->type, - attribute->stride, - base + attribute->offset)); - -#endif - break; - case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: - { -#ifdef MAY_HAVE_PROGRAMABLE_GL - /* FIXME: go through cogl cache to enable generic array. */ - /* FIXME: this is going to end up just using the builtins - on GLES 2 */ - GE (glEnableVertexAttribArray (generic_index++)); - GE (glVertexAttribPointer (generic_index, - attribute->n_components, - attribute->type, - attribute->normalized, - attribute->stride, - base + attribute->offset)); -#endif - } - break; - default: - g_warning ("Unrecognised attribute type 0x%08x", attribute->type); - } - - _cogl_buffer_unbind (buffer); - } - - /* Flush the state of the attribute arrays */ - set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask); - - _cogl_enable (enable_flags); - _cogl_flush_face_winding (); - - return source; -} - -void -_cogl_attribute_disable_cached_arrays (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_bitmask_clear_all (&ctx->temp_bitmask); - set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask); -} - -/* FIXME: we shouldn't be disabling state after drawing we should - * just disable the things not needed after enabling state. */ -static void -disable_gl_state (CoglAttribute **attributes, - CoglPipeline *source) -{ -#ifdef MAY_HAVE_PROGRAMABLE_GL - GLuint generic_index = 0; -#endif - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (G_UNLIKELY (source != cogl_get_source ())) - cogl_object_unref (source); - - for (i = 0; attributes[i]; i++) - { - CoglAttribute *attribute = attributes[i]; - - switch (attribute->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - /* GE (glDisableClientState (GL_COLOR_ARRAY)); */ - break; - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: - /* FIXME: go through cogl cache to enable normal array */ -#ifndef HAVE_COGL_GLES2 - GE (glDisableClientState (GL_NORMAL_ARRAY)); -#endif - break; - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: - /* The enabled state of the texture coord arrays is - cached in ctx->enabled_texcoord_arrays so we don't - need to do anything here. The array will be disabled - by the next drawing primitive if it is not - required */ - break; - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: - /* GE (glDisableClientState (GL_VERTEX_ARRAY)); */ - break; - case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: -#ifdef MAY_HAVE_PROGRAMABLE_GL - /* FIXME: go through cogl cache to enable generic array */ - GE (glDisableVertexAttribArray (generic_index++)); -#endif - break; - default: - g_warning ("Unrecognised attribute type 0x%08x", attribute->type); - } - } -} - -#ifdef COGL_ENABLE_DEBUG -static int -get_index (void *indices, - CoglIndicesType type, - int _index) -{ - if (!indices) - return _index; - - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return ((guint8 *)indices)[_index]; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return ((guint16 *)indices)[_index]; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return ((guint32 *)indices)[_index]; - } - - g_return_val_if_reached (0); -} - -static void -add_line (void *vertices, - void *indices, - CoglIndicesType indices_type, - CoglAttribute *attribute, - int start, - int end, - CoglVertexP3 *lines, - int *n_line_vertices) -{ - int start_index = get_index (indices, indices_type, start); - int end_index = get_index (indices, indices_type, end); - float *v0 = (float *)((guint8 *)vertices + start_index * attribute->stride); - float *v1 = (float *)((guint8 *)vertices + end_index * attribute->stride); - float *o = (float *)(&lines[*n_line_vertices]); - int i; - - for (i = 0; i < attribute->n_components; i++) - *(o++) = *(v0++); - for (;i < 3; i++) - *(o++) = 0; - - for (i = 0; i < attribute->n_components; i++) - *(o++) = *(v1++); - for (;i < 3; i++) - *(o++) = 0; - - *n_line_vertices += 2; -} - -static CoglVertexP3 * -get_wire_lines (CoglAttribute *attribute, - CoglVerticesMode mode, - int n_vertices_in, - int *n_vertices_out, - CoglIndices *_indices) -{ - CoglVertexArray *vertex_array = cogl_attribute_get_array (attribute); - void *vertices; - CoglIndexArray *index_array; - void *indices; - CoglIndicesType indices_type; - int i; - int n_lines; - CoglVertexP3 *out = NULL; - - vertices = cogl_buffer_map (COGL_BUFFER (vertex_array), - COGL_BUFFER_ACCESS_READ, 0); - if (_indices) - { - index_array = cogl_indices_get_array (_indices); - indices = cogl_buffer_map (COGL_BUFFER (index_array), - COGL_BUFFER_ACCESS_READ, 0); - indices_type = cogl_indices_get_type (_indices); - } - else - { - index_array = NULL; - indices = NULL; - indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE; - } - - *n_vertices_out = 0; - - if (mode == COGL_VERTICES_MODE_TRIANGLES && - (n_vertices_in % 3) == 0) - { - n_lines = n_vertices_in; - out = g_new (CoglVertexP3, n_lines * 2); - for (i = 0; i < n_vertices_in; i += 3) - { - add_line (vertices, indices, indices_type, attribute, - i, i+1, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - i+1, i+2, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - i+2, i, out, n_vertices_out); - } - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN && - n_vertices_in >= 3) - { - n_lines = 2 * n_vertices_in - 3; - out = g_new (CoglVertexP3, n_lines * 2); - - add_line (vertices, indices, indices_type, attribute, - 0, 1, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - 1, 2, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - 0, 2, out, n_vertices_out); - - for (i = 3; i < n_vertices_in; i++) - { - add_line (vertices, indices, indices_type, attribute, - i - 1, i, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - 0, i, out, n_vertices_out); - } - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP && - n_vertices_in >= 3) - { - n_lines = 2 * n_vertices_in - 3; - out = g_new (CoglVertexP3, n_lines * 2); - - add_line (vertices, indices, indices_type, attribute, - 0, 1, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - 1, 2, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - 0, 2, out, n_vertices_out); - - for (i = 3; i < n_vertices_in; i++) - { - add_line (vertices, indices, indices_type, attribute, - i - 1, i, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - i - 2, i, out, n_vertices_out); - } - } - /* In the journal we are a bit sneaky and actually use GL_QUADS - * which isn't actually a valid CoglVerticesMode! */ -#ifdef HAVE_COGL_GL - else if (mode == GL_QUADS && (n_vertices_in % 4) == 0) - { - n_lines = n_vertices_in; - out = g_new (CoglVertexP3, n_lines * 2); - - for (i = 0; i < n_vertices_in; i += 4) - { - add_line (vertices, indices, indices_type, attribute, - i, i + 1, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - i + 1, i + 2, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - i + 2, i + 3, out, n_vertices_out); - add_line (vertices, indices, indices_type, attribute, - i + 3, i, out, n_vertices_out); - } - } -#endif - - if (vertices != NULL) - cogl_buffer_unmap (COGL_BUFFER (vertex_array)); - - if (indices != NULL) - cogl_buffer_unmap (COGL_BUFFER (index_array)); - - return out; -} - -static void -draw_wireframe (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - CoglIndices *indices) -{ - CoglAttribute *position = NULL; - int i; - int n_line_vertices; - static CoglPipeline *wire_pipeline; - CoglAttribute *wire_attribute[2]; - CoglVertexP3 *lines; - CoglVertexArray *array; - - for (i = 0; attributes[i]; i++) - { - if (strcmp (attributes[i]->name, "cogl_position_in") == 0) - { - position = attributes[i]; - break; - } - } - if (!position) - return; - - lines = get_wire_lines (position, - mode, - n_vertices, - &n_line_vertices, - indices); - array = cogl_vertex_array_new (sizeof (CoglVertexP3) * n_line_vertices, - lines); - wire_attribute[0] = - cogl_attribute_new (array, "cogl_position_in", - sizeof (CoglVertexP3), - 0, - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - wire_attribute[1] = NULL; - cogl_object_unref (array); - - if (!wire_pipeline) - { - wire_pipeline = cogl_pipeline_new (); - cogl_pipeline_set_color4ub (wire_pipeline, - 0x00, 0xff, 0x00, 0xff); - } - - cogl_push_source (wire_pipeline); - - /* temporarily disable the wireframe to avoid recursion! */ - COGL_DEBUG_CLEAR_FLAG (COGL_DEBUG_WIREFRAME); - _cogl_draw_attributes_array (COGL_VERTICES_MODE_LINES, - 0, - n_line_vertices, - wire_attribute, - COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH | - COGL_DRAW_SKIP_LEGACY_STATE); - - COGL_DEBUG_SET_FLAG (COGL_DEBUG_WIREFRAME); - - cogl_pop_source (); - - cogl_object_unref (wire_attribute[0]); -} -#endif - -static void -flush_state (CoglDrawFlags flags, - ValidateLayerState *state) -{ - if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH)) - { - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - _cogl_journal_flush (framebuffer->journal, framebuffer); - } - - state->unit = 0; - state->options.flags = 0; - state->fallback_layers = 0; - - if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION)) - cogl_pipeline_foreach_layer (cogl_get_source (), - validate_layer_cb, - state); - - /* NB: _cogl_framebuffer_flush_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. We need to do this - * before setting up the array pointers because setting up the clip - * stack can cause some drawing which would change the array - * pointers. */ - if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH)) - _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), - _cogl_get_read_framebuffer (), - 0); -} - -/* This can be called directly by the CoglJournal to draw attributes - * skipping the implicit journal flush, the framebuffer flush and - * pipeline validation. */ -void -_cogl_draw_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - CoglDrawFlags flags) -{ - ValidateLayerState state; - CoglPipeline *source; - - flush_state (flags, &state); - - source = enable_gl_state (flags, attributes, &state); - - GE (glDrawArrays ((GLenum)mode, first_vertex, n_vertices)); - - /* FIXME: we shouldn't be disabling state after drawing we should - * just disable the things not needed after enabling state. */ - disable_gl_state (attributes, source); - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME))) - draw_wireframe (mode, first_vertex, n_vertices, attributes, NULL); -#endif -} - -void -cogl_draw_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes) -{ - _cogl_draw_attributes_array (mode, first_vertex, - n_vertices, attributes, - 0 /* no flags */); -} - -void -cogl_draw_attributes (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - ...) -{ - va_list ap; - int n_attributes; - CoglAttribute *attribute; - CoglAttribute **attributes; - int i; - - va_start (ap, n_vertices); - for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++) - ; - va_end (ap); - - attributes = g_alloca (sizeof (CoglAttribute *) * (n_attributes + 1)); - attributes[n_attributes] = NULL; - - va_start (ap, n_vertices); - for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++) - attributes[i] = attribute; - va_end (ap); - - cogl_draw_attributes_array (mode, first_vertex, n_vertices, - attributes); -} - -static size_t -sizeof_index_type (CoglIndicesType type) -{ - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return 4; - } - g_return_val_if_reached (0); -} - -void -_cogl_draw_indexed_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - CoglDrawFlags flags) -{ - ValidateLayerState state; - CoglPipeline *source; - CoglBuffer *buffer; - guint8 *base; - size_t array_offset; - size_t index_size; - GLenum indices_gl_type = 0; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - flush_state (flags, &state); - - source = enable_gl_state (flags, attributes, &state); - - buffer = COGL_BUFFER (cogl_indices_get_array (indices)); - base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_ARRAY); - array_offset = cogl_indices_get_offset (indices); - index_size = sizeof_index_type (cogl_indices_get_type (indices)); - - switch (cogl_indices_get_type (indices)) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - indices_gl_type = GL_UNSIGNED_BYTE; - break; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - indices_gl_type = GL_UNSIGNED_SHORT; - break; - case COGL_INDICES_TYPE_UNSIGNED_INT: - indices_gl_type = GL_UNSIGNED_INT; - break; - } - - GE (glDrawElements ((GLenum)mode, - n_vertices, - indices_gl_type, - base + array_offset + index_size * first_vertex)); - - _cogl_buffer_unbind (buffer); - - /* FIXME: we shouldn't be disabling state after drawing we should - * just disable the things not needed after enabling state. */ - disable_gl_state (attributes, source); - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME))) - draw_wireframe (mode, first_vertex, n_vertices, attributes, indices); -#endif -} - -void -cogl_draw_indexed_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes) -{ - _cogl_draw_indexed_attributes_array (mode, first_vertex, - n_vertices, indices, attributes, - 0 /* no flags */); -} - -void -cogl_draw_indexed_attributes (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - ...) -{ - va_list ap; - int n_attributes; - CoglAttribute **attributes; - int i; - CoglAttribute *attribute; - - va_start (ap, indices); - for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++) - ; - va_end (ap); - - attributes = g_alloca (sizeof (CoglAttribute *) * (n_attributes + 1)); - attributes[n_attributes] = NULL; - - va_start (ap, indices); - for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++) - attributes[i] = attribute; - va_end (ap); - - cogl_draw_indexed_attributes_array (mode, - first_vertex, - n_vertices, - indices, - attributes); -} - - diff --git a/clutter/cogl/cogl/cogl-attribute.h b/clutter/cogl/cogl/cogl-attribute.h deleted file mode 100644 index 70d4c2b..0000000 --- a/clutter/cogl/cogl/cogl-attribute.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_ATTRIBUTE_H__ -#define __COGL_ATTRIBUTE_H__ - -#include -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-attribute - * @short_description: Functions for declaring and drawing vertex - * attributes - * - * FIXME - */ - -typedef struct _CoglAttribute CoglAttribute; - -/** - * cogl_attribute_new: - * @array: The #CoglVertexArray containing the actual attribute data - * @name: The name of the attribute (used to reference it from GLSL) - * @stride: The number of bytes to jump to get to the next attribute - * value for the next vertex. (Usually - *
sizeof (MyVertex)
) - * @offset: The byte offset from the start of @array for the first - * attribute value. (Usually - *
offsetof (MyVertex, component0)
- * @components: The number of components (e.g. 4 for an rgba color or - * 3 for and (x,y,z) position) - * @type: FIXME - * - * Describes the layout for a list of vertex attribute values (For - * example, a list of texture coordinates or colors). - * - * The @name is used to access the attribute inside a GLSL vertex - * shader and there are some special names you should use if they are - * applicable: - * - * "cogl_position_in" (used for vertex positions) - * "cogl_color_in" (used for vertex colors) - * "cogl_tex_coord0_in", "cogl_tex_coord1", ... - * (used for vertex texture coordinates) - * "cogl_normal_in" (used for vertex normals) - * - * - * The attribute values corresponding to different vertices can either - * be tightly packed or interleaved with other attribute values. For - * example it's common to define a structure for a single vertex like: - * |[ - * typedef struct - * { - * float x, y, z; /* position attribute */ - * float s, t; /* texture coordinate attribute */ - * } MyVertex; - * ]| - * - * And then create an array of vertex data something like: - * |[ - * MyVertex vertices[100] = { .... } - * ]| - * - * In this case, to describe either the position or texture coordinate - * attribute you have to move
sizeof (MyVertex)
bytes to - * move from one vertex to the next. This is called the attribute - * @stride. If you weren't interleving attributes and you instead had - * a packed array of float x, y pairs then the attribute stride would - * be
(2 * sizeof (float))
. So the @stride is the number of - * bytes to move to find the attribute value of the next vertex. - * - * Normally a list of attributes starts at the beginning of an array. - * So for the
MyVertex
example above the @offset is the - * offset inside the
MyVertex
structure to the first - * component of the attribute. For the texture coordinate attribute - * the offset would be
offsetof (MyVertex, s)
or instead of - * using the offsetof macro you could use
sizeof (float) * 3
. - * If you've divided your @array into blocks of non-interleved - * attributes then you will need to calculate the @offset as the - * number of bytes in blocks preceding the attribute you're - * describing. - * - * An attribute often has more than one component. For example a color - * is often comprised of 4 red, green, blue and alpha @components, and a - * position may be comprised of 2 x and y @components. You should aim - * to keep the number of components to a minimum as more components - * means more data needs to be mapped into the GPU which can be a - * bottlneck when dealing with a large number of vertices. - * - * Finally you need to specify the component data type. Here you - * should aim to use the smallest type that meets your precision - * requirements. Again the larger the type then more data needs to be - * mapped into the GPU which can be a bottlneck when dealing with - * a large number of vertices. - * - * Returns: A newly allocated #CoglAttribute describing the - * layout for a list of attribute values stored in @array. - * - * Since: 1.4 - * Stability: Unstable - */ -/* XXX: look for a precedent to see if the stride/offset args should - * have a different order. */ -CoglAttribute * -cogl_attribute_new (CoglVertexArray *array, - const char *name, - gsize stride, - gsize offset, - int components, - CoglAttributeType type); - -/** - * cogl_is_attribute: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglAttribute. - * - * Return value: %TRUE if the handle references a #CoglAttribute, - * %FALSE otherwise - */ -gboolean -cogl_is_attribute (void *object); - -void -cogl_draw_attributes (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - ...) G_GNUC_NULL_TERMINATED; - -void -cogl_draw_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes); - -void -cogl_draw_indexed_attributes (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - ...) G_GNUC_NULL_TERMINATED; - -void -cogl_draw_indexed_attributes_array (CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes); - -G_END_DECLS - -#endif /* __COGL_ATTRIBUTE_H__ */ - diff --git a/clutter/cogl/cogl/cogl-bitmap-fallback.c b/clutter/cogl/cogl/cogl-bitmap-fallback.c deleted file mode 100644 index 4478c43..0000000 --- a/clutter/cogl/cogl/cogl-bitmap-fallback.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-bitmap-private.h" - -#include - -/* TO rgba */ - -inline static void -_cogl_g_to_rgba (const guint8 *src, guint8 *dst) -{ - dst[0] = src[0]; - dst[1] = src[0]; - dst[2] = src[0]; - dst[3] = 255; -} - -inline static void -_cogl_rgb_to_rgba (const guint8 *src, guint8 *dst) -{ - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = 255; -} - -inline static void -_cogl_bgr_to_rgba (const guint8 *src, guint8 *dst) -{ - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - dst[3] = 255; -} - -inline static void -_cogl_bgra_to_rgba (const guint8 *src, guint8 *dst) -{ - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - dst[3] = src[3]; -} - -inline static void -_cogl_argb_to_rgba (const guint8 *src, guint8 *dst) -{ - dst[0] = src[1]; - dst[1] = src[2]; - dst[2] = src[3]; - dst[3] = src[0]; -} - -inline static void -_cogl_abgr_to_rgba (const guint8 *src, guint8 *dst) -{ - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; -} - -inline static void -_cogl_rgba_to_rgba (const guint8 *src, guint8 *dst) -{ - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; -} - -/* FROM rgba */ - -inline static void -_cogl_rgba_to_g (const guint8 *src, guint8 *dst) -{ - dst[0] = (src[0] + src[1] + src[2]) / 3; -} - -inline static void -_cogl_rgba_to_rgb (const guint8 *src, guint8 *dst) -{ - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; -} - -inline static void -_cogl_rgba_to_bgr (const guint8 *src, guint8 *dst) -{ - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; -} - -inline static void -_cogl_rgba_to_bgra (const guint8 *src, guint8 *dst) -{ - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - dst[3] = src[3]; -} - -inline static void -_cogl_rgba_to_argb (const guint8 *src, guint8 *dst) -{ - dst[0] = src[3]; - dst[1] = src[0]; - dst[2] = src[1]; - dst[3] = src[2]; -} - -inline static void -_cogl_rgba_to_abgr (const guint8 *src, guint8 *dst) -{ - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; -} - -/* (Un)Premultiplication */ - -inline static void -_cogl_unpremult_alpha_0 (guint8 *dst) -{ - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; -} - -inline static void -_cogl_unpremult_alpha_last (guint8 *dst) -{ - guint8 alpha = dst[3]; - - dst[0] = (dst[0] * 255) / alpha; - dst[1] = (dst[1] * 255) / alpha; - dst[2] = (dst[2] * 255) / alpha; -} - -inline static void -_cogl_unpremult_alpha_first (guint8 *dst) -{ - guint8 alpha = dst[0]; - - dst[1] = (dst[1] * 255) / alpha; - dst[2] = (dst[2] * 255) / alpha; - dst[3] = (dst[3] * 255) / alpha; -} - -/* No division form of floor((c*a + 128)/255) (I first encountered - * this in the RENDER implementation in the X server.) Being exact - * is important for a == 255 - we want to get exactly c. - */ -#define MULT(d,a,t) \ - G_STMT_START { \ - t = d * a + 128; \ - d = ((t >> 8) + t) >> 8; \ - } G_STMT_END - -inline static void -_cogl_premult_alpha_last (guint8 *dst) -{ - guint8 alpha = dst[3]; - /* Using a separate temporary per component has given slightly better - * code generation with GCC in the past; it shouldn't do any worse in - * any case. - */ - unsigned int t1, t2, t3; - MULT(dst[0], alpha, t1); - MULT(dst[1], alpha, t2); - MULT(dst[2], alpha, t3); -} - -inline static void -_cogl_premult_alpha_first (guint8 *dst) -{ - guint8 alpha = dst[0]; - unsigned int t1, t2, t3; - - MULT(dst[1], alpha, t1); - MULT(dst[2], alpha, t2); - MULT(dst[3], alpha, t3); -} - -#undef MULT - -/* Use the SSE optimized version to premult four pixels at once when - it is available. The same assembler code works for x86 and x86-64 - because it doesn't refer to any non-SSE registers directly */ -#if defined(__SSE2__) && defined(__GNUC__) \ - && (defined(__x86_64) || defined(__i386)) -#define COGL_USE_PREMULT_SSE2 -#endif - -#ifdef COGL_USE_PREMULT_SSE2 - -inline static void -_cogl_premult_alpha_last_four_pixels_sse2 (guint8 *p) -{ - /* 8 copies of 128 used below */ - static const gint16 eight_halves[8] __attribute__ ((aligned (16))) = - { 128, 128, 128, 128, 128, 128, 128, 128 }; - /* Mask of the rgb components of the four pixels */ - static const gint8 just_rgb[16] __attribute__ ((aligned (16))) = - { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, - 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00 }; - /* Each SSE register only holds two pixels because we need to work - with 16-bit intermediate values. We still do four pixels by - interleaving two registers in the hope that it will pipeline - better */ - asm (/* Load eight_halves into xmm5 for later */ - "movdqa (%1), %%xmm5\n" - /* Clear xmm3 */ - "pxor %%xmm3, %%xmm3\n" - /* Load two pixels from p into the low half of xmm0 */ - "movlps (%0), %%xmm0\n" - /* Load the next set of two pixels from p into the low half of xmm1 */ - "movlps 8(%0), %%xmm1\n" - /* Unpack 8 bytes from the low quad-words in each register to 8 - 16-bit values */ - "punpcklbw %%xmm3, %%xmm0\n" - "punpcklbw %%xmm3, %%xmm1\n" - /* Copy alpha values of the first pixel in xmm0 to all - components of the first pixel in xmm2 */ - "pshuflw $255, %%xmm0, %%xmm2\n" - /* same for xmm1 and xmm3 */ - "pshuflw $255, %%xmm1, %%xmm3\n" - /* The above also copies the second pixel directly so we now - want to replace the RGB components with copies of the alpha - components */ - "pshufhw $255, %%xmm2, %%xmm2\n" - "pshufhw $255, %%xmm3, %%xmm3\n" - /* Multiply the rgb components by the alpha */ - "pmullw %%xmm2, %%xmm0\n" - "pmullw %%xmm3, %%xmm1\n" - /* Add 128 to each component */ - "paddw %%xmm5, %%xmm0\n" - "paddw %%xmm5, %%xmm1\n" - /* Copy the results to temporary registers xmm4 and xmm5 */ - "movdqa %%xmm0, %%xmm4\n" - "movdqa %%xmm1, %%xmm5\n" - /* Divide the results by 256 */ - "psrlw $8, %%xmm0\n" - "psrlw $8, %%xmm1\n" - /* Add the temporaries back in */ - "paddw %%xmm4, %%xmm0\n" - "paddw %%xmm5, %%xmm1\n" - /* Divide again */ - "psrlw $8, %%xmm0\n" - "psrlw $8, %%xmm1\n" - /* Pack the results back as bytes */ - "packuswb %%xmm1, %%xmm0\n" - /* Load just_rgb into xmm3 for later */ - "movdqa (%2), %%xmm3\n" - /* Reload all four pixels into xmm2 */ - "movups (%0), %%xmm2\n" - /* Mask out the alpha from the results */ - "andps %%xmm3, %%xmm0\n" - /* Mask out the RGB from the original four pixels */ - "andnps %%xmm2, %%xmm3\n" - /* Combine the two to get the right alpha values */ - "orps %%xmm3, %%xmm0\n" - /* Write to memory */ - "movdqu %%xmm0, (%0)\n" - : /* no outputs */ - : "r" (p), "r" (eight_halves), "r" (just_rgb) - : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -#endif /* COGL_USE_PREMULT_SSE2 */ - -gboolean -_cogl_bitmap_fallback_can_convert (CoglPixelFormat src, CoglPixelFormat dst) -{ - if (src == dst) - return FALSE; - - switch (src & COGL_UNORDERED_MASK) - { - case COGL_PIXEL_FORMAT_G_8: - case COGL_PIXEL_FORMAT_24: - case COGL_PIXEL_FORMAT_32: - - if ((dst & COGL_UNORDERED_MASK) != COGL_PIXEL_FORMAT_24 && - (dst & COGL_UNORDERED_MASK) != COGL_PIXEL_FORMAT_32 && - (dst & COGL_UNORDERED_MASK) != COGL_PIXEL_FORMAT_G_8) - return FALSE; - break; - - default: - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_bitmap_fallback_can_unpremult (CoglPixelFormat format) -{ - return ((format & COGL_UNORDERED_MASK) == COGL_PIXEL_FORMAT_32); -} - -gboolean -_cogl_bitmap_fallback_can_premult (CoglPixelFormat format) -{ - return ((format & COGL_UNORDERED_MASK) == COGL_PIXEL_FORMAT_32); -} - -CoglBitmap * -_cogl_bitmap_fallback_convert (CoglBitmap *src_bmp, - CoglPixelFormat dst_format) -{ - guint8 *src_data; - guint8 *dst_data; - guint8 *src; - guint8 *dst; - int src_bpp; - int dst_bpp; - int src_rowstride; - int dst_rowstride; - int x,y; - guint8 temp_rgba[4] = {0,0,0,0}; - int width, height; - CoglPixelFormat src_format; - - src_format = _cogl_bitmap_get_format (src_bmp); - src_rowstride = _cogl_bitmap_get_rowstride (src_bmp); - width = _cogl_bitmap_get_width (src_bmp); - height = _cogl_bitmap_get_height (src_bmp); - - /* Make sure conversion supported */ - if (!_cogl_bitmap_fallback_can_convert (src_format, dst_format)) - return NULL; - - src_data = _cogl_bitmap_map (src_bmp, COGL_BUFFER_ACCESS_READ, 0); - if (src_data == NULL) - return NULL; - - src_bpp = _cogl_get_format_bpp (src_format); - dst_bpp = _cogl_get_format_bpp (dst_format); - - /* Initialize destination bitmap */ - dst_rowstride = sizeof(guint8) * dst_bpp * width; - /* Copy the premult bit if the new format has an alpha channel */ - if ((dst_format & COGL_A_BIT)) - dst_format = ((src_format & COGL_PREMULT_BIT) | - (dst_format & COGL_UNPREMULT_MASK)); - - /* Allocate a new buffer to hold converted data */ - dst_data = g_malloc (height * dst_rowstride); - - /* FIXME: Optimize */ - for (y = 0; y < height; y++) - { - src = src_data + y * src_rowstride; - dst = dst_data + y * dst_rowstride; - - for (x = 0; x < width; x++) - { - /* FIXME: Would be nice to at least remove this inner - * branching, but not sure it can be done without - * rewriting of the whole loop */ - switch (src_format & COGL_UNPREMULT_MASK) - { - case COGL_PIXEL_FORMAT_G_8: - _cogl_g_to_rgba (src, temp_rgba); break; - case COGL_PIXEL_FORMAT_RGB_888: - _cogl_rgb_to_rgba (src, temp_rgba); break; - case COGL_PIXEL_FORMAT_BGR_888: - _cogl_bgr_to_rgba (src, temp_rgba); break; - case COGL_PIXEL_FORMAT_RGBA_8888: - _cogl_rgba_to_rgba (src, temp_rgba); break; - case COGL_PIXEL_FORMAT_BGRA_8888: - _cogl_bgra_to_rgba (src, temp_rgba); break; - case COGL_PIXEL_FORMAT_ARGB_8888: - _cogl_argb_to_rgba (src, temp_rgba); break; - case COGL_PIXEL_FORMAT_ABGR_8888: - _cogl_abgr_to_rgba (src, temp_rgba); break; - default: - break; - } - - switch (dst_format & COGL_UNPREMULT_MASK) - { - case COGL_PIXEL_FORMAT_G_8: - _cogl_rgba_to_g (temp_rgba, dst); break; - case COGL_PIXEL_FORMAT_RGB_888: - _cogl_rgba_to_rgb (temp_rgba, dst); break; - case COGL_PIXEL_FORMAT_BGR_888: - _cogl_rgba_to_bgr (temp_rgba, dst); break; - case COGL_PIXEL_FORMAT_RGBA_8888: - _cogl_rgba_to_rgba (temp_rgba, dst); break; - case COGL_PIXEL_FORMAT_BGRA_8888: - _cogl_rgba_to_bgra (temp_rgba, dst); break; - case COGL_PIXEL_FORMAT_ARGB_8888: - _cogl_rgba_to_argb (temp_rgba, dst); break; - case COGL_PIXEL_FORMAT_ABGR_8888: - _cogl_rgba_to_abgr (temp_rgba, dst); break; - default: - break; - } - - src += src_bpp; - dst += dst_bpp; - } - } - - _cogl_bitmap_unmap (src_bmp); - - return _cogl_bitmap_new_from_data (dst_data, - dst_format, - width, height, dst_rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); -} - -gboolean -_cogl_bitmap_fallback_unpremult (CoglBitmap *bmp) -{ - guint8 *p, *data; - int x,y; - CoglPixelFormat format; - int width, height; - int rowstride; - - format = _cogl_bitmap_get_format (bmp); - width = _cogl_bitmap_get_width (bmp); - height = _cogl_bitmap_get_height (bmp); - rowstride = _cogl_bitmap_get_rowstride (bmp); - - /* Make sure format supported for un-premultiplication */ - if (!_cogl_bitmap_fallback_can_unpremult (format)) - return FALSE; - - if ((data = _cogl_bitmap_map (bmp, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0)) == NULL) - return FALSE; - - for (y = 0; y < height; y++) - { - p = (guint8*) data + y * rowstride; - - if (format & COGL_AFIRST_BIT) - { - for (x = 0; x < width; x++) - { - if (p[0] == 0) - _cogl_unpremult_alpha_0 (p); - else - _cogl_unpremult_alpha_first (p); - p += 4; - } - } - else - { - for (x = 0; x < width; x++) - { - if (p[3] == 0) - _cogl_unpremult_alpha_0 (p); - else - _cogl_unpremult_alpha_last (p); - p += 4; - } - } - } - - _cogl_bitmap_unmap (bmp); - - _cogl_bitmap_set_format (bmp, format & ~COGL_PREMULT_BIT); - - return TRUE; -} - -gboolean -_cogl_bitmap_fallback_premult (CoglBitmap *bmp) -{ - guint8 *p, *data; - int x,y; - CoglPixelFormat format; - int width, height; - int rowstride; - - format = _cogl_bitmap_get_format (bmp); - width = _cogl_bitmap_get_width (bmp); - height = _cogl_bitmap_get_height (bmp); - rowstride = _cogl_bitmap_get_rowstride (bmp); - - /* Make sure format supported for un-premultiplication */ - if (!_cogl_bitmap_fallback_can_premult (format)) - return FALSE; - - if ((data = _cogl_bitmap_map (bmp, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0)) == NULL) - return FALSE; - - for (y = 0; y < height; y++) - { - p = (guint8*) data + y * rowstride; - - if (format & COGL_AFIRST_BIT) - { - for (x = 0; x < width; x++) - { - _cogl_premult_alpha_first (p); - p += 4; - } - } - else - { - x = width; - -#ifdef COGL_USE_PREMULT_SSE2 - - /* Process 4 pixels at a time */ - while (x >= 4) - { - _cogl_premult_alpha_last_four_pixels_sse2 (p); - p += 4 * 4; - x -= 4; - } - - /* If there are any pixels left we will fall through and - handle them below */ - -#endif /* COGL_USE_PREMULT_SSE2 */ - - while (x-- > 0) - { - _cogl_premult_alpha_last (p); - p += 4; - } - } - } - - _cogl_bitmap_unmap (bmp); - - _cogl_bitmap_set_format (bmp, format | COGL_PREMULT_BIT); - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_fallback_from_file (const char *filename) -{ - /* FIXME: use jpeglib, libpng, etc. manually maybe */ - return FALSE; -} diff --git a/clutter/cogl/cogl/cogl-bitmap-pixbuf.c b/clutter/cogl/cogl/cogl-bitmap-pixbuf.c deleted file mode 100644 index 1a99f4b..0000000 --- a/clutter/cogl/cogl/cogl-bitmap-pixbuf.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-bitmap-private.h" - -#include - -#ifdef USE_QUARTZ -#include -#elif defined(USE_GDKPIXBUF) -#include -#endif - -gboolean -_cogl_bitmap_can_convert (CoglPixelFormat src, CoglPixelFormat dst) -{ - return FALSE; -} - -gboolean -_cogl_bitmap_can_unpremult (CoglPixelFormat format) -{ - return FALSE; -} - -gboolean -_cogl_bitmap_can_premult (CoglPixelFormat format) -{ - return FALSE; -} - -CoglBitmap * -_cogl_bitmap_convert (CoglBitmap *bmp, - CoglPixelFormat dst_format) -{ - return NULL; -} - -gboolean -_cogl_bitmap_unpremult (CoglBitmap *dst_bmp) -{ - return FALSE; -} - -gboolean -_cogl_bitmap_premult (CoglBitmap *dst_bmp) -{ - return FALSE; -} - -#ifdef USE_QUARTZ - -gboolean -_cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height) -{ - if (width) - *width = 0; - - if (height) - *height = 0; - - return TRUE; -} - -/* the error does not contain the filename as the caller already has it */ -CoglBitmap * -_cogl_bitmap_from_file (const char *filename, - GError **error) -{ - CFURLRef url; - CGImageSourceRef image_source; - CGImageRef image; - int save_errno; - CFStringRef type; - gsize width, height, rowstride; - guint8 *out_data; - CGColorSpaceRef color_space; - CGContextRef bitmap_context; - - g_assert (filename != NULL); - g_assert (error == NULL || *error == NULL); - - url = CFURLCreateFromFileSystemRepresentation (NULL, - (guchar *) filename, - strlen (filename), - false); - image_source = CGImageSourceCreateWithURL (url, NULL); - save_errno = errno; - CFRelease (url); - - if (image_source == NULL) - { - /* doesn't exist, not readable, etc. */ - g_set_error_literal (error, - COGL_BITMAP_ERROR, - COGL_BITMAP_ERROR_FAILED, - g_strerror (save_errno)); - return NULL; - } - - /* Unknown images would be cleanly caught as zero width/height below, but try - * to provide better error message - */ - type = CGImageSourceGetType (image_source); - if (type == NULL) - { - CFRelease (image_source); - g_set_error_literal (error, - COGL_BITMAP_ERROR, - COGL_BITMAP_ERROR_UNKNOWN_TYPE, - "Unknown image type"); - return NULL; - } - - CFRelease (type); - - image = CGImageSourceCreateImageAtIndex (image_source, 0, NULL); - CFRelease (image_source); - - width = CGImageGetWidth (image); - height = CGImageGetHeight (image); - if (width == 0 || height == 0) - { - /* incomplete or corrupt */ - CFRelease (image); - g_set_error_literal (error, - COGL_BITMAP_ERROR, - COGL_BITMAP_ERROR_CORRUPT_IMAGE, - "Image has zero width or height"); - return NULL; - } - - /* allocate buffer big enough to hold pixel data */ - rowstride = 4 * width; - out_data = g_malloc0 (height * rowstride); - - /* render to buffer */ - color_space = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB); - bitmap_context = CGBitmapContextCreate (out_data, - width, height, 8, - rowstride, color_space, - kCGImageAlphaPremultipliedFirst); - CGColorSpaceRelease (color_space); - - { - const CGRect rect = {{0, 0}, {width, height}}; - - CGContextDrawImage (bitmap_context, rect, image); - } - - CGImageRelease (image); - CGContextRelease (bitmap_context); - - /* store bitmap info */ - return _cogl_bitmap_new_from_data (out_data, - COGL_PIXEL_FORMAT_ARGB_8888, - width, height, - rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); -} - -#elif defined(USE_GDKPIXBUF) - -gboolean -_cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height) -{ - g_return_val_if_fail (filename != NULL, FALSE); - - if (gdk_pixbuf_get_file_info (filename, width, height) != NULL) - return TRUE; - - return FALSE; -} - -static void -_cogl_bitmap_unref_pixbuf (guint8 *pixels, - void *pixbuf) -{ - g_object_unref (pixbuf); -} - -CoglBitmap * -_cogl_bitmap_from_file (const char *filename, - GError **error) -{ - GdkPixbuf *pixbuf; - gboolean has_alpha; - GdkColorspace color_space; - CoglPixelFormat pixel_format; - int width; - int height; - int rowstride; - int bits_per_sample; - int n_channels; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* Load from file using GdkPixbuf */ - pixbuf = gdk_pixbuf_new_from_file (filename, error); - if (pixbuf == NULL) - return FALSE; - - /* Get pixbuf properties */ - has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); - color_space = gdk_pixbuf_get_colorspace (pixbuf); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf); - n_channels = gdk_pixbuf_get_n_channels (pixbuf); - - /* According to current docs this should be true and so - * the translation to cogl pixel format below valid */ - g_assert (bits_per_sample == 8); - - if (has_alpha) - g_assert (n_channels == 4); - else - g_assert (n_channels == 3); - - /* Translate to cogl pixel format */ - switch (color_space) - { - case GDK_COLORSPACE_RGB: - /* The only format supported by GdkPixbuf so far */ - pixel_format = has_alpha ? - COGL_PIXEL_FORMAT_RGBA_8888 : - COGL_PIXEL_FORMAT_RGB_888; - break; - - default: - /* Ouch, spec changed! */ - g_object_unref (pixbuf); - return FALSE; - } - - /* We just use the data directly from the pixbuf so that we don't - have to copy to a seperate buffer. Note that Cogl is expected not - to read past the end of bpp*width on the last row even if the - rowstride is much larger so we don't need to worry about - GdkPixbuf's semantics that it may under-allocate the buffer. */ - return _cogl_bitmap_new_from_data (gdk_pixbuf_get_pixels (pixbuf), - pixel_format, - width, - height, - rowstride, - _cogl_bitmap_unref_pixbuf, - pixbuf); -} - -#else - -#include "stb_image.c" - -gboolean -_cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height) -{ - if (width) - *width = 0; - - if (height) - *height = 0; - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_from_file (const char *filename, - GError **error) -{ - CoglBitmap *bmp; - int stb_pixel_format; - int width; - int height; - guint8 *pixels; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* Load from file using stb */ - pixels = stbi_load (filename, - &width, &height, &stb_pixel_format, - STBI_rgb_alpha); - if (pixels == NULL) - return FALSE; - - /* Store bitmap info */ - bmp = _cogl_bitmap_new_from_data (g_memdup (pixels, height * width * 4), - COGL_PIXEL_FORMAT_RGBA_8888, - width, height, - width * 4, - (CoglBitmapDestroyNotify) g_free, - NULL); - - free (pixels); - - return bmp; -} -#endif diff --git a/clutter/cogl/cogl/cogl-bitmap-private.h b/clutter/cogl/cogl/cogl-bitmap-private.h deleted file mode 100644 index 3df519f..0000000 --- a/clutter/cogl/cogl/cogl-bitmap-private.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Clutter COGL - * - * A basic GL/GLES Abstraction/Utility Layer - * - * Authored By Matthew Allum - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_BITMAP_H -#define __COGL_BITMAP_H - -#include - -#include "cogl-handle.h" -#include "cogl-buffer.h" -#include "cogl-bitmap.h" - -/* - * CoglBitmapDestroyNotify: - * @data: The image data - * @destroy_data: The callback closure data that was given to - * _cogl_bitmap_new_from_data(). - * - * Function prototype that is used to destroy the bitmap data when - * _cogl_bitmap_new_from_data() is called. - */ -typedef void (* CoglBitmapDestroyNotify) (guint8 *data, void *destroy_data); - -/* - * _cogl_bitmap_new_from_data: - * @data: A pointer to the data. The bitmap will take ownership of this data. - * @format: The format of the pixel data. - * @width: The width of the bitmap. - * @height: The height of the bitmap. - * @rowstride: The rowstride of the bitmap (the number of bytes from - * the start of one row of the bitmap to the next). - * @destroy_fn: A function to be called when the bitmap is - * destroyed. This should free @data. %NULL can be used instead if - * no free is needed. - * @destroy_fn_data: This pointer will get passed to @destroy_fn. - * - * Creates a bitmap using some existing data. The data is not copied - * so the bitmap will take ownership of the data pointer. When the - * bitmap is freed @destroy_fn will be called to free the data. - * - * Return value: A new %CoglBitmap. - */ -CoglBitmap * -_cogl_bitmap_new_from_data (guint8 *data, - CoglPixelFormat format, - int width, - int height, - int rowstride, - CoglBitmapDestroyNotify destroy_fn, - gpointer destroy_fn_data); - -/* The idea of this function is that it will create a bitmap that - shares the actual data with another bitmap. This is needed for the - atlas texture backend because it needs upload a bitmap to a sub - texture but override the format so that it ignores the premult - flag. */ -CoglBitmap * -_cogl_bitmap_new_shared (CoglBitmap *shared_bmp, - CoglPixelFormat format, - int width, - int height, - int rowstride); - -/* This creates a cogl bitmap that internally references a pixel - array. The data is not copied. _cogl_bitmap_map will divert to - mapping the pixel array */ -CoglBitmap * -_cogl_bitmap_new_from_buffer (CoglBuffer *buffer, - CoglPixelFormat format, - int width, - int height, - int rowstride, - int offset); - -gboolean -_cogl_bitmap_can_convert (CoglPixelFormat src, CoglPixelFormat dst); - -gboolean -_cogl_bitmap_fallback_can_convert (CoglPixelFormat src, CoglPixelFormat dst); - -gboolean -_cogl_bitmap_can_unpremult (CoglPixelFormat format); - -gboolean -_cogl_bitmap_fallback_can_unpremult (CoglPixelFormat format); - -gboolean -_cogl_bitmap_can_premult (CoglPixelFormat format); - -gboolean -_cogl_bitmap_fallback_can_premult (CoglPixelFormat format); - -CoglBitmap * -_cogl_bitmap_convert (CoglBitmap *bmp, - CoglPixelFormat dst_format); -CoglBitmap * -_cogl_bitmap_fallback_convert (CoglBitmap *bmp, - CoglPixelFormat dst_format); - -gboolean -_cogl_bitmap_unpremult (CoglBitmap *dst_bmp); - -gboolean -_cogl_bitmap_fallback_unpremult (CoglBitmap *dst_bmp); - -gboolean -_cogl_bitmap_premult (CoglBitmap *dst_bmp); - -gboolean -_cogl_bitmap_fallback_premult (CoglBitmap *dst_bmp); - -CoglBitmap * -_cogl_bitmap_from_file (const char *filename, - GError **error); - -CoglBitmap * -_cogl_bitmap_fallback_from_file (const char *filename); - -gboolean -_cogl_bitmap_convert_premult_status (CoglBitmap *bmp, - CoglPixelFormat dst_format); - -CoglBitmap * -_cogl_bitmap_convert_format_and_premult (CoglBitmap *bmp, - CoglPixelFormat dst_format); - -void -_cogl_bitmap_copy_subregion (CoglBitmap *src, - CoglBitmap *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height); - -/* Creates a deep copy of the source bitmap */ -CoglBitmap * -_cogl_bitmap_copy (CoglBitmap *src_bmp); - -gboolean -_cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height); - -CoglPixelFormat -_cogl_bitmap_get_format (CoglBitmap *bitmap); - -void -_cogl_bitmap_set_format (CoglBitmap *bitmap, - CoglPixelFormat format); - -int -_cogl_bitmap_get_width (CoglBitmap *bitmap); - -int -_cogl_bitmap_get_height (CoglBitmap *bitmap); - -int -_cogl_bitmap_get_rowstride (CoglBitmap *bitmap); - -/* Maps the bitmap so that the pixels can be accessed directly or if - the bitmap is just a memory bitmap then it just returns the pointer - to memory. Note that the bitmap isn't guaranteed to allocated to - the full size of rowstride*height so it is not safe to read up to - the rowstride of the last row. This will be the case if the user - uploads data using gdk_pixbuf_new_subpixbuf with a sub region - containing the last row of the pixbuf because in that case the - rowstride can be much larger than the width of the image */ -guint8 * -_cogl_bitmap_map (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints); - -void -_cogl_bitmap_unmap (CoglBitmap *bitmap); - -/* These two are replacements for map and unmap that should used when - the pointer is going to be passed to GL for pixel packing or - unpacking. The address might not be valid for reading if the bitmap - was created with new_from_buffer but it will however be good to - pass to glTexImage2D for example. The access should be READ for - unpacking and WRITE for packing. It can not be both */ -guint8 * -_cogl_bitmap_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints); - -void -_cogl_bitmap_unbind (CoglBitmap *bitmap); - -#endif /* __COGL_BITMAP_H */ diff --git a/clutter/cogl/cogl/cogl-bitmap.c b/clutter/cogl/cogl/cogl-bitmap.c deleted file mode 100644 index cc83dda..0000000 --- a/clutter/cogl/cogl/cogl-bitmap.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-bitmap-private.h" -#include "cogl-buffer-private.h" - -#include - -struct _CoglBitmap -{ - CoglHandleObject _parent; - CoglPixelFormat format; - int width; - int height; - int rowstride; - - guint8 *data; - CoglBitmapDestroyNotify destroy_fn; - void *destroy_fn_data; - - gboolean mapped; - gboolean bound; - - /* If this is non-null then 'data' is ignored and instead it is - fetched from this shared bitmap. */ - CoglBitmap *shared_bmp; - - /* If this is non-null then 'data' is treated as an offset into the - buffer and map will divert to mapping the buffer */ - CoglBuffer *buffer; -}; - -static void _cogl_bitmap_free (CoglBitmap *bmp); - -COGL_OBJECT_DEFINE (Bitmap, bitmap); - -static void -_cogl_bitmap_free (CoglBitmap *bmp) -{ - g_assert (!bmp->mapped); - g_assert (!bmp->bound); - - if (bmp->destroy_fn) - bmp->destroy_fn (bmp->data, bmp->destroy_fn_data); - - if (bmp->shared_bmp) - cogl_object_unref (bmp->shared_bmp); - - if (bmp->buffer) - cogl_object_unref (bmp->buffer); - - g_slice_free (CoglBitmap, bmp); -} - -int -_cogl_get_format_bpp (CoglPixelFormat format) -{ - int bpp_lut[] = { - 0, /* invalid */ - 1, /* A_8 */ - 3, /* 888 */ - 4, /* 8888 */ - 2, /* 565 */ - 2, /* 4444 */ - 2, /* 5551 */ - 2, /* YUV */ - 1 /* G_8 */ - }; - - return bpp_lut [format & COGL_UNORDERED_MASK]; -} - -gboolean -_cogl_bitmap_convert_premult_status (CoglBitmap *bmp, - CoglPixelFormat dst_format) -{ - /* Do we need to unpremultiply? */ - if ((bmp->format & COGL_PREMULT_BIT) > 0 && - (dst_format & COGL_PREMULT_BIT) == 0) - /* Try unpremultiplying using imaging library */ - return (_cogl_bitmap_unpremult (bmp) - /* ... or try fallback */ - || _cogl_bitmap_fallback_unpremult (bmp)); - - /* Do we need to premultiply? */ - if ((bmp->format & COGL_PREMULT_BIT) == 0 && - (dst_format & COGL_PREMULT_BIT) > 0) - /* Try premultiplying using imaging library */ - return (_cogl_bitmap_premult (bmp) - /* ... or try fallback */ - || _cogl_bitmap_fallback_premult (bmp)); - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_convert_format_and_premult (CoglBitmap *bmp, - CoglPixelFormat dst_format) -{ - CoglPixelFormat src_format = _cogl_bitmap_get_format (bmp); - CoglBitmap *dst_bmp; - - /* Is base format different (not considering premult status)? */ - if ((src_format & COGL_UNPREMULT_MASK) != - (dst_format & COGL_UNPREMULT_MASK)) - { - /* Try converting using imaging library */ - if ((dst_bmp = _cogl_bitmap_convert (bmp, dst_format)) == NULL) - { - /* ... or try fallback */ - if ((dst_bmp = _cogl_bitmap_fallback_convert (bmp, - dst_format)) == NULL) - return NULL; - } - } - else - { - int rowstride = _cogl_bitmap_get_rowstride (bmp); - int height = _cogl_bitmap_get_height (bmp); - guint8 *data; - - /* Copy the bitmap so that we can premultiply in-place */ - - if ((data = _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0)) == NULL) - return NULL; - - dst_bmp = _cogl_bitmap_new_from_data (g_memdup (data, height * rowstride), - src_format, - _cogl_bitmap_get_width (bmp), - height, - rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); - - _cogl_bitmap_unmap (bmp); - } - - src_format = _cogl_bitmap_get_format (dst_bmp); - - /* We only need to do a premult conversion if both formats have an - alpha channel. If we're converting from RGB to RGBA then the - alpha will have been filled with 255 so the premult won't do - anything or if we are converting from RGBA to RGB we're losing - information so either converting or not will be wrong for - transparent pixels */ - if ((src_format & COGL_A_BIT) == COGL_A_BIT && - (dst_format & COGL_A_BIT) == COGL_A_BIT && - !_cogl_bitmap_convert_premult_status (dst_bmp, dst_format)) - { - cogl_object_unref (dst_bmp); - return NULL; - } - - return dst_bmp; -} - -CoglBitmap * -_cogl_bitmap_copy (CoglBitmap *src_bmp) -{ - CoglBitmap *dst_bmp; - CoglPixelFormat src_format = _cogl_bitmap_get_format (src_bmp); - int bpp = _cogl_get_format_bpp (src_format); - int width = _cogl_bitmap_get_width (src_bmp); - int height = _cogl_bitmap_get_height (src_bmp); - int dst_rowstride = width * bpp; - - /* Round the rowstride up to the next nearest multiple of 4 bytes */ - dst_rowstride = (dst_rowstride + 3) & ~3; - - dst_bmp = _cogl_bitmap_new_from_data (g_malloc (dst_rowstride * height), - src_format, - width, height, - dst_rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); - - _cogl_bitmap_copy_subregion (src_bmp, - dst_bmp, - 0, 0, /* src_x/y */ - 0, 0, /* dst_x/y */ - width, height); - - return dst_bmp; -} - -void -_cogl_bitmap_copy_subregion (CoglBitmap *src, - CoglBitmap *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - guint8 *srcdata; - guint8 *dstdata; - int bpp; - int line; - - /* Intended only for fast copies when format is equal! */ - g_assert (src->format == dst->format); - bpp = _cogl_get_format_bpp (src->format); - - if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0))) - { - if ((dstdata = _cogl_bitmap_map (dst, COGL_BUFFER_ACCESS_WRITE, 0))) - { - srcdata += src_y * src->rowstride + src_x * bpp; - dstdata += dst_y * dst->rowstride + dst_x * bpp; - - for (line=0; linerowstride; - dstdata += dst->rowstride; - } - - _cogl_bitmap_unmap (dst); - } - - _cogl_bitmap_unmap (src); - } -} - -gboolean -cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height) -{ - return _cogl_bitmap_get_size_from_file (filename, width, height); -} - -CoglBitmap * -_cogl_bitmap_new_from_data (guint8 *data, - CoglPixelFormat format, - int width, - int height, - int rowstride, - CoglBitmapDestroyNotify destroy_fn, - void *destroy_fn_data) -{ - CoglBitmap *bmp = g_slice_new (CoglBitmap); - - bmp->format = format; - bmp->width = width; - bmp->height = height; - bmp->rowstride = rowstride; - bmp->data = data; - bmp->destroy_fn = destroy_fn; - bmp->destroy_fn_data = destroy_fn_data; - bmp->mapped = FALSE; - bmp->bound = FALSE; - bmp->shared_bmp = NULL; - bmp->buffer = NULL; - - return _cogl_bitmap_object_new (bmp); -} - -CoglBitmap * -_cogl_bitmap_new_shared (CoglBitmap *shared_bmp, - CoglPixelFormat format, - int width, - int height, - int rowstride) -{ - CoglBitmap *bmp = _cogl_bitmap_new_from_data (NULL, /* data */ - format, - width, - height, - rowstride, - NULL, /* destroy_fn */ - NULL /* destroy_fn_data */); - - bmp->shared_bmp = cogl_object_ref (shared_bmp); - - return bmp; -} - -CoglBitmap * -cogl_bitmap_new_from_file (const char *filename, - GError **error) -{ - CoglBitmap *bmp; - - g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); - - if ((bmp = _cogl_bitmap_from_file (filename, error)) == NULL) - { - /* Try fallback */ - if ((bmp = _cogl_bitmap_fallback_from_file (filename)) - && error && *error) - { - g_error_free (*error); - *error = NULL; - } - } - - return bmp; -} - -CoglBitmap * -_cogl_bitmap_new_from_buffer (CoglBuffer *buffer, - CoglPixelFormat format, - int width, - int height, - int rowstride, - int offset) -{ - CoglBitmap *bmp; - - g_return_val_if_fail (cogl_is_buffer (buffer), NULL); - - bmp = _cogl_bitmap_new_from_data (NULL, /* data */ - format, - width, - height, - rowstride, - NULL, /* destroy_fn */ - NULL /* destroy_fn_data */); - - bmp->buffer = cogl_object_ref (buffer); - bmp->data = GINT_TO_POINTER (offset); - - return bmp; -} - -CoglPixelFormat -_cogl_bitmap_get_format (CoglBitmap *bitmap) -{ - return bitmap->format; -} - -void -_cogl_bitmap_set_format (CoglBitmap *bitmap, - CoglPixelFormat format) -{ - bitmap->format = format; -} - -int -_cogl_bitmap_get_width (CoglBitmap *bitmap) -{ - return bitmap->width; -} - -GQuark -cogl_bitmap_error_quark (void) -{ - return g_quark_from_static_string ("cogl-bitmap-error-quark"); -} - -int -_cogl_bitmap_get_height (CoglBitmap *bitmap) -{ - return bitmap->height; -} - -int -_cogl_bitmap_get_rowstride (CoglBitmap *bitmap) -{ - return bitmap->rowstride; -} - -guint8 * -_cogl_bitmap_map (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_map (bitmap->shared_bmp, access, hints); - - g_assert (!bitmap->mapped); - - if (bitmap->buffer) - { - guint8 *data = cogl_buffer_map (bitmap->buffer, - access, - hints); - - COGL_NOTE (BITMAP, "A pixel array is being mapped from a bitmap. This " - "usually means that some conversion on the pixel array is " - "needed so a sub-optimal format is being used."); - - if (data) - { - bitmap->mapped = TRUE; - - return data + GPOINTER_TO_INT (bitmap->data); - } - else - return NULL; - } - else - { - bitmap->mapped = TRUE; - - return bitmap->data; - } -} - -void -_cogl_bitmap_unmap (CoglBitmap *bitmap) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_unmap (bitmap->shared_bmp); - - g_assert (bitmap->mapped); - bitmap->mapped = FALSE; - - if (bitmap->buffer) - cogl_buffer_unmap (bitmap->buffer); -} - -guint8 * -_cogl_bitmap_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints) -{ - guint8 *ptr; - - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_bind (bitmap->shared_bmp, access, hints); - - g_assert (!bitmap->bound); - - /* If the bitmap wasn't created from a buffer then the - implementation of bind is the same as map */ - if (bitmap->buffer == NULL) - { - guint8 *data = _cogl_bitmap_map (bitmap, access, hints); - if (data) - bitmap->bound = TRUE; - return data; - } - - bitmap->bound = TRUE; - - if (access == COGL_BUFFER_ACCESS_READ) - ptr = _cogl_buffer_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK); - else if (access == COGL_BUFFER_ACCESS_WRITE) - ptr = _cogl_buffer_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_PACK); - else - g_assert_not_reached (); - - /* The data pointer actually stores the offset */ - return GPOINTER_TO_INT (bitmap->data) + ptr; -} - -void -_cogl_bitmap_unbind (CoglBitmap *bitmap) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_unbind (bitmap->shared_bmp); - - g_assert (bitmap->bound); - bitmap->bound = FALSE; - - /* If the bitmap wasn't created from a pixel array then the - implementation of unbind is the same as unmap */ - if (bitmap->buffer) - _cogl_buffer_unbind (bitmap->buffer); - else - _cogl_bitmap_unmap (bitmap); -} diff --git a/clutter/cogl/cogl/cogl-bitmap.h b/clutter/cogl/cogl/cogl-bitmap.h deleted file mode 100644 index 1983802..0000000 --- a/clutter/cogl/cogl/cogl-bitmap.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_BITMAP_H__ -#define __COGL_BITMAP_H__ - -#include - -G_BEGIN_DECLS - -typedef struct _CoglBitmap CoglBitmap; - -/** - * SECTION:cogl-bitmap - * @short_description: Fuctions for loading images - * - * Cogl allows loading image data into memory as CoglBitmaps without - * loading them immediately into GPU textures. - * - * #CoglBitmap is available since Cogl 1.0 - */ - - -/** - * cogl_bitmap_new_from_file: - * @filename: the file to load. - * @error: a #GError or %NULL. - * - * Loads an image file from disk. This function can be safely called from - * within a thread. - * - * Return value: a #CoglBitmap to the new loaded image data, or - * %NULL if loading the image failed. - * - * Since: 1.0 - */ -CoglBitmap * -cogl_bitmap_new_from_file (const char *filename, - GError **error); - -/** - * cogl_bitmap_get_size_from_file: - * @filename: the file to check - * @width: (out): return location for the bitmap width, or %NULL - * @height: (out): return location for the bitmap height, or %NULL - * - * Parses an image file enough to extract the width and height - * of the bitmap. - * - * Return value: %TRUE if the image was successfully parsed - * - * Since: 1.0 - */ -gboolean -cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height); - -/** - * cogl_is_bitmap: - * @handle: a #CoglHandle for a bitmap - * - * Checks whether @handle is a #CoglHandle for a bitmap - * - * Return value: %TRUE if the passed handle represents a bitmap, - * and %FALSE otherwise - * - * Since: 1.0 - */ -gboolean -cogl_is_bitmap (CoglHandle handle); - -/** - * COGL_BITMAP_ERROR: - * - * #GError domain for bitmap errors. - * - * Since: 1.4 - */ -#define COGL_BITMAP_ERROR (cogl_bitmap_error_quark ()) - -/** - * CoglBitmapError: - * @COGL_BITMAP_ERROR_FAILED: Generic failure code, something went - * wrong. - * @COGL_BITMAP_ERROR_UNKNOWN_TYPE: Unknown image type. - * @COGL_BITMAP_ERROR_CORRUPT_IMAGE: An image file was broken somehow. - * - * Error codes that can be thrown when performing bitmap - * operations. Note that gdk_pixbuf_new_from_file() can also throw - * errors directly from the underlying image loading library. For - * example, if GdkPixbuf is used then errors #GdkPixbufErrors - * will be used directly. - * - * Since: 1.4 - */ -typedef enum { - COGL_BITMAP_ERROR_FAILED, - COGL_BITMAP_ERROR_UNKNOWN_TYPE, - COGL_BITMAP_ERROR_CORRUPT_IMAGE -} CoglBitmapError; - -GQuark cogl_bitmap_error_quark (void); - -G_END_DECLS - -#endif /* __COGL_BITMAP_H__ */ diff --git a/clutter/cogl/cogl/cogl-bitmask.c b/clutter/cogl/cogl/cogl-bitmask.c deleted file mode 100644 index 568d549..0000000 --- a/clutter/cogl/cogl/cogl-bitmask.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "cogl-bitmask.h" - -gboolean -_cogl_bitmask_get_from_array (const CoglBitmask *bitmask, - unsigned int bit_num) -{ - GArray *array = (GArray *) *bitmask; - - /* If the index is off the end of the array then assume the bit is - not set */ - if (bit_num >= sizeof (unsigned int) * 8 * array->len) - return FALSE; - else - return !!(g_array_index (array, unsigned int, - bit_num / (sizeof (unsigned int) * 8)) & - (1 << (bit_num % (sizeof (unsigned int) * 8)))); -} - -static void -_cogl_bitmask_convert_to_array (CoglBitmask *bitmask) -{ - GArray *array; - /* Fetch the old values, ignoring the least significant bit */ - unsigned int old_values = GPOINTER_TO_UINT (*bitmask) >> 1; - - array = g_array_new (FALSE, TRUE, sizeof (unsigned int)); - /* Copy the old values back in */ - g_array_append_val (array, old_values); - - *bitmask = (struct _CoglBitmaskImaginaryType *) array; -} - -void -_cogl_bitmask_set_in_array (CoglBitmask *bitmask, - unsigned int bit_num, - gboolean value) -{ - GArray *array; - unsigned int array_index, new_value_mask; - - /* If the bitmask is not already an array then we need to allocate one */ - if (!_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_convert_to_array (bitmask); - - array = (GArray *) *bitmask; - - array_index = bit_num / (sizeof (unsigned int) * 8); - /* Grow the array if necessary. This will clear the new data */ - if (array_index >= array->len) - g_array_set_size (array, array_index + 1); - - new_value_mask = 1 << (bit_num % (sizeof (unsigned int) * 8)); - - if (value) - g_array_index (array, unsigned int, array_index) |= new_value_mask; - else - g_array_index (array, unsigned int, array_index) &= ~new_value_mask; -} - -void -_cogl_bitmask_set_bits (CoglBitmask *dst, - const CoglBitmask *src) -{ - if (_cogl_bitmask_has_array (src)) - { - GArray *src_array, *dst_array; - int i; - - if (!_cogl_bitmask_has_array (dst)) - _cogl_bitmask_convert_to_array (dst); - - dst_array = (GArray *) *dst; - src_array = (GArray *) *src; - - if (dst_array->len < src_array->len) - g_array_set_size (dst_array, src_array->len); - - for (i = 0; i < src_array->len; i++) - g_array_index (dst_array, unsigned int, i) |= - g_array_index (src_array, unsigned int, i); - } - else if (_cogl_bitmask_has_array (dst)) - { - GArray *dst_array; - - dst_array = (GArray *) *dst; - - g_array_index (dst_array, unsigned int, 0) |= - (GPOINTER_TO_UINT (*src) >> 1); - } - else - *dst = GUINT_TO_POINTER (GPOINTER_TO_UINT (*dst) | - GPOINTER_TO_UINT (*src)); -} - -void -_cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value) -{ - GArray *array; - unsigned int array_index, bit_index; - - if (n_bits == 0) - return; - - /* If the bitmask is not already an array then we need to allocate one */ - if (!_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_convert_to_array (bitmask); - - array = (GArray *) *bitmask; - - /* Get the array index of the top most value that will be touched */ - array_index = (n_bits - 1) / (sizeof (unsigned int) * 8); - /* Get the bit index of the top most value */ - bit_index = (n_bits - 1) % (sizeof (unsigned int) * 8); - /* Grow the array if necessary. This will clear the new data */ - if (array_index >= array->len) - g_array_set_size (array, array_index + 1); - - if (value) - { - /* Set the bits that are touching this index */ - g_array_index (array, unsigned int, array_index) |= - ~(unsigned int) 0 >> (sizeof (unsigned int) * 8 - 1 - bit_index); - - /* Set all of the bits in any lesser indices */ - memset (array->data, 0xff, sizeof (unsigned int) * array_index); - } - else - { - /* Clear the bits that are touching this index */ - g_array_index (array, unsigned int, array_index) &= - ~(unsigned int) 1 << bit_index; - - /* Clear all of the bits in any lesser indices */ - memset (array->data, 0x00, sizeof (unsigned int) * array_index); - } -} - -void -_cogl_bitmask_xor_bits (CoglBitmask *dst, - const CoglBitmask *src) -{ - if (_cogl_bitmask_has_array (src)) - { - GArray *src_array, *dst_array; - int i; - - if (!_cogl_bitmask_has_array (dst)) - _cogl_bitmask_convert_to_array (dst); - - dst_array = (GArray *) *dst; - src_array = (GArray *) *src; - - if (dst_array->len < src_array->len) - g_array_set_size (dst_array, src_array->len); - - for (i = 0; i < src_array->len; i++) - g_array_index (dst_array, unsigned int, i) ^= - g_array_index (src_array, unsigned int, i); - } - else if (_cogl_bitmask_has_array (dst)) - { - GArray *dst_array; - - dst_array = (GArray *) *dst; - - g_array_index (dst_array, unsigned int, 0) ^= - (GPOINTER_TO_UINT (*src) >> 1); - } - else - *dst = GUINT_TO_POINTER ((GPOINTER_TO_UINT (*dst) ^ - GPOINTER_TO_UINT (*src)) | 1); -} - -void -_cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask) -{ - GArray *array = (GArray *) *bitmask; - - memset (array->data, 0, sizeof (unsigned int) * array->len); -} - -void -_cogl_bitmask_foreach (const CoglBitmask *bitmask, - CoglBitmaskForeachFunc func, - gpointer user_data) -{ - if (_cogl_bitmask_has_array (bitmask)) - { - GArray *array = (GArray *) *bitmask; - int array_index; - - for (array_index = 0; array_index < array->len; array_index++) - { - unsigned int mask = g_array_index (array, unsigned int, array_index); - int bit = 0; - - while (mask) - { - if (mask & 1) - func (array_index * sizeof (unsigned int) * 8 + bit, user_data); - - bit++; - mask >>= 1; - } - } - } - else - { - unsigned int mask = GPOINTER_TO_UINT (*bitmask) >> 1; - int bit = 0; - - while (mask) - { - if (mask & 1) - func (bit, user_data); - - bit++; - mask >>= 1; - } - } -} diff --git a/clutter/cogl/cogl/cogl-bitmask.h b/clutter/cogl/cogl/cogl-bitmask.h deleted file mode 100644 index d3c36a4..0000000 --- a/clutter/cogl/cogl/cogl-bitmask.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_BITMASK_H -#define __COGL_BITMASK_H - -#include - -G_BEGIN_DECLS - -/* - * CoglBitmask implements a growable array of bits. A CoglBitmask can - * be allocated on the stack but it must be initialised with - * _cogl_bitmask_init() before use and then destroyed with - * _cogl_bitmask_destroy(). A CoglBitmask will try to avoid allocating - * any memory unless more than 31 bits are needed. - * - * Internally a CoglBitmask is a pointer. If the least significant bit - * of the pointer is 1 then the rest of the bits are directly used as - * part of the bitmask, otherwise it is a pointer to a GArray of - * unsigned ints. This relies on the fact the g_malloc will return a - * pointer aligned to at least two bytes (so that the least - * significant bit of the address is always 0) - * - * If the maximum possible bit number in the set is known at compile - * time, it may make more sense to use the macros in cogl-flags.h - * instead of this type. - */ - -typedef struct _CoglBitmaskImaginaryType *CoglBitmask; - -/* Internal helper macro to determine whether this bitmask has a - GArray allocated or whether the pointer is just used directly */ -#define _cogl_bitmask_has_array(bitmask) \ - (!(GPOINTER_TO_UINT (*bitmask) & 1)) - -/* Number of bits we can use before needing to allocate an array */ -#define COGL_BITMASK_MAX_DIRECT_BITS (sizeof (unsigned int) * 8 - 1) - -/* - * _cogl_bitmask_init: - * @bitmask: A pointer to a bitmask - * - * Initialises the cogl bitmask. This must be called before any other - * bitmask functions are called. Initially all of the values are - * zero - */ -/* Set the last significant bit to mark that no array has been - allocated yet */ -#define _cogl_bitmask_init(bitmask) \ - G_STMT_START { *(bitmask) = GUINT_TO_POINTER (1); } G_STMT_END - -gboolean -_cogl_bitmask_get_from_array (const CoglBitmask *bitmask, - unsigned int bit_num); - -void -_cogl_bitmask_set_in_array (CoglBitmask *bitmask, - unsigned int bit_num, - gboolean value); - -void -_cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value); - -void -_cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask); - -/* - * cogl_bitmask_set_bits: - * @dst: The bitmask to modify - * @src: The bitmask to copy bits from - * - * This makes sure that all of the bits that are set in @src are also - * set in @dst. Any unset bits in @src are left alone in @dst. - */ -void -_cogl_bitmask_set_bits (CoglBitmask *dst, - const CoglBitmask *src); - -/* - * cogl_bitmask_xor_bits: - * @dst: The bitmask to modify - * @src: The bitmask to copy bits from - * - * For every bit that is set in src, the corresponding bit in dst is - * inverted. - */ -void -_cogl_bitmask_xor_bits (CoglBitmask *dst, - const CoglBitmask *src); - -typedef void (* CoglBitmaskForeachFunc) (int bit_num, gpointer user_data); - -/* - * cogl_bitmask_foreach: - * @bitmask: A pointer to a bitmask - * @func: A callback function - * @user_data: A pointer to pass to the callback - * - * This calls @func for each bit that is set in @bitmask. - */ -void -_cogl_bitmask_foreach (const CoglBitmask *bitmask, - CoglBitmaskForeachFunc func, - gpointer user_data); - -/* - * _cogl_bitmask_get: - * @bitmask: A pointer to a bitmask - * @bit_num: A bit number - * - * Return value: whether bit number @bit_num is set in @bitmask - */ -static inline gboolean -_cogl_bitmask_get (const CoglBitmask *bitmask, unsigned int bit_num) -{ - if (_cogl_bitmask_has_array (bitmask)) - return _cogl_bitmask_get_from_array (bitmask, bit_num); - else if (bit_num >= COGL_BITMASK_MAX_DIRECT_BITS) - return FALSE; - else - return !!(GPOINTER_TO_UINT (*bitmask) & (1 << (bit_num + 1))); -} - -/* - * _cogl_bitmask_set: - * @bitmask: A pointer to a bitmask - * @bit_num: A bit number - * @value: The new value - * - * Sets or resets a bit number @bit_num in @bitmask according to @value. - */ -static inline void -_cogl_bitmask_set (CoglBitmask *bitmask, unsigned int bit_num, gboolean value) -{ - if (_cogl_bitmask_has_array (bitmask) || - bit_num >= COGL_BITMASK_MAX_DIRECT_BITS) - _cogl_bitmask_set_in_array (bitmask, bit_num, value); - else if (value) - *bitmask = GUINT_TO_POINTER (GPOINTER_TO_UINT (*bitmask) | - (1 << (bit_num + 1))); - else - *bitmask = GUINT_TO_POINTER (GPOINTER_TO_UINT (*bitmask) & - ~(1 << (bit_num + 1))); -} - -/* - * _cogl_bitmask_set_range: - * @bitmask: A pointer to a bitmask - * @n_bits: The number of bits to set - * @value: The value to set - * - * Sets the first @n_bits in @bitmask to @value. - */ -static inline void -_cogl_bitmask_set_range (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value) -{ - if (_cogl_bitmask_has_array (bitmask) || - n_bits > COGL_BITMASK_MAX_DIRECT_BITS) - _cogl_bitmask_set_range_in_array (bitmask, n_bits, value); - else if (value) - *bitmask = GUINT_TO_POINTER (GPOINTER_TO_UINT (*bitmask) | - ~(~(unsigned int) 1 << n_bits)); - else - *bitmask = GUINT_TO_POINTER (GPOINTER_TO_UINT (*bitmask) & - ((~(unsigned int) 1 << n_bits) | 1)); -} - -/* - * _cogl_bitmask_destroy: - * @bitmask: A pointer to a bitmask - * - * Destroys any resources allocated by the bitmask - */ -static inline void -_cogl_bitmask_destroy (CoglBitmask *bitmask) -{ - if (_cogl_bitmask_has_array (bitmask)) - g_array_free ((GArray *) *bitmask, TRUE); -} - -/* - * _cogl_bitmask_clear_all: - * @bitmask: A pointer to a bitmask - * - * Clears all the bits in a bitmask without destroying any resources. - */ -static inline void -_cogl_bitmask_clear_all (CoglBitmask *bitmask) -{ - if (_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_clear_all_in_array (bitmask); - else - *bitmask = GUINT_TO_POINTER (1); -} - -G_END_DECLS - -#endif /* __COGL_BITMASK_H */ - diff --git a/clutter/cogl/cogl/cogl-blend-string.c b/clutter/cogl/cogl/cogl-blend-string.c deleted file mode 100644 index 921b809..0000000 --- a/clutter/cogl/cogl/cogl-blend-string.c +++ /dev/null @@ -1,984 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-debug.h" -#include "cogl-blend-string.h" - -typedef enum _ParserState -{ - PARSER_STATE_EXPECT_DEST_CHANNELS, - PARSER_STATE_SCRAPING_DEST_CHANNELS, - PARSER_STATE_EXPECT_FUNCTION_NAME, - PARSER_STATE_SCRAPING_FUNCTION_NAME, - PARSER_STATE_EXPECT_ARG_START, - PARSER_STATE_EXPECT_STATEMENT_END -} ParserState; - -typedef enum _ParserArgState -{ - PARSER_ARG_STATE_START, - PARSER_ARG_STATE_EXPECT_MINUS, - PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME, - PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME, - PARSER_ARG_STATE_MAYBE_COLOR_MASK, - PARSER_ARG_STATE_SCRAPING_MASK, - PARSER_ARG_STATE_MAYBE_MULT, - PARSER_ARG_STATE_EXPECT_OPEN_PAREN, - PARSER_ARG_STATE_EXPECT_FACTOR, - PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE, - PARSER_ARG_STATE_MAYBE_MINUS, - PARSER_ARG_STATE_EXPECT_CLOSE_PAREN, - PARSER_ARG_STATE_EXPECT_END -} ParserArgState; - - -#define DEFINE_COLOR_SOURCE(NAME, NAME_LEN) \ - {/*.type = */COGL_BLEND_STRING_COLOR_SOURCE_ ## NAME, \ - /*.name = */#NAME, \ - /*.name_len = */NAME_LEN} - -static CoglBlendStringColorSourceInfo blending_color_sources[] = { - DEFINE_COLOR_SOURCE (SRC_COLOR, 9), - DEFINE_COLOR_SOURCE (DST_COLOR, 9), - DEFINE_COLOR_SOURCE (CONSTANT, 8) -}; - -static CoglBlendStringColorSourceInfo tex_combine_color_sources[] = { - DEFINE_COLOR_SOURCE (TEXTURE, 7), - /* DEFINE_COLOR_SOURCE (TEXTURE_N, *) - handled manually */ - DEFINE_COLOR_SOURCE (PRIMARY, 7), - DEFINE_COLOR_SOURCE (CONSTANT, 8), - DEFINE_COLOR_SOURCE (PREVIOUS, 8) -}; - -static CoglBlendStringColorSourceInfo tex_combine_texture_n_color_source = { - /*.type = */COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N, - /*.name = */"TEXTURE_N", - /*.name_len = */0 -}; - -#undef DEFINE_COLOR_SOURCE - -#define DEFINE_FUNCTION(NAME, NAME_LEN, ARGC) \ - { /*.type = */COGL_BLEND_STRING_FUNCTION_ ## NAME, \ - /*.name = */#NAME, \ - /*.name_len = */NAME_LEN, \ - /*.argc = */ARGC } - -/* NB: These must be sorted so any name that's a subset of another - * comes later than the longer name. */ -static CoglBlendStringFunctionInfo tex_combine_functions[] = { - DEFINE_FUNCTION (REPLACE, 7, 1), - DEFINE_FUNCTION (MODULATE, 8, 2), - DEFINE_FUNCTION (ADD_SIGNED, 10, 2), - DEFINE_FUNCTION (ADD, 3, 2), - DEFINE_FUNCTION (INTERPOLATE, 11, 3), - DEFINE_FUNCTION (SUBTRACT, 8, 2), - DEFINE_FUNCTION (DOT3_RGBA, 9, 2), - DEFINE_FUNCTION (DOT3_RGB, 8, 2) -}; - -static CoglBlendStringFunctionInfo blend_functions[] = { - DEFINE_FUNCTION (ADD, 3, 2) -}; - -#undef DEFINE_FUNCTION - -GQuark -cogl_blend_string_error_quark (void) -{ - return g_quark_from_static_string ("cogl-blend-string-error-quark"); -} - -void -_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, - CoglBlendStringStatement *rgb, - CoglBlendStringStatement *a) -{ - int i; - - memcpy (rgb, statement, sizeof (CoglBlendStringStatement)); - memcpy (a, statement, sizeof (CoglBlendStringStatement)); - - rgb->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - - for (i = 0; i < statement->function->argc; i++) - { - CoglBlendStringArgument *arg = &statement->args[i]; - CoglBlendStringArgument *rgb_arg = &rgb->args[i]; - CoglBlendStringArgument *a_arg = &a->args[i]; - - if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - rgb_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - } - - if (arg->factor.is_color && - arg->factor.source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - rgb_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - } - } -} - -static gboolean -validate_tex_combine_statements (CoglBlendStringStatement *statements, - int n_statements, - GError **error) -{ - int i, j; - const char *error_string; - CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; - - for (i = 0; i < n_statements; i++) - { - for (j = 0; j < statements[i].function->argc; j++) - { - CoglBlendStringArgument *arg = &statements[i].args[j]; - if (arg->source.is_zero) - { - error_string = "You can't use the constant '0' as a texture " - "combine argument"; - goto error; - } - if (!arg->factor.is_one) - { - error_string = "Argument factors are only relevant to blending " - "not texture combining"; - goto error; - } - } - } - - return TRUE; - -error: - g_set_error (error, - COGL_BLEND_STRING_ERROR, - detail, - "Invalid texture combine string: %s", - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Invalid texture combine string: %s", - error_string); - } - return FALSE; -} - -static gboolean -validate_blend_statements (CoglBlendStringStatement *statements, - int n_statements, - GError **error) -{ - int i, j; - const char *error_string; - CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; - -#ifdef HAVE_COGL_GL - _COGL_GET_CONTEXT (ctx, 0); -#endif - -#ifdef HAVE_COGL_GL - if (n_statements == 2) - { - /* glBlendEquationSeperate is GL 2.0 only */ - if (!ctx->drv.pf_glBlendEquationSeparate && - statements[0].function->type != statements[1].function->type) - { - error_string = "Separate blend functions for the RGB an A " - "channels isn't supported by the driver"; - detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; - goto error; - } - } -#elif defined(HAVE_COGL_GLES) - if (n_statements != 1) - { - error_string = "Separate blend functions for the RGB an A " - "channels isn't supported by the GLES 1"; - detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; - goto error; - } -#endif - - for (i = 0; i < n_statements; i++) - for (j = 0; j < statements[i].function->argc; j++) - { - CoglBlendStringArgument *arg = &statements[i].args[j]; - - if (arg->source.is_zero) - continue; - - if ((j == 0 && - arg->source.info->type != - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR) - || (j == 1 && - arg->source.info->type != - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR)) - { - error_string = "For blending you must always use SRC_COLOR " - "for arg0 and DST_COLOR for arg1"; - goto error; - } - -#ifdef HAVE_COGL_GLES - if (arg->factor.is_color && - arg->factor.source.info->type == COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT) - { - error_string = "GLES Doesn't support constant blend factors"; - detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; - goto error; - } -#endif - } - - return TRUE; - -error: - g_set_error (error, - COGL_BLEND_STRING_ERROR, - detail, - "Invalid blend string: %s", - error_string); - return FALSE; -} - -static gboolean -validate_statements_for_context (CoglBlendStringStatement *statements, - int n_statements, - CoglBlendStringContext context, - GError **error) -{ - const char *error_string; - - if (n_statements == 1) - { - if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - error_string = "You need to also give a blend statement for the RGB" - "channels"; - goto error; - } - else if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB) - { - error_string = "You need to also give a blend statement for the " - "Alpha channel"; - goto error; - } - } - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - return validate_blend_statements (statements, n_statements, error); - else - return validate_tex_combine_statements (statements, n_statements, error); - -error: - g_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_INVALID_ERROR, - "Invalid %s string: %s", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Invalid %s string: %s", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - error_string); - } - - return FALSE; -} - -static void -print_argument (CoglBlendStringArgument *arg) -{ - const char *mask_names[] = { - "RGB", - "A", - "RGBA" - }; - - g_print (" Arg:\n"); - g_print (" is zero = %s\n", arg->source.is_zero ? "yes" : "no"); - if (!arg->source.is_zero) - { - g_print (" color source = %s\n", arg->source.info->name); - g_print (" one minus = %s\n", arg->source.one_minus ? "yes" : "no"); - g_print (" mask = %s\n", mask_names[arg->source.mask]); - g_print (" texture = %d\n", arg->source.texture); - g_print ("\n"); - g_print (" factor is_one = %s\n", arg->factor.is_one ? "yes" : "no"); - g_print (" factor is_src_alpha_saturate = %s\n", - arg->factor.is_src_alpha_saturate ? "yes" : "no"); - g_print (" factor is_color = %s\n", arg->factor.is_color ? "yes" : "no"); - if (arg->factor.is_color) - { - g_print (" factor color:is zero = %s\n", - arg->factor.source.is_zero ? "yes" : "no"); - g_print (" factor color:color source = %s\n", - arg->factor.source.info->name); - g_print (" factor color:one minus = %s\n", - arg->factor.source.one_minus ? "yes" : "no"); - g_print (" factor color:mask = %s\n", - mask_names[arg->factor.source.mask]); - g_print (" factor color:texture = %d\n", - arg->factor.source.texture); - } - } -} - -static void -print_statement (int num, CoglBlendStringStatement *statement) -{ - const char *mask_names[] = { - "RGB", - "A", - "RGBA" - }; - int i; - g_print ("Statement %d:\n", num); - g_print (" Destination channel mask = %s\n", - mask_names[statement->mask]); - g_print (" Function = %s\n", statement->function->name); - for (i = 0; i < statement->function->argc; i++) - print_argument (&statement->args[i]); -} - -static const CoglBlendStringFunctionInfo * -get_function_info (const char *mark, - const char *p, - CoglBlendStringContext context) -{ - gsize len = p - mark; - CoglBlendStringFunctionInfo *functions; - gsize array_len; - int i; - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - { - functions = blend_functions; - array_len = G_N_ELEMENTS (blend_functions); - } - else - { - functions = tex_combine_functions; - array_len = G_N_ELEMENTS (tex_combine_functions); - } - - for (i = 0; i < array_len; i++) - { - if (len >= functions[i].name_len - && strncmp (mark, functions[i].name, functions[i].name_len) == 0) - return &functions[i]; - } - return NULL; -} - -static const CoglBlendStringColorSourceInfo * -get_color_src_info (const char *mark, - const char *p, - CoglBlendStringContext context) -{ - gsize len = p - mark; - CoglBlendStringColorSourceInfo *sources; - gsize array_len; - int i; - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - { - sources = blending_color_sources; - array_len = G_N_ELEMENTS (blending_color_sources); - } - else - { - sources = tex_combine_color_sources; - array_len = G_N_ELEMENTS (tex_combine_color_sources); - } - - for (i = 0; i < array_len; i++) - { - if (len >= sources[i].name_len - && strncmp (mark, sources[i].name, sources[i].name_len) == 0) - return &sources[i]; - } - - if (len >= 9 && - strncmp (mark, "TEXTURE_", 8) == 0 && - g_ascii_isdigit (mark[8])) - { - return &tex_combine_texture_n_color_source; - } - - return NULL; -} - -static gboolean -is_symbol_char (const char c) -{ - return (g_ascii_isalpha (c) || c == '_') ? TRUE : FALSE; -} - -static gboolean -is_alphanum_char (const char c) -{ - return (g_ascii_isalnum (c) || c == '_') ? TRUE : FALSE; -} - -static gboolean -parse_argument (const char *string, /* original user string */ - const char **ret_p, /* start of argument IN:OUT */ - const CoglBlendStringStatement *statement, - int current_arg, - CoglBlendStringArgument *arg, /* OUT */ - CoglBlendStringContext context, - GError **error) -{ - const char *p = *ret_p; - const char *mark = NULL; - const char *error_string = NULL; - ParserArgState state = PARSER_ARG_STATE_START; - gboolean parsing_factor = FALSE; - - arg->source.is_zero = FALSE; - arg->source.info = NULL; - arg->source.texture = 0; - arg->source.one_minus = FALSE; - arg->source.mask = statement->mask; - - arg->factor.is_one = FALSE; - arg->factor.is_color = FALSE; - arg->factor.is_src_alpha_saturate = FALSE; - - arg->factor.source.is_zero = FALSE; - arg->factor.source.info = NULL; - arg->factor.source.texture = 0; - arg->factor.source.one_minus = FALSE; - arg->factor.source.mask = statement->mask; - - do - { - if (g_ascii_isspace (*p)) - continue; - - if (*p == '\0') - { - error_string = "Unexpected end of string while parsing argument"; - goto error; - } - - switch (state) - { - case PARSER_ARG_STATE_START: - if (*p == '1') - state = PARSER_ARG_STATE_EXPECT_MINUS; - else if (*p == '0') - { - arg->source.is_zero = TRUE; - state = PARSER_ARG_STATE_EXPECT_END; - } - else - { - p--; /* backtrack */ - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - } - continue; - - case PARSER_ARG_STATE_EXPECT_MINUS: - if (*p != '-') - { - error_string = "expected a '-' following the 1"; - goto error; - } - arg->source.one_minus = TRUE; - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - continue; - - case PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME: - if (!is_symbol_char (*p)) - { - error_string = "expected a color source name"; - goto error; - } - state = PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME; - mark = p; - if (parsing_factor) - arg->factor.is_color = TRUE; - - /* fall through */ - case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME: - if (!is_symbol_char (*p)) - { - CoglBlendStringColorSource *source = - parsing_factor ? &arg->factor.source : &arg->source; - source->info = get_color_src_info (mark, p, context); - if (!source->info) - { - error_string = "Unknown color source name"; - goto error; - } - if (source->info->type == - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N) - { - char *endp; - source->texture = - strtoul (&mark[strlen ("TEXTURE_")], &endp, 10); - if (mark == endp) - { - error_string = "invalid texture number given with " - "TEXTURE_N color source"; - goto error; - } - p = endp; - } - state = PARSER_ARG_STATE_MAYBE_COLOR_MASK; - } - else - continue; - - /* fall through */ - case PARSER_ARG_STATE_MAYBE_COLOR_MASK: - if (*p != '[') - { - p--; /* backtrack */ - if (!parsing_factor) - state = PARSER_ARG_STATE_MAYBE_MULT; - else - state = PARSER_ARG_STATE_EXPECT_END; - continue; - } - state = PARSER_ARG_STATE_SCRAPING_MASK; - mark = p; - - /* fall through */ - case PARSER_ARG_STATE_SCRAPING_MASK: - if (*p == ']') - { - gsize len = p - mark; - CoglBlendStringColorSource *source = - parsing_factor ? &arg->factor.source : &arg->source; - - if (len == 5 && strncmp (mark, "[RGBA", len) == 0) - { - if (statement->mask != COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - error_string = "You can't use an RGBA color mask if the " - "statement hasn't also got an RGBA= mask"; - goto error; - } - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA; - } - else if (len == 4 && strncmp (mark, "[RGB", len) == 0) - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - else if (len == 2 && strncmp (mark, "[A", len) == 0) - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - else - { - error_string = "Expected a channel mask of [RGBA]" - "[RGB] or [A]"; - goto error; - } - if (parsing_factor) - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - else - state = PARSER_ARG_STATE_MAYBE_MULT; - } - continue; - - case PARSER_ARG_STATE_EXPECT_OPEN_PAREN: - if (*p != '(') - { - error_string = "Expected '(' before blend factor - the parser " - "currently requires that all blend factors " - "following a '*' be surrounded in brackets"; - goto error; - } - parsing_factor = TRUE; - state = PARSER_ARG_STATE_EXPECT_FACTOR; - continue; - - case PARSER_ARG_STATE_EXPECT_FACTOR: - if (*p == '1') - state = PARSER_ARG_STATE_MAYBE_MINUS; - else if (*p == '0') - { - arg->source.is_zero = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - else - { - state = PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE; - mark = p; - } - continue; - - case PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE: - if (!is_symbol_char (*p)) - { - gsize len = p - mark; - if (len >= strlen ("SRC_ALPHA_SATURATE") && - strncmp (mark, "SRC_ALPHA_SATURATE", len) == 0) - { - arg->factor.is_src_alpha_saturate = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - else - { - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - p = mark - 1; /* backtrack */ - } - } - continue; - - case PARSER_ARG_STATE_MAYBE_MINUS: - if (*p == '-') - { - arg->factor.source.one_minus = TRUE; - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - } - else - { - arg->factor.is_one = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - continue; - - case PARSER_ARG_STATE_EXPECT_CLOSE_PAREN: - if (*p != ')') - { - error_string = "Expected closing parenthesis after blend factor"; - goto error; - } - state = PARSER_ARG_STATE_EXPECT_END; - continue; - - case PARSER_ARG_STATE_MAYBE_MULT: - if (*p == '*') - { - state = PARSER_ARG_STATE_EXPECT_OPEN_PAREN; - continue; - } - arg->factor.is_one = TRUE; - state = PARSER_ARG_STATE_EXPECT_END; - - /* fall through */ - case PARSER_ARG_STATE_EXPECT_END: - if (*p != ',' && *p != ')') - { - error_string = "expected , or )"; - goto error; - } - - *ret_p = p - 1; - return TRUE; - } - } - while (p++); - -error: - { - int offset = p - string; - g_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, - "Syntax error for argument %d at offset %d: %s", - current_arg, - offset, - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Syntax error for argument %d at offset %d: %s", - current_arg, offset, error_string); - } - return FALSE; - } -} - -int -_cogl_blend_string_compile (const char *string, - CoglBlendStringContext context, - CoglBlendStringStatement *statements, - GError **error) -{ - const char *p = string; - const char *mark = NULL; - const char *error_string; - ParserState state = PARSER_STATE_EXPECT_DEST_CHANNELS; - CoglBlendStringStatement *statement = statements; - int current_statement = 0; - int current_arg = 0; - int remaining_argc = 0; - -#if 0 - COGL_DEBUG_SET_FLAG (COGL_DEBUG_BLEND_STRINGS); -#endif - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - COGL_NOTE (BLEND_STRINGS, "Compiling %s string:\n%s\n", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - string); - } - - do - { - if (g_ascii_isspace (*p)) - continue; - - if (*p == '\0') - { - switch (state) - { - case PARSER_STATE_EXPECT_DEST_CHANNELS: - if (current_statement != 0) - goto finished; - error_string = "Empty statement"; - goto error; - case PARSER_STATE_SCRAPING_DEST_CHANNELS: - error_string = "Expected an '=' following the destination " - "channel mask"; - goto error; - case PARSER_STATE_EXPECT_FUNCTION_NAME: - error_string = "Expected a function name"; - goto error; - case PARSER_STATE_SCRAPING_FUNCTION_NAME: - error_string = "Expected parenthesis after the function name"; - goto error; - case PARSER_STATE_EXPECT_ARG_START: - error_string = "Expected to find the start of an argument"; - goto error; - case PARSER_STATE_EXPECT_STATEMENT_END: - error_string = "Expected closing parenthesis for statement"; - goto error; - } - } - - switch (state) - { - case PARSER_STATE_EXPECT_DEST_CHANNELS: - mark = p; - state = PARSER_STATE_SCRAPING_DEST_CHANNELS; - - /* fall through */ - case PARSER_STATE_SCRAPING_DEST_CHANNELS: - if (*p != '=') - continue; - if (strncmp (mark, "RGBA", 4) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA; - else if (strncmp (mark, "RGB", 3) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - else if (strncmp (mark, "A", 1) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - else - { - error_string = "Unknown destination channel mask; " - "expected RGBA=, RGB= or A="; - goto error; - } - state = PARSER_STATE_EXPECT_FUNCTION_NAME; - continue; - - case PARSER_STATE_EXPECT_FUNCTION_NAME: - mark = p; - state = PARSER_STATE_SCRAPING_FUNCTION_NAME; - - /* fall through */ - case PARSER_STATE_SCRAPING_FUNCTION_NAME: - if (*p != '(') - { - if (!is_alphanum_char (*p)) - { - error_string = "non alpha numeric character in function" - "name"; - goto error; - } - continue; - } - statement->function = get_function_info (mark, p, context); - if (!statement->function) - { - error_string = "Unknown function name"; - goto error; - } - remaining_argc = statement->function->argc; - current_arg = 0; - state = PARSER_STATE_EXPECT_ARG_START; - - /* fall through */ - case PARSER_STATE_EXPECT_ARG_START: - if (*p != '(' && *p != ',') - continue; - if (remaining_argc) - { - p++; /* parse_argument expects to see the first char of the arg */ - if (!parse_argument (string, &p, statement, - current_arg, &statement->args[current_arg], - context, error)) - return 0; - current_arg++; - remaining_argc--; - } - if (!remaining_argc) - state = PARSER_STATE_EXPECT_STATEMENT_END; - continue; - - case PARSER_STATE_EXPECT_STATEMENT_END: - if (*p != ')') - { - error_string = "Expected end of statement"; - goto error; - } - state = PARSER_STATE_EXPECT_DEST_CHANNELS; - if (current_statement++ == 1) - goto finished; - statement = &statements[current_statement]; - } - } - while (p++); - -finished: - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - if (current_statement > 0) - print_statement (0, &statements[0]); - if (current_statement > 1) - print_statement (1, &statements[1]); - } - - if (!validate_statements_for_context (statements, - current_statement, - context, - error)) - return 0; - - return current_statement; - -error: - { - int offset = p - string; - g_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_PARSE_ERROR, - "Syntax error at offset %d: %s", - offset, - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Syntax error at offset %d: %s", - offset, error_string); - } - return 0; - } -} - -/* - * INTERNAL TESTING CODE ... - */ - -struct _TestString -{ - const char *string; - CoglBlendStringContext context; -}; - -int -_cogl_blend_string_test (void) -{ - struct _TestString strings[] = { - {" A = MODULATE ( TEXTURE[RGB], PREVIOUS[A], PREVIOUS[A] ) ", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {" RGB = MODULATE ( TEXTURE[RGB], PREVIOUS[A] ) ", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - - {"RGBA = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, DST_COLOR*(0))", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, 0)", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD()", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, 0, DST_COLOR)", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {NULL} - }; - int i; - - GError *error = NULL; - for (i = 0; strings[i].string; i++) - { - CoglBlendStringStatement statements[2]; - int count = _cogl_blend_string_compile (strings[i].string, - strings[i].context, - statements, - &error); - if (!count) - { - g_print ("Failed to parse string:\n%s\n%s\n", - strings[i].string, - error->message); - g_error_free (error); - error = NULL; - continue; - } - g_print ("Original:\n"); - g_print ("%s\n", strings[i].string); - if (count > 0) - print_statement (0, &statements[0]); - if (count > 1) - print_statement (1, &statements[1]); - } - - return 0; -} - diff --git a/clutter/cogl/cogl/cogl-blend-string.h b/clutter/cogl/cogl/cogl-blend-string.h deleted file mode 100644 index 99fe407..0000000 --- a/clutter/cogl/cogl/cogl-blend-string.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef COGL_BLEND_STRING_H -#define COGL_BLEND_STRING_H - -#include -#include - -typedef enum _CoglBlendStringContext -{ - COGL_BLEND_STRING_CONTEXT_BLENDING, - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE -} CoglBlendStringContext; - -/* NB: debug stringify code will get upset if these - * are re-ordered */ -typedef enum _CoglBlendStringChannelMask -{ - COGL_BLEND_STRING_CHANNEL_MASK_RGB, - COGL_BLEND_STRING_CHANNEL_MASK_ALPHA, - COGL_BLEND_STRING_CHANNEL_MASK_RGBA -} CoglBlendStringChannelMask; - -typedef enum _CoglBlendStringColorSourceType -{ - /* blending */ - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR, - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR, - - /* shared */ - COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT, - - /* texture combining */ - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE, - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N, - COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY, - COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS -} CoglBlendStringColorSourceType; - -typedef struct _CoglBlendStringColorSourceInfo -{ - CoglBlendStringColorSourceType type; - const char *name; - gsize name_len; -} CoglBlendStringColorSourceInfo; - -typedef struct _CoglBlendStringColorSource -{ - gboolean is_zero; - const CoglBlendStringColorSourceInfo *info; - int texture; /* for the TEXTURE_N color source */ - gboolean one_minus; - CoglBlendStringChannelMask mask; -} CoglBlendStringColorSource; - -typedef struct _CoglBlendStringFactor -{ - gboolean is_one; - gboolean is_src_alpha_saturate; - gboolean is_color; - CoglBlendStringColorSource source; -} CoglBlendStringFactor; - -typedef struct _CoglBlendStringArgument -{ - CoglBlendStringColorSource source; - CoglBlendStringFactor factor; -} CoglBlendStringArgument; - -typedef enum _CoglBlendStringFunctionType -{ - /* shared */ - COGL_BLEND_STRING_FUNCTION_ADD, - - /* texture combine only */ - COGL_BLEND_STRING_FUNCTION_REPLACE, - COGL_BLEND_STRING_FUNCTION_MODULATE, - COGL_BLEND_STRING_FUNCTION_ADD_SIGNED, - COGL_BLEND_STRING_FUNCTION_INTERPOLATE, - COGL_BLEND_STRING_FUNCTION_SUBTRACT, - COGL_BLEND_STRING_FUNCTION_DOT3_RGB, - COGL_BLEND_STRING_FUNCTION_DOT3_RGBA -} CoglBlendStringFunctionType; - -typedef struct _CoglBlendStringFunctionInfo -{ - enum _CoglBlendStringFunctionType type; - const char *name; - gsize name_len; - int argc; -} CoglBlendStringFunctionInfo; - -typedef struct _CoglBlendStringStatement -{ - CoglBlendStringChannelMask mask; - const CoglBlendStringFunctionInfo *function; - CoglBlendStringArgument args[3]; -} CoglBlendStringStatement; - - -gboolean -_cogl_blend_string_compile (const char *string, - CoglBlendStringContext context, - CoglBlendStringStatement *statements, - GError **error); - -void -_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, - CoglBlendStringStatement *rgb, - CoglBlendStringStatement *a); - -#endif /* COGL_BLEND_STRING_H */ - diff --git a/clutter/cogl/cogl/cogl-blit.c b/clutter/cogl/cogl/cogl-blit.c deleted file mode 100644 index 9442441..0000000 --- a/clutter/cogl/cogl/cogl-blit.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl.h" -#include "cogl-blit.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-texture-2d-private.h" - -static const CoglBlitMode *_cogl_blit_default_mode = NULL; - -static gboolean -_cogl_blit_texture_render_begin (CoglBlitData *data) -{ - CoglHandle fbo; - CoglPipeline *pipeline; - unsigned int dst_width, dst_height; - - _COGL_GET_CONTEXT (ctx, FALSE); - - fbo = _cogl_offscreen_new_to_texture_full - (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - if (fbo == COGL_INVALID_HANDLE) - return FALSE; - - cogl_push_framebuffer (fbo); - cogl_handle_unref (fbo); - - dst_width = cogl_texture_get_width (data->dst_tex); - dst_height = cogl_texture_get_height (data->dst_tex); - - /* Set up an orthographic projection so we can use pixel - coordinates to render to the texture */ - cogl_ortho (0, /* left */ - dst_width, /* right */ - dst_height, /* bottom */ - 0, /* top */ - -1, /* near */ - 1 /* far */); - - /* We cache a pipeline used for migrating on to the context so - that it doesn't have to continuously regenerate a shader - program */ - if (ctx->blit_texture_pipeline == NULL) - { - ctx->blit_texture_pipeline = cogl_pipeline_new (); - - cogl_pipeline_set_layer_filters (ctx->blit_texture_pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - /* Disable blending by just directly taking the contents of the - source texture */ - cogl_pipeline_set_blend (ctx->blit_texture_pipeline, - "RGBA = ADD(SRC_COLOR, 0)", - NULL); - } - - pipeline = ctx->blit_texture_pipeline; - - cogl_pipeline_set_layer_texture (pipeline, 0, data->src_tex); - - cogl_push_source (pipeline); - - return TRUE; -} - -static void -_cogl_blit_texture_render_blit (CoglBlitData *data, - unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height) -{ - cogl_rectangle_with_texture_coords (dst_x, dst_y, - dst_x + width, - dst_y + height, - src_x / (float) data->src_width, - src_y / (float) data->src_height, - (src_x + width) / - (float) data->src_width, - (src_y + height) / - (float) data->src_height); -} - -static void -_cogl_blit_texture_render_end (CoglBlitData *data) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_pop_source (); - cogl_pop_framebuffer (); - - /* Attach the target texture to the texture render pipeline so that - we don't keep a reference to the source texture forever. This is - assuming that the destination texture will live for a long time - which is currently the case when cogl_blit_* is used from the - atlas code. It may be better in future to keep around a set of - dummy 1x1 textures for each texture target that we could bind - instead. This would also be useful when using a pipeline as a - hash table key such as for the ARBfp program cache. */ - cogl_pipeline_set_layer_texture (ctx->blit_texture_pipeline, 0, - data->dst_tex); -} - -static gboolean -_cogl_blit_framebuffer_begin (CoglBlitData *data) -{ - CoglHandle dst_fbo, src_fbo; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* We can only blit between FBOs if both textures are the same - format and the blit framebuffer extension is supported */ - if ((cogl_texture_get_format (data->src_tex) & ~COGL_A_BIT) != - (cogl_texture_get_format (data->dst_tex) & ~COGL_A_BIT) || - !cogl_features_available (COGL_FEATURE_OFFSCREEN_BLIT)) - return FALSE; - - dst_fbo = _cogl_offscreen_new_to_texture_full - (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - if (dst_fbo == COGL_INVALID_HANDLE) - return FALSE; - - src_fbo = _cogl_offscreen_new_to_texture_full - (data->src_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - if (src_fbo == COGL_INVALID_HANDLE) - { - cogl_handle_unref (dst_fbo); - return FALSE; - } - - _cogl_push_framebuffers (dst_fbo, src_fbo); - cogl_handle_unref (src_fbo); - cogl_handle_unref (dst_fbo); - - return TRUE; -} - -static void -_cogl_blit_framebuffer_blit (CoglBlitData *data, - unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height) -{ - _cogl_blit_framebuffer (src_x, src_y, - dst_x, dst_y, - width, height); -} - -static void -_cogl_blit_framebuffer_end (CoglBlitData *data) -{ - cogl_pop_framebuffer (); -} - -static gboolean -_cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data) -{ - CoglHandle fbo; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* This will only work if the target texture is a CoglTexture2D */ - if (!_cogl_is_texture_2d (data->dst_tex)) - return FALSE; - - fbo = _cogl_offscreen_new_to_texture_full - (data->src_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - if (fbo == COGL_INVALID_HANDLE) - return FALSE; - - cogl_push_framebuffer (fbo); - cogl_handle_unref (fbo); - - return TRUE; -} - -static void -_cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data, - unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height) -{ - _cogl_texture_2d_copy_from_framebuffer (data->dst_tex, - dst_x, dst_y, - src_x, src_y, - width, height); -} - -static void -_cogl_blit_copy_tex_sub_image_end (CoglBlitData *data) -{ - cogl_pop_framebuffer (); -} - -static gboolean -_cogl_blit_get_tex_data_begin (CoglBlitData *data) -{ - data->format = cogl_texture_get_format (data->src_tex); - data->bpp = _cogl_get_format_bpp (data->format); - - data->image_data = g_malloc (data->bpp * data->src_width * - data->src_height); - cogl_texture_get_data (data->src_tex, data->format, - data->src_width * data->bpp, data->image_data); - - return TRUE; -} - -static void -_cogl_blit_get_tex_data_blit (CoglBlitData *data, - unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height) -{ - cogl_texture_set_region (data->dst_tex, - src_x, src_y, - dst_x, dst_y, - width, height, - data->src_width, data->src_height, - data->format, - data->src_width * data->bpp, - data->image_data); -} - -static void -_cogl_blit_get_tex_data_end (CoglBlitData *data) -{ - g_free (data->image_data); -} - -/* These should be specified in order of preference */ -static const CoglBlitMode -_cogl_blit_modes[] = - { - { - "texture-render", - _cogl_blit_texture_render_begin, - _cogl_blit_texture_render_blit, - _cogl_blit_texture_render_end - }, - { - "framebuffer", - _cogl_blit_framebuffer_begin, - _cogl_blit_framebuffer_blit, - _cogl_blit_framebuffer_end - }, - { - "copy-tex-sub-image", - _cogl_blit_copy_tex_sub_image_begin, - _cogl_blit_copy_tex_sub_image_blit, - _cogl_blit_copy_tex_sub_image_end - }, - { - "get-tex-data", - _cogl_blit_get_tex_data_begin, - _cogl_blit_get_tex_data_blit, - _cogl_blit_get_tex_data_end - } - }; - -void -_cogl_blit_begin (CoglBlitData *data, - CoglHandle dst_tex, - CoglHandle src_tex) -{ - int i; - - if (_cogl_blit_default_mode == NULL) - { - const char *default_mode_string; - - /* Allow the default to be specified with an environment - variable. For the time being these functions are only used - when blitting between atlas textures so the environment - variable is named to be specific to the atlas code. If we - want to use the code in other places we should create another - environment variable for each specific use case */ - if ((default_mode_string = g_getenv ("COGL_ATLAS_DEFAULT_BLIT_MODE"))) - { - for (i = 0; i < G_N_ELEMENTS (_cogl_blit_modes); i++) - if (!strcmp (_cogl_blit_modes[i].name, default_mode_string)) - { - _cogl_blit_default_mode = _cogl_blit_modes + i; - break; - } - - if (i >= G_N_ELEMENTS (_cogl_blit_modes)) - { - g_warning ("Unknown blit mode %s", default_mode_string); - _cogl_blit_default_mode = _cogl_blit_modes; - } - } - else - /* Default to the first blit mode */ - _cogl_blit_default_mode = _cogl_blit_modes; - } - - data->dst_tex = dst_tex; - data->src_tex = src_tex; - - data->src_width = cogl_texture_get_width (src_tex); - data->src_height = cogl_texture_get_height (src_tex); - - /* Try the default blit mode first */ - if (!_cogl_blit_default_mode->begin_func (data)) - { - COGL_NOTE (ATLAS, "Failed to set up blit mode %s", - _cogl_blit_default_mode->name); - - /* Try all of the other modes in order */ - for (i = 0; i < G_N_ELEMENTS (_cogl_blit_modes); i++) - if (_cogl_blit_modes + i != _cogl_blit_default_mode && - _cogl_blit_modes[i].begin_func (data)) - { - /* Use this mode as the default from now on */ - _cogl_blit_default_mode = _cogl_blit_modes + i; - break; - } - else - COGL_NOTE (ATLAS, - "Failed to set up blit mode %s", - _cogl_blit_modes[i].name); - - /* The last blit mode can't fail so this should never happen */ - g_return_if_fail (i < G_N_ELEMENTS (_cogl_blit_modes)); - } - - data->blit_mode = _cogl_blit_default_mode; - - COGL_NOTE (ATLAS, "Setup blit using %s", _cogl_blit_default_mode->name); -} - -void -_cogl_blit (CoglBlitData *data, - unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height) -{ - data->blit_mode->blit_func (data, src_x, src_y, dst_x, dst_y, width, height); -} - -void -_cogl_blit_end (CoglBlitData *data) -{ - data->blit_mode->end_func (data); -} diff --git a/clutter/cogl/cogl/cogl-blit.h b/clutter/cogl/cogl/cogl-blit.h deleted file mode 100644 index 95e708e..0000000 --- a/clutter/cogl/cogl/cogl-blit.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __COGL_BLIT_H -#define __COGL_BLIT_H - -#include -#include "cogl-handle.h" - -/* This structures and functions are used when a series of blits needs - to be performed between two textures. In this case there are - multiple methods we can use, most of which involve transferring - between an FBO bound to the texture. */ - -typedef struct _CoglBlitData CoglBlitData; - -typedef gboolean (* CoglBlitBeginFunc) (CoglBlitData *data); -typedef void (* CoglBlitEndFunc) (CoglBlitData *data); - -typedef void (* CoglBlitFunc) (CoglBlitData *data, - unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height); - -typedef struct -{ - const char *name; - CoglBlitBeginFunc begin_func; - CoglBlitFunc blit_func; - CoglBlitEndFunc end_func; -} CoglBlitMode; - -struct _CoglBlitData -{ - CoglHandle src_tex, dst_tex; - - unsigned int src_width; - unsigned int src_height; - - const CoglBlitMode *blit_mode; - - /* If we're not using an FBO then we g_malloc a buffer and copy the - complete texture data in */ - unsigned char *image_data; - CoglPixelFormat format; - int bpp; -}; - -void -_cogl_blit_begin (CoglBlitData *data, - CoglHandle dst_tex, - CoglHandle src_tex); - -void -_cogl_blit (CoglBlitData *data, - unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height); - -void -_cogl_blit_end (CoglBlitData *data); - -#endif /* __COGL_BLIT_H */ diff --git a/clutter/cogl/cogl/cogl-buffer-private.h b/clutter/cogl/cogl/cogl-buffer-private.h deleted file mode 100644 index fc79e7d..0000000 --- a/clutter/cogl/cogl/cogl-buffer-private.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#ifndef __COGL_BUFFER_PRIVATE_H__ -#define __COGL_BUFFER_PRIVATE_H__ - -#include - -#include "cogl.h" -#include "cogl-object-private.h" -#include "cogl-buffer.h" - -G_BEGIN_DECLS - -#define COGL_BUFFER(buffer) ((CoglBuffer *)(buffer)) - -typedef struct _CoglBufferVtable CoglBufferVtable; - -struct _CoglBufferVtable -{ - void * (* map) (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints); - - void (* unmap) (CoglBuffer *buffer); - - gboolean (* set_data) (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size); -}; - -typedef enum _CoglBufferFlags -{ - COGL_BUFFER_FLAG_NONE = 0, - COGL_BUFFER_FLAG_BUFFER_OBJECT = 1UL << 0, /* real openGL buffer object */ - COGL_BUFFER_FLAG_MAPPED = 1UL << 1, - COGL_BUFFER_FLAG_MAPPED_FALLBACK = 1UL << 2 -} CoglBufferFlags; - -typedef enum { - COGL_BUFFER_USAGE_HINT_TEXTURE, - COGL_BUFFER_USAGE_HINT_VERTEX_ARRAY, - COGL_BUFFER_USAGE_HINT_INDEX_ARRAY -} CoglBufferUsageHint; - -typedef enum { - COGL_BUFFER_BIND_TARGET_PIXEL_PACK, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - COGL_BUFFER_BIND_TARGET_VERTEX_ARRAY, - COGL_BUFFER_BIND_TARGET_INDEX_ARRAY, - - COGL_BUFFER_BIND_TARGET_COUNT -} CoglBufferBindTarget; - -struct _CoglBuffer -{ - CoglObject _parent; - CoglBufferVtable vtable; - - CoglBufferBindTarget last_target; - - CoglBufferFlags flags; - - GLuint gl_handle; /* OpenGL handle */ - unsigned int size; /* size of the buffer, in bytes */ - CoglBufferUsageHint usage_hint; - CoglBufferUpdateHint update_hint; - - guint8 *data; /* points to the mapped memory when - * the CoglBuffer is a VBO, PBO, ... or - * points to allocated memory in the - * fallback paths */ - - int immutable_ref; - - guint store_created:1; -}; - -/* This is used to register a type to the list of handle types that - will be considered a texture in cogl_is_texture() */ -void -_cogl_buffer_register_buffer_type (GQuark type); - -#define COGL_BUFFER_DEFINE(TypeName, type_name) \ - COGL_OBJECT_DEFINE_WITH_CODE \ - (TypeName, type_name, \ - _cogl_buffer_register_buffer_type (_cogl_object_ \ - ## type_name ## _get_type ())) - -void -_cogl_buffer_initialize (CoglBuffer *buffer, - unsigned int size, - gboolean use_malloc, - CoglBufferBindTarget default_target, - CoglBufferUsageHint usage_hint, - CoglBufferUpdateHint update_hint); - -void -_cogl_buffer_fini (CoglBuffer *buffer); - -void * -_cogl_buffer_bind (CoglBuffer *buffer, - CoglBufferBindTarget target); - -void -_cogl_buffer_unbind (CoglBuffer *buffer); - -CoglBufferUsageHint -_cogl_buffer_get_usage_hint (CoglBuffer *buffer); - -GLenum -_cogl_buffer_access_to_gl_enum (CoglBufferAccess access); - -GLenum -_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint, - CoglBufferUpdateHint update_hint); - -CoglBuffer * -_cogl_buffer_immutable_ref (CoglBuffer *buffer); - -void -_cogl_buffer_immutable_unref (CoglBuffer *buffer); - -/* This is a wrapper around cogl_buffer_map for internal use when we - want to map the buffer for write only to replace the entire - contents. If the map fails then it will fallback to writing to a - temporary buffer. When _cogl_buffer_unmap_for_fill_or_fallback is - called the temporary buffer will be copied into the array. Note - that these calls share a global array so they can not be nested. */ -void * -_cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer); - -void -_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer); - -G_END_DECLS - -#endif /* __COGL_BUFFER_PRIVATE_H__ */ diff --git a/clutter/cogl/cogl/cogl-buffer.c b/clutter/cogl/cogl/cogl-buffer.c deleted file mode 100644 index 3caaa94..0000000 --- a/clutter/cogl/cogl/cogl-buffer.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -/* For an overview of the functionality implemented here, please see - * cogl-buffer.h, which contains the gtk-doc section overview for the - * Pixel Buffers API. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-pixel-array-private.h" - -/* - * GL/GLES compatibility defines for the buffer API: - */ - -#if defined (HAVE_COGL_GL) - -#define glGenBuffers ctx->drv.pf_glGenBuffers -#define glBindBuffer ctx->drv.pf_glBindBuffer -#define glBufferData ctx->drv.pf_glBufferData -#define glBufferSubData ctx->drv.pf_glBufferSubData -#define glGetBufferSubData ctx->drv.pf_glGetBufferSubData -#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers - -#endif - -/* These two are always accessed through an extension, even on GLES */ -#define glMapBuffer ctx->drv.pf_glMapBuffer -#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer - -#ifndef GL_PIXEL_PACK_BUFFER -#define GL_PIXEL_PACK_BUFFER 0x88EB -#endif -#ifndef GL_PIXEL_UNPACK_BUFFER -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#endif -#ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8892 -#endif -#ifndef GL_ELEMENT_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8893 -#endif -#ifndef GL_READ_ONLY -#define GL_READ_ONLY 0x88B8 -#endif -#ifndef GL_WRITE_ONLY -#define GL_WRITE_ONLY 0x88B9 -#endif -#ifndef GL_READ_WRITE -#define GL_READ_WRITE 0x88BA -#endif - -/* XXX: - * The CoglHandle macros don't support any form of inheritance, so for - * now we implement the CoglObject support for the CoglBuffer - * abstract class manually. - */ - -void -_cogl_buffer_register_buffer_type (GQuark type) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - ctx->buffer_types = g_slist_prepend (ctx->buffer_types, - GINT_TO_POINTER (type)); -} - -gboolean -cogl_is_buffer (const void *object) -{ - const CoglHandleObject *obj = object; - GSList *l; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (object == NULL) - return FALSE; - - for (l = ctx->buffer_types; l; l = l->next) - if (GPOINTER_TO_INT (l->data) == obj->klass->type) - return TRUE; - - return FALSE; -} - -static GLenum -convert_bind_target_to_gl_target (CoglBufferBindTarget target) -{ - switch (target) - { - case COGL_BUFFER_BIND_TARGET_PIXEL_PACK: - return GL_PIXEL_PACK_BUFFER; - case COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK: - return GL_PIXEL_UNPACK_BUFFER; - case COGL_BUFFER_BIND_TARGET_VERTEX_ARRAY: - return GL_ARRAY_BUFFER; - case COGL_BUFFER_BIND_TARGET_INDEX_ARRAY: - return GL_ELEMENT_ARRAY_BUFFER; - default: - g_return_val_if_reached (COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK); - } -} - -static void * -bo_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints) -{ - guint8 *data; - CoglBufferBindTarget target; - GLenum gl_target; - - _COGL_GET_CONTEXT (ctx, NULL); - - if ((access & COGL_BUFFER_ACCESS_READ) && - !cogl_features_available (COGL_FEATURE_MAP_BUFFER_FOR_READ)) - return NULL; - if ((access & COGL_BUFFER_ACCESS_WRITE) && - !cogl_features_available (COGL_FEATURE_MAP_BUFFER_FOR_WRITE)) - return NULL; - - target = buffer->last_target; - _cogl_buffer_bind (buffer, target); - - gl_target = convert_bind_target_to_gl_target (target); - - /* create an empty store if we don't have one yet. creating the store - * lazily allows the user of the CoglBuffer to set a hint before the - * store is created. */ - if (!buffer->store_created || (hints & COGL_BUFFER_MAP_HINT_DISCARD)) - { - GE( glBufferData (gl_target, - buffer->size, - NULL, - _cogl_buffer_hints_to_gl_enum (buffer->usage_hint, - buffer->update_hint)) ); - buffer->store_created = TRUE; - } - - GE_RET( data, glMapBuffer (gl_target, - _cogl_buffer_access_to_gl_enum (access)) ); - if (data) - buffer->flags |= COGL_BUFFER_FLAG_MAPPED; - - _cogl_buffer_unbind (buffer); - - return data; -} - -static void -bo_unmap (CoglBuffer *buffer) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_buffer_bind (buffer, buffer->last_target); - - GE( glUnmapBuffer (convert_bind_target_to_gl_target (buffer->last_target)) ); - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED; - - _cogl_buffer_unbind (buffer); -} - -static gboolean -bo_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size) -{ - CoglBufferBindTarget target; - GLenum gl_target; - - _COGL_GET_CONTEXT (ctx, FALSE); - - target = buffer->last_target; - _cogl_buffer_bind (buffer, target); - - gl_target = convert_bind_target_to_gl_target (target); - - /* create an empty store if we don't have one yet. creating the store - * lazily allows the user of the CoglBuffer to set a hint before the - * store is created. */ - if (!buffer->store_created) - { - GE( glBufferData (gl_target, - buffer->size, - NULL, - _cogl_buffer_hints_to_gl_enum (buffer->usage_hint, - buffer->update_hint)) ); - buffer->store_created = TRUE; - } - - GE( glBufferSubData (gl_target, offset, size, data) ); - - _cogl_buffer_unbind (buffer); - - return TRUE; -} - -/* - * Fallback path, buffer->data points to a malloc'ed buffer. - */ - -static void * -malloc_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints) -{ - buffer->flags |= COGL_BUFFER_FLAG_MAPPED; - return buffer->data; -} - -static void -malloc_unmap (CoglBuffer *buffer) -{ - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED; -} - -static gboolean -malloc_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size) -{ - memcpy (buffer->data + offset, data, size); - return TRUE; -} - -void -_cogl_buffer_initialize (CoglBuffer *buffer, - unsigned int size, - gboolean use_malloc, - CoglBufferBindTarget default_target, - CoglBufferUsageHint usage_hint, - CoglBufferUpdateHint update_hint) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - buffer->flags = COGL_BUFFER_FLAG_NONE; - buffer->store_created = FALSE; - buffer->size = size; - buffer->last_target = default_target; - buffer->usage_hint = usage_hint; - buffer->update_hint = update_hint; - buffer->data = NULL; - buffer->immutable_ref = 0; - - if (use_malloc) - { - buffer->vtable.map = malloc_map; - buffer->vtable.unmap = malloc_unmap; - buffer->vtable.set_data = malloc_set_data; - - buffer->data = g_malloc (size); - } - else - { - buffer->vtable.map = bo_map; - buffer->vtable.unmap = bo_unmap; - buffer->vtable.set_data = bo_set_data; - - GE( glGenBuffers (1, &buffer->gl_handle) ); - buffer->flags |= COGL_BUFFER_FLAG_BUFFER_OBJECT; - } -} - -void -_cogl_buffer_fini (CoglBuffer *buffer) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)); - g_return_if_fail (buffer->immutable_ref == 0); - - if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) - GE( glDeleteBuffers (1, &buffer->gl_handle) ); - else - g_free (buffer->data); -} - -GLenum -_cogl_buffer_access_to_gl_enum (CoglBufferAccess access) -{ - if ((access & COGL_BUFFER_ACCESS_READ_WRITE) == COGL_BUFFER_ACCESS_READ_WRITE) - return GL_READ_WRITE; - else if (access & COGL_BUFFER_ACCESS_WRITE) - return GL_WRITE_ONLY; - else - return GL_READ_ONLY; -} - -/* OpenGL ES 1.1 and 2 only know about STATIC_DRAW and DYNAMIC_DRAW */ -#if defined (COGL_HAS_GLES) -GLenum -_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint, - CoglBufferUpdateHint update_hint) -{ - /* usage hint is always TEXTURE for now */ - if (update_hint == COGL_BUFFER_UPDATE_HINT_STATIC) - return GL_STATIC_DRAW; - return GL_DYNAMIC_DRAW; -} -#else -GLenum -_cogl_buffer_hints_to_gl_enum (CoglBufferUsageHint usage_hint, - CoglBufferUpdateHint update_hint) -{ - /* usage hint is always TEXTURE for now */ - if (update_hint == COGL_BUFFER_UPDATE_HINT_STATIC) - return GL_STATIC_DRAW; - if (update_hint == COGL_BUFFER_UPDATE_HINT_DYNAMIC) - return GL_DYNAMIC_DRAW; - if (update_hint == COGL_BUFFER_UPDATE_HINT_STREAM) - return GL_STREAM_DRAW; - - return GL_STATIC_DRAW; -} -#endif - -void * -_cogl_buffer_bind (CoglBuffer *buffer, CoglBufferBindTarget target) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (buffer != NULL, NULL); - - /* Don't allow binding the buffer to multiple targets at the same time */ - g_return_val_if_fail (ctx->current_buffer[buffer->last_target] != buffer, - NULL); - - /* Don't allow nesting binds to the same target */ - g_return_val_if_fail (ctx->current_buffer[target] == NULL, NULL); - - buffer->last_target = target; - ctx->current_buffer[target] = buffer; - - if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) - { - GLenum gl_target = convert_bind_target_to_gl_target (buffer->last_target); - GE( glBindBuffer (gl_target, buffer->gl_handle) ); - return NULL; - } - else - return buffer->data; -} - -void -_cogl_buffer_unbind (CoglBuffer *buffer) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (buffer != NULL); - - /* the unbind should pair up with a previous bind */ - g_return_if_fail (ctx->current_buffer[buffer->last_target] == buffer); - - if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) - { - GLenum gl_target = convert_bind_target_to_gl_target (buffer->last_target); - GE( glBindBuffer (gl_target, 0) ); - } - - ctx->current_buffer[buffer->last_target] = NULL; -} - -unsigned int -cogl_buffer_get_size (CoglBuffer *buffer) -{ - if (!cogl_is_buffer (buffer)) - return 0; - - return COGL_BUFFER (buffer)->size; -} - -void -cogl_buffer_set_update_hint (CoglBuffer *buffer, - CoglBufferUpdateHint hint) -{ - if (!cogl_is_buffer (buffer)) - return; - - if (G_UNLIKELY (hint > COGL_BUFFER_UPDATE_HINT_STREAM)) - hint = COGL_BUFFER_UPDATE_HINT_STATIC; - - buffer->update_hint = hint; -} - -CoglBufferUpdateHint -cogl_buffer_get_update_hint (CoglBuffer *buffer) -{ - if (!cogl_is_buffer (buffer)) - return FALSE; - - return buffer->update_hint; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of buffers has " - "undefined results\n"); - seen = TRUE; - } -} - -void * -cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints) -{ - g_return_val_if_fail (cogl_is_buffer (buffer), NULL); - - if (G_UNLIKELY (buffer->immutable_ref)) - warn_about_midscene_changes (); - - if (buffer->flags & COGL_BUFFER_FLAG_MAPPED) - return buffer->data; - - buffer->data = buffer->vtable.map (buffer, access, hints); - return buffer->data; -} - -void -cogl_buffer_unmap (CoglBuffer *buffer) -{ - if (!cogl_is_buffer (buffer)) - return; - - if (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)) - return; - - buffer->vtable.unmap (buffer); -} - -void * -_cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer) -{ - void *ret; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (!ctx->buffer_map_fallback_in_use, NULL); - - ctx->buffer_map_fallback_in_use = TRUE; - - ret = cogl_buffer_map (buffer, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - - if (ret) - return ret; - else - { - /* If the map fails then we'll use a temporary buffer to fill - the data and then upload it using cogl_buffer_set_data when - the buffer is unmapped. The temporary buffer is shared to - avoid reallocating it every time */ - g_byte_array_set_size (ctx->buffer_map_fallback_array, buffer->size); - - buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK; - - return ctx->buffer_map_fallback_array->data; - } -} - -void -_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (ctx->buffer_map_fallback_in_use); - - ctx->buffer_map_fallback_in_use = FALSE; - - if ((buffer->flags & COGL_BUFFER_FLAG_MAPPED_FALLBACK)) - { - cogl_buffer_set_data (buffer, 0, - ctx->buffer_map_fallback_array->data, - buffer->size); - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED_FALLBACK; - } - else - cogl_buffer_unmap (buffer); -} - -gboolean -cogl_buffer_set_data (CoglBuffer *buffer, - gsize offset, - const void *data, - gsize size) -{ - g_return_val_if_fail (cogl_is_buffer (buffer), FALSE); - g_return_val_if_fail ((offset + size) <= buffer->size, FALSE); - - if (G_UNLIKELY (buffer->immutable_ref)) - warn_about_midscene_changes (); - - return buffer->vtable.set_data (buffer, offset, data, size); -} - -CoglBuffer * -_cogl_buffer_immutable_ref (CoglBuffer *buffer) -{ - g_return_val_if_fail (cogl_is_buffer (buffer), NULL); - - buffer->immutable_ref++; - return buffer; -} - -void -_cogl_buffer_immutable_unref (CoglBuffer *buffer) -{ - g_return_if_fail (cogl_is_buffer (buffer)); - g_return_if_fail (buffer->immutable_ref > 0); - - buffer->immutable_ref--; -} - diff --git a/clutter/cogl/cogl/cogl-buffer.h b/clutter/cogl/cogl/cogl-buffer.h deleted file mode 100644 index 9d0312b..0000000 --- a/clutter/cogl/cogl/cogl-buffer.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C)2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_BUFFER_H__ -#define __COGL_BUFFER_H__ - -#include -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-buffer - * @short_description: Buffer creation and manipulation - * @stability: Unstable - * - * COGL allows the creation and the manipulation of buffers. If the underlying - * OpenGL implementation allows it, COGL will use Pixel Buffer Objects. - */ - -/* All of the cogl-buffer API is currently experimental so we suffix - * the actual symbols with _EXP so if somone is monitoring for ABI - * changes it will hopefully be clearer to them what's going on if any - * of the symbols dissapear at a later date. - */ -#define cogl_is_buffer cogl_is_buffer_EXP -#define cogl_buffer_get_size cogl_buffer_get_size_EXP -#define cogl_buffer_set_usage_hint cogl_buffer_set_usage_hint_EXP -#define cogl_buffer_get_usage_hint cogl_buffer_get_usage_hint_EXP -#define cogl_buffer_set_update_hint cogl_buffer_set_update_hint_EXP -#define cogl_buffer_get_update_hint cogl_buffer_get_update_hint_EXP -#define cogl_buffer_map cogl_buffer_map_EXP -#define cogl_buffer_unmap cogl_buffer_unmap_EXP -#define cogl_buffer_set_data cogl_buffer_set_data_EXP - -typedef struct _CoglBuffer CoglBuffer; - -/** - * cogl_is_buffer: - * @buffer: a buffer object - * - * Checks whether @buffer is a buffer object. - * - * Return value: %TRUE if the handle is a CoglBuffer, and %FALSE otherwise - * - * Since: 1.2 - * Stability: Unstable - */ -gboolean -cogl_is_buffer (const void *object); - -/** - * cogl_buffer_get_size: - * @buffer: a buffer object - * - * Retrieves the size of buffer - * - * Return value: the size of the buffer in bytes - * - * Since: 1.2 - * Stability: Unstable - */ -unsigned int -cogl_buffer_get_size (CoglBuffer *buffer); - -/** - * CoglBufferUpdateHint: - * @COGL_BUFFER_UPDATE_HINT_STATIC: the buffer will not change over time - * @COGL_BUFFER_UPDATE_HINT_DYNAMIC: the buffer will change from time to time - * @COGL_BUFFER_UPDATE_HINT_STREAM: the buffer will be used once or a couple of - * times - * - * The update hint on a buffer allows the user to give some detail on how often - * the buffer data is going to be updated. - * - * Since: 1.2 - * Stability: Unstable - */ -typedef enum { /*< prefix=COGL_BUFFER_UPDATE_HINT >*/ - COGL_BUFFER_UPDATE_HINT_STATIC, - COGL_BUFFER_UPDATE_HINT_DYNAMIC, - COGL_BUFFER_UPDATE_HINT_STREAM -} CoglBufferUpdateHint; - -/** - * cogl_buffer_set_update_hint: - * @buffer: a buffer object - * @hint: the new hint - * - * Sets the update hint on a buffer. See #CoglBufferUpdateHint for a description - * of the available hints. - * - * Since: 1.2 - * Stability: Unstable - */ -void -cogl_buffer_set_update_hint (CoglBuffer *buffer, - CoglBufferUpdateHint hint); - -/** - * cogl_buffer_get_update_hint: - * @buffer: a buffer object - * - * Retrieves the update hints set using cogl_buffer_set_update_hint() - * - * Return value: the #CoglBufferUpdateHint currently used by the buffer - * - * Since: 1.2 - * Stability: Unstable - */ -CoglBufferUpdateHint -cogl_buffer_get_update_hint (CoglBuffer *buffer); - -/** - * CoglBufferAccess: - * @COGL_BUFFER_ACCESS_READ: the buffer will be read - * @COGL_BUFFER_ACCESS_WRITE: the buffer will written to - * @COGL_BUFFER_ACCESS_READ_WRITE: the buffer will be used for both reading and - * writing - * - * The access hints for cogl_buffer_set_update_hint() - * - * Since: 1.2 - * Stability: Unstable - */ -typedef enum { /*< prefix=COGL_BUFFER_ACCESS >*/ - COGL_BUFFER_ACCESS_READ = 1 << 0, - COGL_BUFFER_ACCESS_WRITE = 1 << 1, - COGL_BUFFER_ACCESS_READ_WRITE = COGL_BUFFER_ACCESS_READ | COGL_BUFFER_ACCESS_WRITE -} CoglBufferAccess; - - -/** - * CoglBufferMapHint: - * @COGL_BUFFER_MAP_HINT_DISCARD: Tells Cogl that you plan to replace - * all the buffer's contents. - * - * Hints to Cogl about how you are planning to modify the data once it - * is mapped. - * - * Since: 1.4 - * Stability: Unstable - */ -typedef enum { /*< prefix=COGL_BUFFER_MAP_HINT >*/ - COGL_BUFFER_MAP_HINT_DISCARD = 1 << 0 -} CoglBufferMapHint; - -/** - * cogl_buffer_map: - * @buffer: a buffer object - * @access: how the mapped buffer will be used by the application - * @hints: A mask of #CoglBufferMapHints that tell Cogl how - * the data will be modified once mapped. - * - * Maps the buffer into the application address space for direct access. - * - * It is strongly recommended that you pass - * %COGL_BUFFER_MAP_HINT_DISCARD as a hint if you are going to replace - * all the buffer's data. This way if the buffer is currently being - * used by the GPU then the driver won't have to stall the CPU and - * wait for the hardware to finish because it can instead allocate a - * new buffer to map. - * - * The behaviour is undefined if you access the buffer in a way - * conflicting with the @access mask you pass. It is also an error to - * release your last reference while the buffer is mapped. - * - * Return value: A pointer to the mapped memory or %NULL is the call fails - * - * Since: 1.2 - * Stability: Unstable - */ -void * -cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints); - -/** - * cogl_buffer_unmap: - * @buffer: a buffer object - * - * Unmaps a buffer previously mapped by cogl_buffer_map(). - * - * Since: 1.2 - * Stability: Unstable - */ -void -cogl_buffer_unmap (CoglBuffer *buffer); - -/** - * cogl_buffer_set_data: - * @buffer: a buffer object - * @offset: destination offset (in bytes) in the buffer - * @data: a pointer to the data to be copied into the buffer - * @size: number of bytes to copy - * - * Updates part of the buffer with new data from @data. Where to put this new - * data is controlled by @offset and @offset + @data should be less than the - * buffer size. - * - * Return value: %TRUE is the operation succeeded, %FALSE otherwise - * - * Since: 1.2 - * Stability: Unstable - */ -gboolean -cogl_buffer_set_data (CoglBuffer *buffer, - gsize offset, - const void *data, - gsize size); - -G_END_DECLS - -#endif /* __COGL_BUFFER_H__ */ diff --git a/clutter/cogl/cogl/cogl-clip-stack.c b/clutter/cogl/cogl/cogl-clip-stack.c deleted file mode 100644 index 5f21810..0000000 --- a/clutter/cogl/cogl/cogl-clip-stack.c +++ /dev/null @@ -1,748 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include - -#include "cogl.h" -#include "cogl-clip-stack.h" -#include "cogl-primitives.h" -#include "cogl-context-private.h" -#include "cogl-internal.h" -#include "cogl-framebuffer-private.h" -#include "cogl-journal-private.h" -#include "cogl-util.h" -#include "cogl-path-private.h" -#include "cogl-matrix-private.h" -#include "cogl-primitives-private.h" - -#ifndef GL_CLIP_PLANE0 -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 -#endif - -static void -project_vertex (const CoglMatrix *modelview_projection, - float *vertex) -{ - int i; - - cogl_matrix_transform_point (modelview_projection, - &vertex[0], &vertex[1], - &vertex[2], &vertex[3]); - - /* Convert from homogenized coordinates */ - for (i = 0; i < 4; i++) - vertex[i] /= vertex[3]; -} - -static void -set_clip_plane (GLint plane_num, - const float *vertex_a, - const float *vertex_b) -{ -#if defined (HAVE_COGL_GLES2) || defined (HAVE_COGL_GLES) - GLfloat plane[4]; -#else - GLdouble plane[4]; -#endif - GLfloat angle; - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglMatrix inverse_projection; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_matrix_stack_get_inverse (projection_stack, &inverse_projection); - - /* Calculate the angle between the axes and the line crossing the - two points */ - angle = atan2f (vertex_b[1] - vertex_a[1], - vertex_b[0] - vertex_a[0]) * (180.0/G_PI); - - _cogl_matrix_stack_push (modelview_stack); - - /* Load the inverse of the projection matrix so we can specify the plane - * in screen coordinates */ - _cogl_matrix_stack_set (modelview_stack, &inverse_projection); - - /* Rotate about point a */ - _cogl_matrix_stack_translate (modelview_stack, - vertex_a[0], vertex_a[1], vertex_a[2]); - /* Rotate the plane by the calculated angle so that it will connect - the two points */ - _cogl_matrix_stack_rotate (modelview_stack, angle, 0.0f, 0.0f, 1.0f); - _cogl_matrix_stack_translate (modelview_stack, - -vertex_a[0], -vertex_a[1], -vertex_a[2]); - - _cogl_matrix_stack_flush_to_gl (modelview_stack, COGL_MATRIX_MODELVIEW); - - plane[0] = 0; - plane[1] = -1.0; - plane[2] = 0; - plane[3] = vertex_a[1]; -#if defined (HAVE_COGL_GLES2) - g_assert_not_reached (); -#elif defined (HAVE_COGL_GLES) - GE( glClipPlanef (plane_num, plane) ); -#else - GE( glClipPlane (plane_num, plane) ); -#endif - - _cogl_matrix_stack_pop (modelview_stack); -} - -static void -set_clip_planes (float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - CoglMatrix modelview_matrix; - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglMatrix projection_matrix; - CoglMatrix modelview_projection; - float signed_area; - - float vertex_tl[4] = { x_1, y_1, 0, 1.0 }; - float vertex_tr[4] = { x_2, y_1, 0, 1.0 }; - float vertex_bl[4] = { x_1, y_2, 0, 1.0 }; - float vertex_br[4] = { x_2, y_2, 0, 1.0 }; - - _cogl_matrix_stack_get (projection_stack, &projection_matrix); - _cogl_matrix_stack_get (modelview_stack, &modelview_matrix); - - cogl_matrix_multiply (&modelview_projection, - &projection_matrix, - &modelview_matrix); - - project_vertex (&modelview_projection, vertex_tl); - project_vertex (&modelview_projection, vertex_tr); - project_vertex (&modelview_projection, vertex_bl); - project_vertex (&modelview_projection, vertex_br); - - /* Calculate the signed area of the polygon formed by the four - vertices so that we can know its orientation */ - signed_area = (vertex_tl[0] * (vertex_tr[1] - vertex_bl[1]) - + vertex_tr[0] * (vertex_br[1] - vertex_tl[1]) - + vertex_br[0] * (vertex_bl[1] - vertex_tr[1]) - + vertex_bl[0] * (vertex_tl[1] - vertex_br[1])); - - /* Set the clip planes to form lines between all of the vertices - using the same orientation as we calculated */ - if (signed_area > 0.0f) - { - /* counter-clockwise */ - set_clip_plane (GL_CLIP_PLANE0, vertex_tl, vertex_bl); - set_clip_plane (GL_CLIP_PLANE1, vertex_bl, vertex_br); - set_clip_plane (GL_CLIP_PLANE2, vertex_br, vertex_tr); - set_clip_plane (GL_CLIP_PLANE3, vertex_tr, vertex_tl); - } - else - { - /* clockwise */ - set_clip_plane (GL_CLIP_PLANE0, vertex_tl, vertex_tr); - set_clip_plane (GL_CLIP_PLANE1, vertex_tr, vertex_br); - set_clip_plane (GL_CLIP_PLANE2, vertex_br, vertex_bl); - set_clip_plane (GL_CLIP_PLANE3, vertex_bl, vertex_tl); - } -} - -static void -add_stencil_clip_rectangle (float x_1, - float y_1, - float x_2, - float y_2, - gboolean first) -{ - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* temporarily swap in our special stenciling pipeline */ - cogl_push_source (ctx->stencil_pipeline); - - /* This can be called from the journal code which doesn't flush - the matrix stacks between calls so we need to ensure they're - flushed now */ - _cogl_matrix_stack_flush_to_gl (modelview_stack, - COGL_MATRIX_MODELVIEW); - _cogl_matrix_stack_flush_to_gl (projection_stack, - COGL_MATRIX_PROJECTION); - - if (first) - { - GE( glEnable (GL_STENCIL_TEST) ); - - /* Initially disallow everything */ - GE( glClearStencil (0) ); - GE( glClear (GL_STENCIL_BUFFER_BIT) ); - - /* Punch out a hole to allow the rectangle */ - GE( glStencilFunc (GL_NEVER, 0x1, 0x1) ); - GE( glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) ); - - _cogl_rectangle_immediate (x_1, y_1, x_2, y_2); - } - else - { - /* Add one to every pixel of the stencil buffer in the - rectangle */ - GE( glStencilFunc (GL_NEVER, 0x1, 0x3) ); - GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); - _cogl_rectangle_immediate (x_1, y_1, x_2, y_2); - - /* Subtract one from all pixels in the stencil buffer so that - only pixels where both the original stencil buffer and the - rectangle are set will be valid */ - GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) ); - - _cogl_matrix_stack_push (projection_stack); - _cogl_matrix_stack_load_identity (projection_stack); - - _cogl_matrix_stack_push (modelview_stack); - _cogl_matrix_stack_load_identity (modelview_stack); - - _cogl_matrix_stack_flush_to_gl (modelview_stack, - COGL_MATRIX_MODELVIEW); - _cogl_matrix_stack_flush_to_gl (projection_stack, - COGL_MATRIX_PROJECTION); - - _cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0); - - _cogl_matrix_stack_pop (modelview_stack); - _cogl_matrix_stack_pop (projection_stack); - } - - /* Restore the stencil mode */ - GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) ); - GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); - - /* restore the original source pipeline */ - cogl_pop_source (); -} - -static void -disable_stencil_buffer (void) -{ - GE( glDisable (GL_STENCIL_TEST) ); -} - -static void -enable_clip_planes (void) -{ - GE( glEnable (GL_CLIP_PLANE0) ); - GE( glEnable (GL_CLIP_PLANE1) ); - GE( glEnable (GL_CLIP_PLANE2) ); - GE( glEnable (GL_CLIP_PLANE3) ); -} - -static void -disable_clip_planes (void) -{ - GE( glDisable (GL_CLIP_PLANE3) ); - GE( glDisable (GL_CLIP_PLANE2) ); - GE( glDisable (GL_CLIP_PLANE1) ); - GE( glDisable (GL_CLIP_PLANE0) ); -} - -static gpointer -_cogl_clip_stack_push_entry (CoglClipStack *clip_stack, - size_t size, - CoglClipStackType type) -{ - CoglClipStack *entry = g_slice_alloc (size); - - /* The new entry starts with a ref count of 1 because the stack - holds a reference to it as it is the top entry */ - entry->ref_count = 1; - entry->type = type; - entry->parent = clip_stack; - - /* We don't need to take a reference to the parent from the entry - because the we are stealing the ref in the new stack top */ - - return entry; -} - -/* Sets the window-space bounds of the entry based on the projected - coordinates of the given rectangle */ -static void -_cogl_clip_stack_entry_set_bounds (CoglClipStack *entry, - float x_1, - float y_1, - float x_2, - float y_2, - const CoglMatrix *modelview) -{ - CoglMatrix projection; - float viewport[4]; - float verts[4 * 2] = { x_1, y_1, x_2, y_1, x_2, y_2, x_1, y_2 }; - float min_x = G_MAXFLOAT, min_y = G_MAXFLOAT; - float max_x = -G_MAXFLOAT, max_y = -G_MAXFLOAT; - int i; - - cogl_get_projection_matrix (&projection); - cogl_get_viewport (viewport); - - for (i = 0; i < 4; i++) - { - float *v = verts + i * 2; - - /* Project the coordinates to window space coordinates */ - _cogl_transform_point (modelview, &projection, viewport, v, v + 1); - - if (v[0] > max_x) - max_x = v[0]; - if (v[0] < min_x) - min_x = v[0]; - if (v[1] > max_y) - max_y = v[1]; - if (v[1] < min_y) - min_y = v[1]; - } - - entry->bounds_x0 = floorf (min_x); - entry->bounds_x1 = ceilf (max_x); - entry->bounds_y0 = floorf (min_y); - entry->bounds_y1 = ceilf (max_y); -} - -CoglClipStack * -_cogl_clip_stack_push_window_rectangle (CoglClipStack *stack, - int x_offset, - int y_offset, - int width, - int height) -{ - CoglClipStack *entry; - - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackWindowRect), - COGL_CLIP_STACK_WINDOW_RECT); - - entry->bounds_x0 = x_offset; - entry->bounds_x1 = x_offset + width; - entry->bounds_y0 = y_offset; - entry->bounds_y1 = y_offset + height; - - return entry; -} - -CoglClipStack * -_cogl_clip_stack_push_rectangle (CoglClipStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - const CoglMatrix *modelview_matrix) -{ - CoglClipStackRect *entry; - CoglMatrix matrix_p; - float v[4]; - - /* Make a new entry */ - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackRect), - COGL_CLIP_STACK_RECT); - - entry->x0 = x_1; - entry->y0 = y_1; - entry->x1 = x_2; - entry->y1 = y_2; - - entry->matrix = *modelview_matrix; - - /* If the modelview meets these constraints then a transformed rectangle - * should still be a rectangle when it reaches screen coordinates. - * - * FIXME: we are are making certain assumptions about the projection - * matrix a.t.m and should really be looking at the combined modelview - * and projection matrix. - * FIXME: we don't consider rotations that are a multiple of 90 degrees - * which could be quite common. - */ - if (modelview_matrix->xy != 0 || modelview_matrix->xz != 0 || - modelview_matrix->yx != 0 || modelview_matrix->yz != 0 || - modelview_matrix->zx != 0 || modelview_matrix->zy != 0) - { - entry->can_be_scissor = FALSE; - _cogl_clip_stack_entry_set_bounds ((CoglClipStack *) entry, - x_1, y_1, x_2, y_2, modelview_matrix); - } - else - { - CoglClipStack *base_entry = (CoglClipStack *) entry; - - cogl_get_projection_matrix (&matrix_p); - cogl_get_viewport (v); - - _cogl_transform_point (modelview_matrix, &matrix_p, v, &x_1, &y_1); - _cogl_transform_point (modelview_matrix, &matrix_p, v, &x_2, &y_2); - - /* Consider that the modelview matrix may flip the rectangle - * along the x or y axis... */ -#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0) - if (x_1 > x_2) - SWAP (x_1, x_2); - if (y_1 > y_2) - SWAP (y_1, y_2); -#undef SWAP - - base_entry->bounds_x0 = COGL_UTIL_NEARBYINT (x_1); - base_entry->bounds_y0 = COGL_UTIL_NEARBYINT (y_1); - base_entry->bounds_x1 = COGL_UTIL_NEARBYINT (x_2); - base_entry->bounds_y1 = COGL_UTIL_NEARBYINT (y_2); - entry->can_be_scissor = TRUE; - } - - return (CoglClipStack *) entry; -} - -CoglClipStack * -_cogl_clip_stack_push_from_path (CoglClipStack *stack, - CoglPath *path, - const CoglMatrix *modelview_matrix) -{ - float x_1, y_1, x_2, y_2; - - _cogl_path_get_bounds (path, &x_1, &y_1, &x_2, &y_2); - - /* If the path is a simple rectangle then we can divert to pushing a - rectangle clip instead which usually won't involve the stencil - buffer */ - if (_cogl_path_is_rectangle (path)) - return _cogl_clip_stack_push_rectangle (stack, - x_1, y_1, - x_2, y_2, - modelview_matrix); - else - { - CoglClipStackPath *entry; - - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackPath), - COGL_CLIP_STACK_PATH); - - entry->path = cogl_path_copy (path); - - entry->matrix = *modelview_matrix; - - _cogl_clip_stack_entry_set_bounds ((CoglClipStack *) entry, - x_1, y_1, x_2, y_2, modelview_matrix); - - return (CoglClipStack *) entry; - } -} - -CoglClipStack * -_cogl_clip_stack_ref (CoglClipStack *entry) -{ - /* A NULL pointer is considered a valid stack so we should accept - that as an argument */ - if (entry) - entry->ref_count++; - - return entry; -} - -void -_cogl_clip_stack_unref (CoglClipStack *entry) -{ - /* Unref all of the entries until we hit the root of the list or the - entry still has a remaining reference */ - while (entry && --entry->ref_count <= 0) - { - CoglClipStack *parent = entry->parent; - - switch (entry->type) - { - case COGL_CLIP_STACK_RECT: - g_slice_free1 (sizeof (CoglClipStackRect), entry); - break; - - case COGL_CLIP_STACK_WINDOW_RECT: - g_slice_free1 (sizeof (CoglClipStackWindowRect), entry); - break; - - case COGL_CLIP_STACK_PATH: - cogl_object_unref (((CoglClipStackPath *) entry)->path); - g_slice_free1 (sizeof (CoglClipStackPath), entry); - break; - - default: - g_assert_not_reached (); - } - - entry = parent; - } -} - -CoglClipStack * -_cogl_clip_stack_pop (CoglClipStack *stack) -{ - CoglClipStack *new_top; - - g_return_val_if_fail (stack != NULL, NULL); - - /* To pop we are moving the top of the stack to the old top's parent - node. The stack always needs to have a reference to the top entry - so we must take a reference to the new top. The stack would have - previously had a reference to the old top so we need to decrease - the ref count on that. We need to ref the new head first in case - this stack was the only thing referencing the old top. In that - case the call to _cogl_clip_stack_entry_unref will unref the - parent. */ - new_top = stack->parent; - - _cogl_clip_stack_ref (new_top); - - _cogl_clip_stack_unref (stack); - - return new_top; -} - -void -_cogl_clip_stack_get_bounds (CoglClipStack *stack, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1) -{ - CoglClipStack *entry; - - *scissor_x0 = 0; - *scissor_y0 = 0; - *scissor_x1 = G_MAXINT; - *scissor_y1 = G_MAXINT; - - for (entry = stack; entry; entry = entry->parent) - { - /* Get the intersection of the current scissor and the bounding - box of this clip */ - *scissor_x0 = MAX (*scissor_x0, entry->bounds_x0); - *scissor_y0 = MAX (*scissor_y0, entry->bounds_y0); - *scissor_x1 = MIN (*scissor_x1, entry->bounds_x1); - *scissor_y1 = MIN (*scissor_y1, entry->bounds_y1); - } -} - -void -_cogl_clip_stack_flush (CoglClipStack *stack) -{ - int has_clip_planes; - gboolean using_clip_planes = FALSE; - gboolean using_stencil_buffer = FALSE; - int scissor_x0; - int scissor_y0; - int scissor_x1; - int scissor_y1; - CoglMatrixStack *modelview_stack; - CoglClipStack *entry; - int scissor_y_start; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If we have already flushed this state then we don't need to do - anything */ - if (ctx->current_clip_stack_valid) - { - if (ctx->current_clip_stack == stack) - return; - - _cogl_clip_stack_unref (ctx->current_clip_stack); - } - - ctx->current_clip_stack_valid = TRUE; - ctx->current_clip_stack = _cogl_clip_stack_ref (stack); - - modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - - has_clip_planes = cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES); - - if (has_clip_planes) - disable_clip_planes (); - disable_stencil_buffer (); - - /* If the stack is empty then there's nothing else to do */ - if (stack == NULL) - { - COGL_NOTE (CLIPPING, "Flushed empty clip stack"); - - ctx->current_clip_stack_uses_stencil = FALSE; - GE (glDisable (GL_SCISSOR_TEST)); - return; - } - - /* Calculate the scissor rect first so that if we eventually have to - clear the stencil buffer then the clear will be clipped to the - intersection of all of the bounding boxes. This saves having to - clear the whole stencil buffer */ - _cogl_clip_stack_get_bounds (stack, - &scissor_x0, &scissor_y0, - &scissor_x1, &scissor_y1); - - /* Enable scissoring as soon as possible */ - if (scissor_x0 >= scissor_x1 || scissor_y0 >= scissor_y1) - scissor_x0 = scissor_y0 = scissor_x1 = scissor_y1 = scissor_y_start = 0; - else - { - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - - /* We store the entry coordinates in Cogl coordinate space - * but OpenGL requires the window origin to be the bottom - * left so we may need to convert the incoming coordinates. - * - * NB: Cogl forces all offscreen rendering to be done upside - * down so in this case no conversion is needed. - */ - - if (cogl_is_offscreen (framebuffer)) - scissor_y_start = scissor_y0; - else - { - int framebuffer_height = - cogl_framebuffer_get_height (framebuffer); - - scissor_y_start = framebuffer_height - scissor_y1; - } - } - - COGL_NOTE (CLIPPING, "Flushing scissor to (%i, %i, %i, %i)", - scissor_x0, scissor_y0, - scissor_x1, scissor_y1); - - GE (glEnable (GL_SCISSOR_TEST)); - GE (glScissor (scissor_x0, scissor_y_start, - scissor_x1 - scissor_x0, - scissor_y1 - scissor_y0)); - - /* Add all of the entries. This will end up adding them in the - reverse order that they were specified but as all of the clips - are intersecting it should work out the same regardless of the - order */ - for (entry = stack; entry; entry = entry->parent) - { - if (entry->type == COGL_CLIP_STACK_PATH) - { - CoglClipStackPath *path_entry = (CoglClipStackPath *) entry; - - COGL_NOTE (CLIPPING, "Adding stencil clip for path"); - - _cogl_matrix_stack_push (modelview_stack); - _cogl_matrix_stack_set (modelview_stack, &path_entry->matrix); - - _cogl_add_path_to_stencil_buffer (path_entry->path, - using_stencil_buffer, - TRUE); - - _cogl_matrix_stack_pop (modelview_stack); - - using_stencil_buffer = TRUE; - } - else if (entry->type == COGL_CLIP_STACK_RECT) - { - CoglClipStackRect *rect = (CoglClipStackRect *) entry; - - /* We don't need to do anything extra if the clip for this - rectangle was entirely described by its scissor bounds */ - if (!rect->can_be_scissor) - { - _cogl_matrix_stack_push (modelview_stack); - _cogl_matrix_stack_set (modelview_stack, &rect->matrix); - - /* If we support clip planes and we haven't already used - them then use that instead */ - if (has_clip_planes) - { - COGL_NOTE (CLIPPING, "Adding clip planes clip for rectangle"); - - set_clip_planes (rect->x0, - rect->y0, - rect->x1, - rect->y1); - using_clip_planes = TRUE; - /* We can't use clip planes a second time */ - has_clip_planes = FALSE; - } - else - { - COGL_NOTE (CLIPPING, "Adding stencil clip for rectangle"); - - add_stencil_clip_rectangle (rect->x0, - rect->y0, - rect->x1, - rect->y1, - !using_stencil_buffer); - using_stencil_buffer = TRUE; - } - - _cogl_matrix_stack_pop (modelview_stack); - } - } - /* We don't need to do anything for window space rectangles - because their functionality is entirely implemented by the - entry bounding box */ - } - - /* Enabling clip planes is delayed to now so that they won't affect - setting up the stencil buffer */ - if (using_clip_planes) - enable_clip_planes (); - - ctx->current_clip_stack_uses_stencil = using_stencil_buffer; -} - -void -_cogl_clip_stack_dirty (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->current_clip_stack_valid) - { - ctx->current_clip_stack_valid = FALSE; - _cogl_clip_stack_unref (ctx->current_clip_stack); - } -} diff --git a/clutter/cogl/cogl/cogl-clip-stack.h b/clutter/cogl/cogl/cogl-clip-stack.h deleted file mode 100644 index 307d7ef..0000000 --- a/clutter/cogl/cogl/cogl-clip-stack.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_CLIP_STACK_H -#define __COGL_CLIP_STACK_H - -#include "cogl2-path.h" -#include "cogl-matrix.h" - -/* The clip stack works like a GSList where only a pointer to the top - of the stack is stored. The empty clip stack is represented simply - by the NULL pointer. When an entry is added to or removed from the - stack the new top of the stack is returned. When an entry is pushed - a new clip stack entry is created which effectively takes ownership - of the reference on the old entry. Therefore unrefing the top entry - effectively loses ownership of all entries in the stack */ - -typedef struct _CoglClipStack CoglClipStack; -typedef struct _CoglClipStackRect CoglClipStackRect; -typedef struct _CoglClipStackWindowRect CoglClipStackWindowRect; -typedef struct _CoglClipStackPath CoglClipStackPath; - -typedef enum - { - COGL_CLIP_STACK_RECT, - COGL_CLIP_STACK_WINDOW_RECT, - COGL_CLIP_STACK_PATH - } CoglClipStackType; - -/* A clip stack consists a list of entries. Each entry has a reference - * count and a link to its parent node. The child takes a reference on - * the parent and the CoglClipStack holds a reference to the top of - * the stack. There are no links back from the parent to the - * children. This allows stacks that have common ancestry to share the - * entries. - * - * For example, the following sequence of operations would generate - * the tree below: - * - * CoglClipStack *stack_a = NULL; - * stack_a = _cogl_clip_stack_push_rectangle (stack_a, ...); - * stack_a = _cogl_clip_stack_push_rectangle (stack_a, ...); - * stack_a = _cogl_clip_stack_push_from_path (stack_a, ...); - * CoglClipStack *stack_b = NULL; - * stack_b = cogl_clip_stack_push_window_rectangle (stack_b, ...); - * - * stack_a - * \ holds a ref to - * +-----------+ - * | path node | - * |ref count 1| - * +-----------+ - * \ - * +-----------+ +-----------+ - * both tops hold | rect node | | rect node | - * a ref to the |ref count 2|--|ref count 1| - * same rect node +-----------+ +-----------+ - * / - * +-----------+ - * | win. rect | - * |ref count 1| - * +-----------+ - * / holds a ref to - * stack_b - * - */ - -struct _CoglClipStack -{ - CoglClipStackType type; - - /* This will be null if there is no parent. If it is not null then - this node must be holding a reference to the parent */ - CoglClipStack *parent; - - /* All clip entries have a window-space bounding box which we can - use to calculate a scissor. The scissor limits the clip so that - we don't need to do a full stencil clear if the stencil buffer is - needed. This is stored in Cogl's coordinate space (ie, 0,0 is the - top left) */ - int bounds_x0; - int bounds_y0; - int bounds_x1; - int bounds_y1; - - unsigned int ref_count; -}; - -struct _CoglClipStackRect -{ - CoglClipStack _parent_data; - - /* The rectangle for this clip */ - float x0; - float y0; - float x1; - float y1; - - /* If this is true then the clip for this rectangle is entirely - described by the scissor bounds. This implies that the rectangle - is screen aligned and we don't need to use the stencil buffer to - set the clip. We keep the entry as a rect entry rather than a - window rect entry so that it will be easier to detect if the - modelview matrix is that same as when a rectangle is added to the - journal. In that case we can use the original clip coordinates - and modify the rectangle instead. */ - gboolean can_be_scissor; - - /* The matrix that was current when the clip was set */ - CoglMatrix matrix; -}; - -struct _CoglClipStackWindowRect -{ - CoglClipStack _parent_data; - - /* The window rect clip doesn't need any specific data because it - just adds to the scissor clip */ -}; - -struct _CoglClipStackPath -{ - CoglClipStack _parent_data; - - /* The matrix that was current when the clip was set */ - CoglMatrix matrix; - - CoglPath *path; -}; - -CoglClipStack * -_cogl_clip_stack_push_window_rectangle (CoglClipStack *stack, - int x_offset, - int y_offset, - int width, - int height); - -CoglClipStack * -_cogl_clip_stack_push_rectangle (CoglClipStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - const CoglMatrix *modelview_matrix); - -CoglClipStack * -_cogl_clip_stack_push_from_path (CoglClipStack *stack, - CoglPath *path, - const CoglMatrix *modelview_matrix); -CoglClipStack * -_cogl_clip_stack_pop (CoglClipStack *stack); - -void -_cogl_clip_stack_get_bounds (CoglClipStack *stack, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1); - -void -_cogl_clip_stack_flush (CoglClipStack *stack); - -CoglClipStack * -_cogl_clip_stack_ref (CoglClipStack *stack); - -void -_cogl_clip_stack_unref (CoglClipStack *stack); - -void -_cogl_clip_stack_dirty (void); - -#endif /* __COGL_CLIP_STACK_H */ diff --git a/clutter/cogl/cogl/cogl-clip-state-private.h b/clutter/cogl/cogl/cogl-clip-state-private.h deleted file mode 100644 index f77a166..0000000 --- a/clutter/cogl/cogl/cogl-clip-state-private.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_CLIP_STATE_PRIVATE_H -#define __COGL_CLIP_STATE_PRIVATE_H - -#include "cogl-clip-stack.h" - -typedef struct _CoglClipState CoglClipState; - -struct _CoglClipState -{ - /* Stack of CoglClipStacks */ - GSList *stacks; -}; - -void -_cogl_clip_state_init (CoglClipState *state); - -void -_cogl_clip_state_destroy (CoglClipState *state); - -void -_cogl_clip_state_flush (CoglClipState *clip_state); - -CoglClipStack * -_cogl_clip_state_get_stack (CoglClipState *clip_state); - -void -_cogl_clip_state_set_stack (CoglClipState *clip_state, - CoglClipStack *clip_stack); - -#endif /* __COGL_CLIP_STATE_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-clip-state.c b/clutter/cogl/cogl/cogl-clip-state.c deleted file mode 100644 index 02b487e..0000000 --- a/clutter/cogl/cogl/cogl-clip-state.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include - -#include "cogl.h" -#include "cogl-clip-stack.h" -#include "cogl-clip-state-private.h" -#include "cogl-context-private.h" -#include "cogl-internal.h" -#include "cogl-framebuffer-private.h" -#include "cogl-journal-private.h" -#include "cogl-util.h" -#include "cogl-matrix-private.h" - -void -cogl_clip_push_window_rectangle (int x_offset, - int y_offset, - int width, - int height) -{ - CoglFramebuffer *framebuffer; - CoglClipState *clip_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - clip_state->stacks->data = - _cogl_clip_stack_push_window_rectangle (clip_state->stacks->data, - x_offset, y_offset, - width, height); -} - -/* XXX: This is deprecated API */ -void -cogl_clip_push_window_rect (float x_offset, - float y_offset, - float width, - float height) -{ - cogl_clip_push_window_rectangle (x_offset, y_offset, width, height); -} - -void -cogl_clip_push_rectangle (float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglFramebuffer *framebuffer; - CoglClipState *clip_state; - CoglMatrix modelview_matrix; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - cogl_get_modelview_matrix (&modelview_matrix); - - clip_state->stacks->data = - _cogl_clip_stack_push_rectangle (clip_state->stacks->data, - x_1, y_1, x_2, y_2, - &modelview_matrix); -} - -/* XXX: Deprecated API */ -void -cogl_clip_push (float x_offset, - float y_offset, - float width, - float height) -{ - cogl_clip_push_rectangle (x_offset, - y_offset, - x_offset + width, - y_offset + height); -} - -void -cogl_clip_push_from_path_preserve (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - cogl2_clip_push_from_path (ctx->current_path); -} - -#undef cogl_clip_push_from_path -void -cogl_clip_push_from_path (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_clip_push_from_path (ctx->current_path); - - cogl_object_unref (ctx->current_path); - ctx->current_path = cogl2_path_new (); -} - -static void -_cogl_clip_pop_real (CoglClipState *clip_state) -{ - clip_state->stacks->data = _cogl_clip_stack_pop (clip_state->stacks->data); -} - -void -cogl_clip_pop (void) -{ - CoglFramebuffer *framebuffer; - CoglClipState *clip_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - _cogl_clip_pop_real (clip_state); -} - -void -_cogl_clip_state_flush (CoglClipState *clip_state) -{ - /* Flush the topmost stack. The clip stack code will bail out early - if this is already flushed */ - _cogl_clip_stack_flush (clip_state->stacks->data); -} - -/* XXX: This should never have been made public API! */ -void -cogl_clip_ensure (void) -{ - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - CoglClipState *clip_state; - - clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - /* Flushing the clip state doesn't cause the journal to be - flushed. This function may be being called by an external - application however so it makes sense to flush the journal - here */ - _cogl_framebuffer_flush_journal (framebuffer); - _cogl_clip_state_flush (clip_state); -} - -static void -_cogl_clip_stack_save_real (CoglClipState *clip_state) -{ - clip_state->stacks = g_slist_prepend (clip_state->stacks, NULL); -} - -void -cogl_clip_stack_save (void) -{ - CoglFramebuffer *framebuffer; - CoglClipState *clip_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - _cogl_clip_stack_save_real (clip_state); -} - -static void -_cogl_clip_stack_restore_real (CoglClipState *clip_state) -{ - CoglHandle stack; - - g_return_if_fail (clip_state->stacks != NULL); - - stack = clip_state->stacks->data; - - _cogl_clip_stack_unref (stack); - - /* Revert to an old stack */ - clip_state->stacks = g_slist_delete_link (clip_state->stacks, - clip_state->stacks); -} - -void -cogl_clip_stack_restore (void) -{ - CoglFramebuffer *framebuffer; - CoglClipState *clip_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - _cogl_clip_stack_restore_real (clip_state); -} - -void -_cogl_clip_state_init (CoglClipState *clip_state) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - clip_state->stacks = NULL; - - /* Add an intial stack */ - _cogl_clip_stack_save_real (clip_state); -} - -void -_cogl_clip_state_destroy (CoglClipState *clip_state) -{ - /* Destroy all of the stacks */ - while (clip_state->stacks) - _cogl_clip_stack_restore_real (clip_state); -} - -CoglClipStack * -_cogl_clip_state_get_stack (CoglClipState *clip_state) -{ - return clip_state->stacks->data; -} - -void -_cogl_clip_state_set_stack (CoglClipState *clip_state, - CoglClipStack *stack) -{ - /* Replace the top of the stack of stacks */ - _cogl_clip_stack_ref (stack); - _cogl_clip_stack_unref (clip_state->stacks->data); - clip_state->stacks->data = stack; -} diff --git a/clutter/cogl/cogl/cogl-clip-state.h b/clutter/cogl/cogl/cogl-clip-state.h deleted file mode 100644 index b51943f..0000000 --- a/clutter/cogl/cogl/cogl-clip-state.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_CLIP_STATE_H -#define __COGL_CLIP_STATE_H - -#include - -G_BEGIN_DECLS - -/** - * cogl_clip_push_from_path: - * - * Sets a new clipping area using the current path. The current path - * is then cleared. The clipping area is intersected with the previous - * clipping area. To restore the previous clipping area, call - * cogl_clip_pop(). - * - * Since: 1.0 - */ -void -cogl_clip_push_from_path (void); - -G_END_DECLS - -#endif /* __COGL_CLIP_STATE_H */ diff --git a/clutter/cogl/cogl/cogl-clutter.c b/clutter/cogl/cogl/cogl-clutter.c deleted file mode 100644 index 49821ac..0000000 --- a/clutter/cogl/cogl/cogl-clutter.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl.h" -#include "cogl-types.h" -#include "cogl-private.h" -#include "cogl-context-private.h" -#include "cogl-winsys-private.h" -#include "cogl-framebuffer-private.h" - -gboolean -cogl_clutter_check_extension (const char *name, const char *ext) -{ - return _cogl_check_extension (name, ext); -} - -gboolean -cogl_clutter_winsys_has_feature (CoglWinsysFeature feature) -{ - return _cogl_winsys_has_feature (feature); -} - -void -cogl_onscreen_clutter_backend_set_size (int width, int height) -{ - CoglFramebuffer *framebuffer; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!ctx->stub_winsys) - return; - - framebuffer = COGL_FRAMEBUFFER (ctx->window_buffer); - - _cogl_framebuffer_winsys_update_size (framebuffer, width, height); -} - -#ifdef COGL_HAS_XLIB_SUPPORT -XVisualInfo * -cogl_clutter_winsys_xlib_get_visual_info (void) -{ - const CoglWinsysVtable *winsys; - - _COGL_GET_CONTEXT (ctx, NULL); - - winsys = _cogl_context_get_winsys (ctx); - - return winsys->xlib_get_visual_info (); -} -#endif diff --git a/clutter/cogl/cogl/cogl-clutter.h b/clutter/cogl/cogl/cogl-clutter.h deleted file mode 100644 index a121671..0000000 --- a/clutter/cogl/cogl/cogl-clutter.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_CLUTTER_H__ -#define __COGL_CLUTTER_H__ - -#ifdef COGL_HAS_XLIB -#include -#endif - -G_BEGIN_DECLS - -#define cogl_clutter_check_extension cogl_clutter_check_extension_CLUTTER -gboolean -cogl_clutter_check_extension (const char *name, const char *ext); - -#define cogl_clutter_winsys_has_feature cogl_clutter_winsys_has_feature_CLUTTER -gboolean -cogl_clutter_winsys_has_feature (CoglWinsysFeature feature); - -#define cogl_onscreen_clutter_backend_set_size cogl_onscreen_clutter_backend_set_size_CLUTTER -void -cogl_onscreen_clutter_backend_set_size (int width, int height); - -#ifdef COGL_HAS_XLIB -#define cogl_clutter_winsys_xlib_get_visual_info cogl_clutter_winsys_xlib_get_visual_info_CLUTTER -XVisualInfo * -cogl_clutter_winsys_xlib_get_visual_info (void); -#endif - -G_END_DECLS - -#endif /* __COGL_CLUTTER_H__ */ diff --git a/clutter/cogl/cogl/cogl-color-private.h b/clutter/cogl/cogl/cogl-color-private.h deleted file mode 100644 index 78bfcf9..0000000 --- a/clutter/cogl/cogl/cogl-color-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_COLOR_PRIVATE_PRIVATE_H -#define __COGL_COLOR_PRIVATE_PRIVATE_H - -#include "cogl-color.h" - -#include - -/* cogl-pipeline.c wants to be able to hash CoglColor data so it needs - * the exact data size to be able to avoid reading the padding bytes. - */ -#define _COGL_COLOR_DATA_SIZE 4 - -void -_cogl_color_get_rgba_4ubv (const CoglColor *color, - guint8 *dest); - -#endif /* __COGL_COLOR_PRIVATE_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-color.c b/clutter/cogl/cogl/cogl-color.c deleted file mode 100644 index b9556b0..0000000 --- a/clutter/cogl/cogl/cogl-color.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl.h" -#include "cogl-color.h" -#include "cogl-fixed.h" - -CoglColor * -cogl_color_new (void) -{ - return g_slice_new (CoglColor); -} - -CoglColor * -cogl_color_copy (const CoglColor *color) -{ - if (G_LIKELY (color)) - return g_slice_dup (CoglColor, color); - - return NULL; -} - -void -cogl_color_free (CoglColor *color) -{ - if (G_LIKELY (color)) - g_slice_free (CoglColor, color); -} - -void -cogl_color_init_from_4ub (CoglColor *color, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha) -{ - g_return_if_fail (color != NULL); - - color->red = red; - color->green = green; - color->blue = blue; - color->alpha = alpha; -} - -/* XXX: deprecated, use cogl_color_init_from_4ub */ -void -cogl_color_set_from_4ub (CoglColor *dest, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha) -{ - cogl_color_init_from_4ub (dest, red, green, blue, alpha); -} - -void -cogl_color_init_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha) -{ - g_return_if_fail (color != NULL); - - color->red = (red * 255); - color->green = (green * 255); - color->blue = (blue * 255); - color->alpha = (alpha * 255); -} - -/* XXX: deprecated, use cogl_color_init_from_4f */ -void -cogl_color_set_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha) -{ - cogl_color_init_from_4f (color, red, green, blue, alpha); -} - -void -cogl_color_init_from_4fv (CoglColor *color, - float *color_array) -{ - g_return_if_fail (color != NULL); - - color->red = (color_array[0] * 255); - color->green = (color_array[1] * 255); - color->blue = (color_array[2] * 255); - color->alpha = (color_array[3] * 255); -} - -unsigned char -cogl_color_get_red_byte (const CoglColor *color) -{ - return color->red; -} - -float -cogl_color_get_red_float (const CoglColor *color) -{ - return (float) color->red / 255.0; -} - -float -cogl_color_get_red (const CoglColor *color) -{ - return ((float) color->red / 255.0); -} - -unsigned char -cogl_color_get_green_byte (const CoglColor *color) -{ - return color->green; -} - -float -cogl_color_get_green_float (const CoglColor *color) -{ - return (float) color->green / 255.0; -} - -float -cogl_color_get_green (const CoglColor *color) -{ - return ((float) color->green / 255.0); -} - -unsigned char -cogl_color_get_blue_byte (const CoglColor *color) -{ - return color->blue; -} - -float -cogl_color_get_blue_float (const CoglColor *color) -{ - return (float) color->blue / 255.0; -} - -float -cogl_color_get_blue (const CoglColor *color) -{ - return ((float) color->blue / 255.0); -} - -unsigned char -cogl_color_get_alpha_byte (const CoglColor *color) -{ - return color->alpha; -} - -float -cogl_color_get_alpha_float (const CoglColor *color) -{ - return (float) color->alpha / 255.0; -} - -float -cogl_color_get_alpha (const CoglColor *color) -{ - return ((float) color->alpha / 255.0); -} - -void -cogl_color_set_red_byte (CoglColor *color, - unsigned char red) -{ - color->red = red; -} - -void -cogl_color_set_red_float (CoglColor *color, - float red) -{ - color->red = red * 255.0; -} - -void -cogl_color_set_red (CoglColor *color, - float red) -{ - color->red = red * 255.0; -} - -void -cogl_color_set_green_byte (CoglColor *color, - unsigned char green) -{ - color->green = green; -} - -void -cogl_color_set_green_float (CoglColor *color, - float green) -{ - color->green = green * 255.0; -} - -void -cogl_color_set_green (CoglColor *color, - float green) -{ - color->green = green * 255.0; -} - -void -cogl_color_set_blue_byte (CoglColor *color, - unsigned char blue) -{ - color->blue = blue; -} - -void -cogl_color_set_blue_float (CoglColor *color, - float blue) -{ - color->blue = blue * 255.0; -} - -void -cogl_color_set_blue (CoglColor *color, - float blue) -{ - color->blue = blue * 255.0; -} - -void -cogl_color_set_alpha_byte (CoglColor *color, - unsigned char alpha) -{ - color->alpha = alpha; -} - -void -cogl_color_set_alpha_float (CoglColor *color, - float alpha) -{ - color->alpha = alpha * 255.0; -} - -void -cogl_color_set_alpha (CoglColor *color, - float alpha) -{ - color->alpha = alpha * 255.0; -} - -void -cogl_color_premultiply (CoglColor *color) -{ - color->red = (color->red * color->alpha + 128) / 255; - color->green = (color->green * color->alpha + 128) / 255; - color->blue = (color->blue * color->alpha + 128) / 255; -} - -void -cogl_color_unpremultiply (CoglColor *color) -{ - if (color->alpha != 0) - { - color->red = (color->red * 255) / color->alpha; - color->green = (color->green * 255) / color->alpha; - color->blue = (color->blue * 255) / color->alpha; - } -} - -gboolean -cogl_color_equal (gconstpointer v1, gconstpointer v2) -{ - const guint32 *c1 = v1, *c2 = v2; - - g_return_val_if_fail (v1 != NULL, FALSE); - g_return_val_if_fail (v2 != NULL, FALSE); - - /* XXX: We don't compare the padding */ - return *c1 == *c2 ? TRUE : FALSE; -} - -void -_cogl_color_get_rgba_4ubv (const CoglColor *color, - guint8 *dest) -{ - memcpy (dest, color, 4); -} - diff --git a/clutter/cogl/cogl/cogl-color.h b/clutter/cogl/cogl/cogl-color.h deleted file mode 100644 index 7ca7cb6..0000000 --- a/clutter/cogl/cogl/cogl-color.h +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/** - * SECTION:cogl-color - * @short_description: A generic color definition - * - * #CoglColor is a simple structure holding the definition of a color such - * that it can be efficiently used by GL - * - * Since: 1.0 - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_COLOR_H__ -#define __COGL_COLOR_H__ - -#include - -G_BEGIN_DECLS - -/** - * cogl_color_new: - * - * Creates a new (empty) color - * - * Return value: a newly-allocated #CoglColor. Use cogl_color_free() - * to free the allocated resources - * - * Since: 1.0 - */ -CoglColor * -cogl_color_new (void); - -/** - * cogl_color_copy: - * @color: the color to copy - * - * Creates a copy of @color - * - * Return value: a newly-allocated #CoglColor. Use cogl_color_free() - * to free the allocate resources - * - * Since: 1.0 - */ -CoglColor * -cogl_color_copy (const CoglColor *color); - -/** - * cogl_color_free: - * @color: the color to free - * - * Frees the resources allocated by cogl_color_new() and cogl_color_copy() - * - * Since: 1.0 - */ -void -cogl_color_free (CoglColor *color); - -/** - * cogl_color_init_from_4ub: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and 255 - * @green: value of the green channel, between 0 and 255 - * @blue: value of the blue channel, between 0 and 255 - * @alpha: value of the alpha channel, between 0 and 255 - * - * Sets the values of the passed channels into a #CoglColor. - * - * Since: 1.4 - */ -void -cogl_color_init_from_4ub (CoglColor *color, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha); - -/** - * cogl_color_set_from_4ub: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and 255 - * @green: value of the green channel, between 0 and 255 - * @blue: value of the blue channel, between 0 and 255 - * @alpha: value of the alpha channel, between 0 and 255 - * - * Sets the values of the passed channels into a #CoglColor. - * - * Since: 1.0 - * Deprecated: 1.4: Use cogl_color_init_from_4ub instead. - */ -void -cogl_color_set_from_4ub (CoglColor *color, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha); - -/** - * cogl_color_init_from_4f: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and %1.0 - * @green: value of the green channel, between 0 and %1.0 - * @blue: value of the blue channel, between 0 and %1.0 - * @alpha: value of the alpha channel, between 0 and %1.0 - * - * Sets the values of the passed channels into a #CoglColor - * - * Since: 1.4 - */ -void -cogl_color_init_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_color_set_from_4f: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and %1.0 - * @green: value of the green channel, between 0 and %1.0 - * @blue: value of the blue channel, between 0 and %1.0 - * @alpha: value of the alpha channel, between 0 and %1.0 - * - * Sets the values of the passed channels into a #CoglColor - * - * Since: 1.0 - * Deprecated: 1.4: Use cogl_color_init_from_4f instead. - */ -void -cogl_color_set_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_color_init_from_4fv: - * @color: A pointer to a #CoglColor to initialize - * @color_array: a pointer to an array of 4 float color components - * - * Sets the values of the passed channels into a #CoglColor - * - * Since: 1.4 - */ -void -cogl_color_init_from_4fv (CoglColor *color, - float *color_array); - -/** - * cogl_color_get_red_byte: - * @color: a #CoglColor - * - * Retrieves the red channel of @color as a byte value - * between 0 and 255 - * - * Return value: the red channel of the passed color - * - * Since: 1.0 - */ -unsigned char -cogl_color_get_red_byte (const CoglColor *color); - -/** - * cogl_color_get_green_byte: - * @color: a #CoglColor - * - * Retrieves the green channel of @color as a byte value - * between 0 and 255 - * - * Return value: the green channel of the passed color - * - * Since: 1.0 - */ -unsigned char -cogl_color_get_green_byte (const CoglColor *color); - -/** - * cogl_color_get_blue_byte: - * @color: a #CoglColor - * - * Retrieves the blue channel of @color as a byte value - * between 0 and 255 - * - * Return value: the blue channel of the passed color - * - * Since: 1.0 - */ -unsigned char -cogl_color_get_blue_byte (const CoglColor *color); - -/** - * cogl_color_get_alpha_byte: - * @color: a #CoglColor - * - * Retrieves the alpha channel of @color as a byte value - * between 0 and 255 - * - * Return value: the alpha channel of the passed color - * - * Since: 1.0 - */ -unsigned char -cogl_color_get_alpha_byte (const CoglColor *color); - -/** - * cogl_color_get_red_float: - * @color: a #CoglColor - * - * Retrieves the red channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the red channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_red_float (const CoglColor *color); - -/** - * cogl_color_get_green_float: - * @color: a #CoglColor - * - * Retrieves the green channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the green channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_green_float (const CoglColor *color); - -/** - * cogl_color_get_blue_float: - * @color: a #CoglColor - * - * Retrieves the blue channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the blue channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_blue_float (const CoglColor *color); - -/** - * cogl_color_get_alpha_float: - * @color: a #CoglColor - * - * Retrieves the alpha channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the alpha channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_alpha_float (const CoglColor *color); - -/** - * cogl_color_get_red: - * @color: a #CoglColor - * - * Retrieves the red channel of @color as a fixed point - * value between 0 and %1.0. - * - * Return value: the red channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_red (const CoglColor *color); - -/** - * cogl_color_get_green: - * @color: a #CoglColor - * - * Retrieves the green channel of @color as a fixed point - * value between 0 and %1.0. - * - * Return value: the green channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_green (const CoglColor *color); - -/** - * cogl_color_get_blue: - * @color: a #CoglColor - * - * Retrieves the blue channel of @color as a fixed point - * value between 0 and %1.0. - * - * Return value: the blue channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_blue (const CoglColor *color); - -/** - * cogl_color_get_alpha: - * @color: a #CoglColor - * - * Retrieves the alpha channel of @color as a fixed point - * value between 0 and %1.0. - * - * Return value: the alpha channel of the passed color - * - * Since: 1.0 - */ -float -cogl_color_get_alpha (const CoglColor *color); - -/** - * cogl_color_set_red_byte: - * @color: a #CoglColor - * @red: a byte value between 0 and 255 - * - * Sets the red channel of @color to @red. - * - * Since: 1.4 - */ -void -cogl_color_set_red_byte (CoglColor *color, - unsigned char red); - -/** - * cogl_color_set_green_byte: - * @color: a #CoglColor - * @green: a byte value between 0 and 255 - * - * Sets the green channel of @color to @green. - * - * Since: 1.4 - */ -void -cogl_color_set_green_byte (CoglColor *color, - unsigned char green); - -/** - * cogl_color_set_blue_byte: - * @color: a #CoglColor - * @blue: a byte value between 0 and 255 - * - * Sets the blue channel of @color to @blue. - * - * Since: 1.4 - */ -void -cogl_color_set_blue_byte (CoglColor *color, - unsigned char blue); - -/** - * cogl_color_set_alpha_byte: - * @color: a #CoglColor - * @alpha: a byte value between 0 and 255 - * - * Sets the alpha channel of @color to @alpha. - * - * Since: 1.4 - */ -void -cogl_color_set_alpha_byte (CoglColor *color, - unsigned char alpha); - -/** - * cogl_color_set_red_float: - * @color: a #CoglColor - * @red: a float value between 0.0f and 1.0f - * - * Sets the red channel of @color to @red. - * - * since: 1.4 - */ -void -cogl_color_set_red_float (CoglColor *color, - float red); - -/** - * cogl_color_set_green_float: - * @color: a #CoglColor - * @green: a float value between 0.0f and 1.0f - * - * Sets the green channel of @color to @green. - * - * since: 1.4 - */ -void -cogl_color_set_green_float (CoglColor *color, - float green); - -/** - * cogl_color_set_blue_float: - * @color: a #CoglColor - * @blue: a float value between 0.0f and 1.0f - * - * Sets the blue channel of @color to @blue. - * - * since: 1.4 - */ -void -cogl_color_set_blue_float (CoglColor *color, - float blue); - -/** - * cogl_color_set_alpha_float: - * @color: a #CoglColor - * @alpha: a float value between 0.0f and 1.0f - * - * Sets the alpha channel of @color to @alpha. - * - * since: 1.4 - */ -void -cogl_color_set_alpha_float (CoglColor *color, - float alpha); - -/** - * cogl_color_set_red: - * @color: a #CoglColor - * @red: a float value between 0.0f and 1.0f - * - * Sets the red channel of @color to @red. - * - * Since: 1.4 - */ -void -cogl_color_set_red (CoglColor *color, - float red); - -/** - * cogl_color_set_green: - * @color: a #CoglColor - * @green: a float value between 0.0f and 1.0f - * - * Sets the green channel of @color to @green. - * - * Since: 1.4 - */ -void -cogl_color_set_green (CoglColor *color, - float green); - -/** - * cogl_color_set_blue: - * @color: a #CoglColor - * @blue: a float value between 0.0f and 1.0f - * - * Sets the blue channel of @color to @blue. - * - * Since: 1.4 - */ -void -cogl_color_set_blue (CoglColor *color, - float blue); - -/** - * cogl_color_set_alpha: - * @color: a #CoglColor - * @alpha: a float value between 0.0f and 1.0f - * - * Sets the alpha channel of @color to @alpha. - * - * Since: 1.4 - */ -void -cogl_color_set_alpha (CoglColor *color, - float alpha); - -/** - * cogl_color_premultiply: - * @color: the color to premultiply - * - * Converts a non-premultiplied color to a pre-multiplied color. For - * example, semi-transparent red is (1.0, 0, 0, 0.5) when non-premultiplied - * and (0.5, 0, 0, 0.5) when premultiplied. - * - * Since: 1.0 - */ -void -cogl_color_premultiply (CoglColor *color); - -/** - * cogl_color_unpremultiply: - * @color: the color to unpremultiply - * - * Converts a pre-multiplied color to a non-premultiplied color. For - * example, semi-transparent red is (0.5, 0, 0, 0.5) when premultiplied - * and (1.0, 0, 0, 0.5) when non-premultiplied. - * - * Since: 1.4 - */ -void -cogl_color_unpremultiply (CoglColor *color); - -/** - * cogl_color_equal: - * @v1: a #CoglColor - * @v2: a #CoglColor - * - * Compares two #CoglColors and checks if they are the same. - * - * This function can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using #CoglColors as keys in a #GHashTable. - * - * Return value: %TRUE if the two colors are the same. - * - * Since: 1.0 - */ -gboolean -cogl_color_equal (gconstpointer v1, - gconstpointer v2); - -G_END_DECLS - -#endif /* __COGL_COLOR_H__ */ diff --git a/clutter/cogl/cogl/cogl-context-private.h b/clutter/cogl/cogl/cogl-context-private.h deleted file mode 100644 index c9b7c64..0000000 --- a/clutter/cogl/cogl/cogl-context-private.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_CONTEXT_PRIVATE_H -#define __COGL_CONTEXT_PRIVATE_H - -#include "cogl-internal.h" -#include "cogl-context.h" -#include "cogl-winsys-private.h" -#include "cogl-flags.h" - -#ifdef COGL_HAS_XLIB_SUPPORT -#include "cogl-xlib-private.h" -#endif - -#if HAVE_COGL_GL -#include "cogl-context-driver-gl.h" -#endif - -#if HAVE_COGL_GLES || HAVE_COGL_GLES2 -#include "cogl-context-driver-gles.h" -#endif - -#include "cogl-display-private.h" -#include "cogl-primitives.h" -#include "cogl-clip-stack.h" -#include "cogl-matrix-stack.h" -#include "cogl-pipeline-private.h" -#include "cogl-buffer-private.h" -#include "cogl-bitmask.h" -#include "cogl-atlas.h" - -typedef struct -{ - GLfloat v[3]; - GLfloat t[2]; - GLubyte c[4]; -} CoglTextureGLVertex; - -struct _CoglContext -{ - CoglObject _parent; - - CoglDisplay *display; - - /* Features cache */ - CoglFeatureFlags feature_flags; - - CoglHandle default_pipeline; - CoglHandle default_layer_0; - CoglHandle default_layer_n; - CoglHandle dummy_layer_dependant; - - /* Enable cache */ - unsigned long enable_flags; - - gboolean enable_backface_culling; - CoglFrontWinding flushed_front_winding; - - /* A few handy matrix constants */ - CoglMatrix identity_matrix; - CoglMatrix y_flip_matrix; - - /* Client-side matrix stack or NULL if none */ - CoglMatrixMode flushed_matrix_mode; - - /* On GLES2 we need to track the matrices separately because the are - stored in GLSL uniforms rather than using the fixed function - API. We keep track of the matrix stack that Cogl is trying to - flush so we can flush it later after the program is generated. A - reference is taken on the stacks. */ -#ifdef HAVE_COGL_GLES2 - CoglMatrixStack *flushed_modelview_stack; - CoglMatrixStack *flushed_projection_stack; -#endif /* HAVE_COGL_GLES2 */ - - GArray *texture_units; - int active_texture_unit; - - CoglPipelineFogState legacy_fog_state; - - /* Pipelines */ - CoglPipeline *opaque_color_pipeline; /* used for set_source_color */ - CoglPipeline *blended_color_pipeline; /* used for set_source_color */ - CoglPipeline *texture_pipeline; /* used for set_source_texture */ - GString *codegen_header_buffer; - GString *codegen_source_buffer; - GList *source_stack; - - int legacy_state_set; - -#ifdef HAVE_COGL_GL - GHashTable *arbfp_cache; -#endif - - /* Textures */ - CoglHandle default_gl_texture_2d_tex; - CoglHandle default_gl_texture_rect_tex; - - /* Central list of all framebuffers so all journals can be flushed - * at any time. */ - GList *framebuffers; - - /* Global journal buffers */ - GArray *journal_flush_attributes_array; - GArray *journal_clip_bounds; - - GArray *polygon_vertices; - - /* Some simple caching, to minimize state changes... */ - CoglPipeline *current_pipeline; - unsigned long current_pipeline_changes_since_flush; - gboolean current_pipeline_skip_gl_color; - unsigned long current_pipeline_age; - - GArray *pipeline0_nodes; - GArray *pipeline1_nodes; - - /* Bitmask of attributes enabled. On GLES2 these are the vertex - attribute numbers and on regular GL these are only used for the - texture coordinate arrays */ - CoglBitmask arrays_enabled; - /* These are temporary bitmasks that are used when disabling - texcoord arrays. They are here just to avoid allocating new ones - each time */ - CoglBitmask arrays_to_change; - CoglBitmask temp_bitmask; - - gboolean gl_blend_enable_cache; - - gboolean depth_test_enabled_cache; - CoglDepthTestFunction depth_test_function_cache; - gboolean depth_writing_enabled_cache; - float depth_range_near_cache; - float depth_range_far_cache; - - gboolean legacy_depth_test_enabled; - - float point_size_cache; - - CoglBuffer *current_buffer[COGL_BUFFER_BIND_TARGET_COUNT]; - - /* Framebuffers */ - GSList *framebuffer_stack; - CoglHandle window_buffer; - gboolean dirty_bound_framebuffer; - gboolean dirty_gl_viewport; - - /* Primitives */ - CoglPath *current_path; - CoglPipeline *stencil_pipeline; - - /* Pre-generated VBOs containing indices to generate GL_TRIANGLES - out of a vertex array of quads */ - CoglHandle quad_buffer_indices_byte; - unsigned int quad_buffer_indices_len; - CoglHandle quad_buffer_indices; - - CoglIndices *rectangle_byte_indices; - CoglIndices *rectangle_short_indices; - int rectangle_short_indices_len; - - gboolean in_begin_gl_block; - - CoglPipeline *texture_download_pipeline; - CoglPipeline *blit_texture_pipeline; - - GSList *atlases; - GHookList atlas_reorganize_callbacks; - - /* This debugging variable is used to pick a colour for visually - displaying the quad batches. It needs to be global so that it can - be reset by cogl_clear. It needs to be reset to increase the - chances of getting the same colour during an animation */ - guint8 journal_rectangles_color; - - /* Cached values for GL_MAX_TEXTURE_[IMAGE_]UNITS to avoid calling - glGetInteger too often */ - GLint max_texture_units; - GLint max_texture_image_units; - GLint max_activateable_texture_units; - - /* Fragment processing programs */ - CoglHandle current_program; - - CoglPipelineProgramType current_fragment_program_type; - CoglPipelineProgramType current_vertex_program_type; - GLuint current_gl_program; - - /* List of types that will be considered a subclass of CoglTexture in - cogl_is_texture */ - GSList *texture_types; - - /* List of types that will be considered a subclass of CoglBuffer in - cogl_is_buffer */ - GSList *buffer_types; - - /* Clipping */ - /* TRUE if we have a valid clipping stack flushed. In that case - current_clip_stack will describe what the current state is. If - this is FALSE then the current clip stack is completely unknown - so it will need to be reflushed. In that case current_clip_stack - doesn't need to be a valid pointer. We can't just use NULL in - current_clip_stack to mark a dirty state because NULL is a valid - stack (meaning no clipping) */ - gboolean current_clip_stack_valid; - /* The clip state that was flushed. This isn't intended to be used - as a stack to push and pop new entries. Instead the current stack - that the user wants is part of the framebuffer state. This is - just used to record the flush state so we can avoid flushing the - same state multiple times. When the clip state is flushed this - will hold a reference */ - CoglClipStack *current_clip_stack; - /* Whether the stencil buffer was used as part of the current clip - state. If TRUE then any further use of the stencil buffer (such - as for drawing paths) would need to be merged with the existing - stencil buffer */ - gboolean current_clip_stack_uses_stencil; - - /* This is used as a temporary buffer to fill a CoglBuffer when - cogl_buffer_map fails and we only want to map to fill it with new - data */ - GByteArray *buffer_map_fallback_array; - gboolean buffer_map_fallback_in_use; - - CoglWinsysRectangleState rectangle_state; - - /* FIXME: remove these when we remove the last xlib based clutter - * backend. they should be tracked as part of the renderer but e.g. - * the eglx backend doesn't yet have a corresponding Cogl winsys - * and so we wont have a renderer in that case. */ -#ifdef COGL_HAS_XLIB_SUPPORT - int damage_base; - /* List of callback functions that will be given every Xlib event */ - GSList *event_filters; - /* Current top of the XError trap state stack. The actual memory for - these is expected to be allocated on the stack by the caller */ - CoglXlibTrapState *trap_state; -#endif - - CoglContextDriver drv; - - unsigned int winsys_features - [COGL_FLAGS_N_INTS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; - void *winsys; - gboolean stub_winsys; -}; - -CoglContext * -_cogl_context_get_default (); - -const CoglWinsysVtable * -_cogl_context_get_winsys (CoglContext *context); - -/* Obtains the context and returns retval if NULL */ -#define _COGL_GET_CONTEXT(ctxvar, retval) \ -CoglContext *ctxvar = _cogl_context_get_default (); \ -if (ctxvar == NULL) return retval; - -#define NO_RETVAL - -#endif /* __COGL_CONTEXT_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-context.c b/clutter/cogl/cogl/cogl-context.c deleted file mode 100644 index 53a09d6..0000000 --- a/clutter/cogl/cogl/cogl-context.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-object.h" -#include "cogl-internal.h" -#include "cogl-private.h" -#include "cogl-winsys-private.h" -#include "cogl-profile.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-journal-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl2-path.h" - -#include - -#ifdef HAVE_COGL_GL -#include "cogl-pipeline-fragend-arbfp-private.h" -#define glActiveTexture _context->drv.pf_glActiveTexture -#endif - -/* This isn't defined in the GLES headers */ -#ifndef GL_POINT_SPRITE -#define GL_POINT_SPRITE 0x8861 -#endif - -static void _cogl_context_free (CoglContext *context); - -COGL_OBJECT_DEFINE (Context, context); - -extern void -_cogl_create_context_driver (CoglContext *context); - -static CoglContext *_context = NULL; - -static void -_cogl_init_feature_overrides (CoglContext *ctx) -{ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_VBOS))) - ctx->feature_flags &= ~COGL_FEATURE_VBOS; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS))) - ctx->feature_flags &= ~COGL_FEATURE_PBOS; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ARBFP))) - ctx->feature_flags &= ~COGL_FEATURE_SHADERS_ARBFP; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_GLSL))) - ctx->feature_flags &= ~COGL_FEATURE_SHADERS_GLSL; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_NPOT_TEXTURES))) - ctx->feature_flags &= ~(COGL_FEATURE_TEXTURE_NPOT | - COGL_FEATURE_TEXTURE_NPOT_BASIC | - COGL_FEATURE_TEXTURE_NPOT_MIPMAP | - COGL_FEATURE_TEXTURE_NPOT_REPEAT); -} - -const CoglWinsysVtable * -_cogl_context_get_winsys (CoglContext *context) -{ - return context->display->renderer->winsys_vtable; -} - -/* For reference: There was some deliberation over whether to have a - * constructor that could throw an exception but looking at standard - * practices with several high level OO languages including python, C++, - * C# Java and Ruby they all support exceptions in constructors and the - * general consensus appears to be that throwing an exception is neater - * than successfully constructing with an internal error status that - * would then have to be explicitly checked via some form of ::is_ok() - * method. - */ -CoglContext * -cogl_context_new (CoglDisplay *display, - GError **error) -{ - CoglContext *context; - GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 }; - unsigned long enable_flags = 0; - const CoglWinsysVtable *winsys; - int i; - -#ifdef CLUTTER_ENABLE_PROFILE - /* We need to be absolutely sure that uprof has been initialized - * before calling _cogl_uprof_init. uprof_init (NULL, NULL) - * will be a NOP if it has been initialized but it will also - * mean subsequent parsing of the UProf GOptionGroup will have no - * affect. - * - * Sadly GOptionGroup based library initialization is extremely - * fragile by design because GOptionGroups have no notion of - * dependencies and so the order things are initialized isn't - * currently under tight control. - */ - uprof_init (NULL, NULL); - _cogl_uprof_init (); -#endif - - /* Allocate context memory */ - context = g_malloc (sizeof (CoglContext)); - - /* XXX: Gross hack! - * Currently everything in Cogl just assumes there is a default - * context which it can access via _COGL_GET_CONTEXT() including - * code used to construct a CoglContext. Until all of that code - * has been updated to take an explicit context argument we have - * to immediately make our pointer the default context. - */ - _context = context; - - /* Init default values */ - context->feature_flags = 0; - - context->texture_types = NULL; - context->buffer_types = NULL; - - context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN; - - memset (context->winsys_features, 0, sizeof (context->winsys_features)); - - if (!display) - display = cogl_display_new (NULL, NULL); - else - cogl_object_ref (display); - - if (!cogl_display_setup (display, error)) - { - cogl_object_unref (display); - g_free (context); - return NULL; - } - - context->display = display; - -#ifdef COGL_HAS_FULL_WINSYS - context->stub_winsys = FALSE; - winsys = _cogl_context_get_winsys (context); - if (!winsys->context_init (context, error)) - { - cogl_object_unref (display); - g_free (context); - return NULL; - } -#else - /* In this case Clutter is still responsible for creating a GL - * context. */ - context->stub_winsys = TRUE; - if (!_cogl_gl_check_version (error)) - { - g_free (context); - return NULL; - } - _cogl_gl_update_features (context); -#ifdef COGL_HAS_XLIB_SUPPORT - _cogl_xlib_query_damage_extension (); -#endif -#endif - - /* Initialise the driver specific state */ - _cogl_init_feature_overrides (context); - - _cogl_pipeline_init_default_pipeline (); - _cogl_pipeline_init_default_layers (); - _cogl_pipeline_init_state_hash_functions (); - _cogl_pipeline_init_layer_state_hash_functions (); - - context->enable_flags = 0; - - context->enable_backface_culling = FALSE; - context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE; - - cogl_matrix_init_identity (&context->identity_matrix); - cogl_matrix_init_identity (&context->y_flip_matrix); - cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1); - - context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW; - - context->texture_units = - g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); - - /* See cogl-pipeline.c for more details about why we leave texture unit 1 - * active by default... */ - context->active_texture_unit = 1; - GE (glActiveTexture (GL_TEXTURE1)); - - context->legacy_fog_state.enabled = FALSE; - - context->opaque_color_pipeline = cogl_pipeline_new (); - context->blended_color_pipeline = cogl_pipeline_new (); - context->texture_pipeline = cogl_pipeline_new (); - context->codegen_header_buffer = g_string_new (""); - context->codegen_source_buffer = g_string_new (""); - context->source_stack = NULL; - - context->legacy_state_set = 0; - - context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE; - context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE; - - context->framebuffers = NULL; - - context->journal_flush_attributes_array = - g_array_new (TRUE, FALSE, sizeof (CoglAttribute *)); - context->journal_clip_bounds = NULL; - - context->polygon_vertices = g_array_new (FALSE, FALSE, sizeof (float)); - - context->current_pipeline = NULL; - context->current_pipeline_changes_since_flush = 0; - context->current_pipeline_skip_gl_color = FALSE; - - context->pipeline0_nodes = - g_array_sized_new (FALSE, FALSE, sizeof (CoglHandle), 20); - context->pipeline1_nodes = - g_array_sized_new (FALSE, FALSE, sizeof (CoglHandle), 20); - - _cogl_bitmask_init (&context->arrays_enabled); - _cogl_bitmask_init (&context->temp_bitmask); - _cogl_bitmask_init (&context->arrays_to_change); - - context->max_texture_units = -1; - context->max_texture_image_units = -1; - context->max_activateable_texture_units = -1; - - context->current_program = COGL_INVALID_HANDLE; - - context->current_fragment_program_type = COGL_PIPELINE_PROGRAM_TYPE_FIXED; - context->current_vertex_program_type = COGL_PIPELINE_PROGRAM_TYPE_FIXED; - context->current_gl_program = 0; - - context->gl_blend_enable_cache = FALSE; - - context->depth_test_enabled_cache = FALSE; - context->depth_test_function_cache = COGL_DEPTH_TEST_FUNCTION_LESS; - context->depth_writing_enabled_cache = TRUE; - context->depth_range_near_cache = 0; - context->depth_range_far_cache = 1; - - context->point_size_cache = 1.0f; - - context->legacy_depth_test_enabled = FALSE; - -#ifdef HAVE_COGL_GL - _context->arbfp_cache = g_hash_table_new (_cogl_pipeline_fragend_arbfp_hash, - _cogl_pipeline_fragend_arbfp_equal); -#endif - - for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++) - context->current_buffer[i] = NULL; - - context->framebuffer_stack = _cogl_create_framebuffer_stack (); - - /* XXX: In this case the Clutter backend is still responsible for - * the OpenGL binding API and for creating onscreen framebuffers and - * so we have to add a dummy framebuffer to represent the backend - * owned window... */ - if (context->stub_winsys) - { - CoglOnscreen *window = _cogl_onscreen_new (); - cogl_set_framebuffer (COGL_FRAMEBUFFER (window)); - cogl_object_unref (COGL_FRAMEBUFFER (window)); - } - - _context->current_clip_stack_valid = FALSE; - - context->dirty_bound_framebuffer = TRUE; - context->dirty_gl_viewport = TRUE; - - context->current_path = cogl2_path_new (); - context->stencil_pipeline = cogl_pipeline_new (); - - context->in_begin_gl_block = FALSE; - - context->quad_buffer_indices_byte = COGL_INVALID_HANDLE; - context->quad_buffer_indices = COGL_INVALID_HANDLE; - context->quad_buffer_indices_len = 0; - - context->rectangle_byte_indices = NULL; - context->rectangle_short_indices = NULL; - context->rectangle_short_indices_len = 0; - - context->texture_download_pipeline = COGL_INVALID_HANDLE; - context->blit_texture_pipeline = COGL_INVALID_HANDLE; - -#ifndef HAVE_COGL_GLES2 - /* The default for GL_ALPHA_TEST is to always pass which is equivalent to - * the test being disabled therefore we assume that for all drivers there - * will be no performance impact if we always leave the test enabled which - * makes things a bit simpler for us. Under GLES2 the alpha test is - * implemented in the fragment shader so there is no enable for it - */ - GE (glEnable (GL_ALPHA_TEST)); -#endif - -#ifdef HAVE_COGL_GLES2 - _context->flushed_modelview_stack = NULL; - _context->flushed_projection_stack = NULL; -#endif - - /* Create default textures used for fall backs */ - context->default_gl_texture_2d_tex = - cogl_texture_new_from_data (1, /* width */ - 1, /* height */ - COGL_TEXTURE_NO_SLICING, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* data format */ - /* internal format */ - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 0, /* auto calc row stride */ - default_texture_data); - context->default_gl_texture_rect_tex = - cogl_texture_new_from_data (1, /* width */ - 1, /* height */ - COGL_TEXTURE_NO_SLICING, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* data format */ - /* internal format */ - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 0, /* auto calc row stride */ - default_texture_data); - - cogl_push_source (context->opaque_color_pipeline); - _cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0); - _cogl_enable (enable_flags); - _cogl_flush_face_winding (); - - context->atlases = NULL; - g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook)); - - _context->buffer_map_fallback_array = g_byte_array_new (); - _context->buffer_map_fallback_in_use = FALSE; - - /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect - unless GL_COORD_REPLACE is enabled for an individual - layer. Therefore it seems like it should be ok to just leave it - enabled all the time instead of having to have a set property on - each pipeline to track whether any layers have point sprite - coords enabled. We don't need to do this for GLES2 because point - sprites are handled using a builtin varying in the shader. */ -#ifndef HAVE_COGL_GLES2 - if (cogl_features_available (COGL_FEATURE_POINT_SPRITE)) - GE (glEnable (GL_POINT_SPRITE)); -#endif - - return _cogl_context_object_new (context); -} - -static void -_cogl_context_free (CoglContext *context) -{ - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - - winsys->context_deinit (context); - - _cogl_destroy_texture_units (); - - _cogl_free_framebuffer_stack (context->framebuffer_stack); - - if (context->current_path) - cogl_handle_unref (context->current_path); - - if (context->default_gl_texture_2d_tex) - cogl_handle_unref (context->default_gl_texture_2d_tex); - if (context->default_gl_texture_rect_tex) - cogl_handle_unref (context->default_gl_texture_rect_tex); - - if (context->opaque_color_pipeline) - cogl_handle_unref (context->opaque_color_pipeline); - if (context->blended_color_pipeline) - cogl_handle_unref (context->blended_color_pipeline); - if (context->texture_pipeline) - cogl_handle_unref (context->texture_pipeline); - - if (context->blit_texture_pipeline) - cogl_handle_unref (context->blit_texture_pipeline); - - if (context->journal_flush_attributes_array) - g_array_free (context->journal_flush_attributes_array, TRUE); - if (context->journal_clip_bounds) - g_array_free (context->journal_clip_bounds, TRUE); - - if (context->polygon_vertices) - g_array_free (context->polygon_vertices, TRUE); - - if (context->quad_buffer_indices_byte) - cogl_handle_unref (context->quad_buffer_indices_byte); - if (context->quad_buffer_indices) - cogl_handle_unref (context->quad_buffer_indices); - - if (context->rectangle_byte_indices) - cogl_object_unref (context->rectangle_byte_indices); - if (context->rectangle_short_indices) - cogl_object_unref (context->rectangle_short_indices); - - if (context->default_pipeline) - cogl_handle_unref (context->default_pipeline); - - if (context->dummy_layer_dependant) - cogl_handle_unref (context->dummy_layer_dependant); - if (context->default_layer_n) - cogl_handle_unref (context->default_layer_n); - if (context->default_layer_0) - cogl_handle_unref (context->default_layer_0); - - if (context->current_clip_stack_valid) - _cogl_clip_stack_unref (context->current_clip_stack); - - g_slist_free (context->atlases); - g_hook_list_clear (&context->atlas_reorganize_callbacks); - - _cogl_bitmask_destroy (&context->arrays_enabled); - _cogl_bitmask_destroy (&context->temp_bitmask); - _cogl_bitmask_destroy (&context->arrays_to_change); - - g_slist_free (context->texture_types); - g_slist_free (context->buffer_types); - -#ifdef HAVE_COGL_GLES2 - if (_context->flushed_modelview_stack) - cogl_object_unref (_context->flushed_modelview_stack); - if (_context->flushed_projection_stack) - cogl_object_unref (_context->flushed_projection_stack); -#endif - -#ifdef HAVE_COGL_GL - g_hash_table_unref (context->arbfp_cache); -#endif - - g_byte_array_free (context->buffer_map_fallback_array, TRUE); - - cogl_object_unref (context->display); - - g_free (context); -} - -CoglContext * -_cogl_context_get_default (void) -{ - GError *error = NULL; - /* Create if doesn't exist yet */ - if (_context == NULL) - { - _context = cogl_context_new (NULL, &error); - if (!_context) - { - g_warning ("Failed to create default context: %s", - error->message); - g_error_free (error); - } - } - - return _context; -} - -void -cogl_set_default_context (CoglContext *context) -{ - cogl_object_ref (context); - - if (_context) - cogl_object_unref (_context); - _context = context; -} - -#ifdef COGL_HAS_EGL_SUPPORT -EGLDisplay -cogl_context_egl_get_egl_display (CoglContext *context) -{ - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - return winsys->context_egl_get_egl_display (context); -} -#endif - diff --git a/clutter/cogl/cogl/cogl-context.h b/clutter/cogl/cogl/cogl-context.h deleted file mode 100644 index 7cd0785..0000000 --- a/clutter/cogl/cogl/cogl-context.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_CONTEXT_H__ -#define __COGL_CONTEXT_H__ - -#include - -#ifdef COGL_HAS_EGL_SUPPORT -#ifdef COGL_HAS_GLES1 -#include -#include -#else -#include -#define NativeDisplayType EGLNativeDisplayType -#define NativeWindowType EGLNativeWindowType -#endif -#endif - -G_BEGIN_DECLS - -/** - * SECTION:cogl-context - * @short_description: The top level application context. - * - * A CoglContext is the topmost sandbox of Cogl state for an - * application or toolkit. Its main purpose is to bind together the - * key state objects at any one time; with the most significant being - * the current framebuffer being drawn too (See #CoglFramebuffer for - * more details) and the current GPU pipeline configuration (See - * #CoglPipeline for more details). - */ - -typedef struct _CoglContext CoglContext; - -#define COGL_CONTEXT(OBJECT) ((CoglContext *)OBJECT) - -#define cogl_context_new cogl_context_new_EXP - -CoglContext * -cogl_context_new (CoglDisplay *display, - GError **error); - -#define cogl_set_default_context cogl_set_default_context_EXP -void -cogl_set_default_context (CoglContext *context); - -#ifdef COGL_HAS_EGL_SUPPORT -#define cogl_context_egl_get_egl_display cogl_context_egl_get_egl_display_EXP -EGLDisplay -cogl_context_egl_get_egl_display (CoglContext *context); -#endif - -G_END_DECLS - -#endif /* __COGL_CONTEXT_H__ */ - diff --git a/clutter/cogl/cogl/cogl-debug-options.h b/clutter/cogl/cogl/cogl-debug-options.h deleted file mode 100644 index 58d1283..0000000 --- a/clutter/cogl/cogl/cogl-debug-options.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -OPT (HANDLE, - "Cogl Tracing", - "ref-counts", - "CoglObject references", - "Debug ref counting issues for CoglObjects") -OPT (SLICING, - "Cogl Tracing", - "slicing", - "Trace Texture Slicing", - "debug the creation of texture slices") -OPT (ATLAS, - "Cogl Tracing", - "atlas", - "Trace Atlas Textures", - "Debug texture atlas management") -OPT (BLEND_STRINGS, - "Cogl Tracing", - "blend-strings", - "Trace Blend Strings", - "Debug CoglBlendString parsing") -OPT (JOURNAL, - "Cogl Tracing", - "journal", - "Trace Journal", - "View all the geometry passing through the journal") -OPT (BATCHING, - "Cogl Tracing", - "batching", - "Trace Batching", - "Show how geometry is being batched in the journal") -OPT (MATRICES, - "Cogl Tracing", - "matrices", - "Trace matrices", - "Trace all matrix manipulation") -/* XXX we should replace the "draw" option its very hand wavy... */ -OPT (DRAW, - "Cogl Tracing", - "draw", - "Trace Misc Drawing", - "Trace some misc drawing operations") -OPT (PANGO, - "Cogl Tracing", - "pango", - "Trace Pango Renderer", - "Trace the Cogl Pango renderer") -OPT (TEXTURE_PIXMAP, - "Cogl Tracing", - "texture-pixmap", - "Trace CoglTexturePixmap backend", - "Trace the Cogl texture pixmap backend") -OPT (RECTANGLES, - "Visualize", - "rectangles", - "Outline rectangles", - "Add wire outlines for all rectangular geometry") -OPT (WIREFRAME, - "Visualize", - "wireframe", - "Show wireframes", - "Add wire outlines for all geometry") -OPT (DISABLE_BATCHING, - "Root Cause", - "disable-batching", - "Disable Journal batching", - "Disable batching of geometry in the Cogl Journal.") -OPT (DISABLE_VBOS, - "Root Cause", - "disable-vbos", - "Disable GL Vertex Buffers", - "Disable use of OpenGL vertex buffer objects") -OPT (DISABLE_PBOS, - "Root Cause", - "disable-pbos", - "Disable GL Pixel Buffers", - "Disable use of OpenGL pixel buffer objects") -OPT (DISABLE_SOFTWARE_TRANSFORM, - "Root Cause", - "disable-software-transform", - "Disable software rect transform", - "Use the GPU to transform rectangular geometry") -OPT (DUMP_ATLAS_IMAGE, - "Cogl Specialist", - "dump-atlas-image", - "Dump atlas images", - "Dump texture atlas changes to an image file") -OPT (DISABLE_ATLAS, - "Root Cause", - "disable-atlas", - "Disable texture atlasing", - "Disable use of texture atlasing") -OPT (DISABLE_SHARED_ATLAS, - "Root Cause", - "disable-shared-atlas", - "Disable sharing the texture atlas between text and images", - "When this is set the glyph cache will always use a separate texture " - "for its atlas. Otherwise it will try to share the atlas with images.") -OPT (DISABLE_TEXTURING, - "Root Cause", - "disable-texturing", - "Disable texturing", - "Disable texturing any primitives") -OPT (DISABLE_ARBFP, - "Root Cause", - "disable-arbfp", - "Disable arbfp", - "Disable use of ARB fragment programs") -OPT (DISABLE_FIXED, - "Root Cause", - "disable-fixed", - "Disable fixed", - "Disable use of the fixed function pipeline backend") -OPT (DISABLE_GLSL, - "Root Cause", - "disable-glsl", - "Disable GLSL", - "Disable use of GLSL") -OPT (DISABLE_BLENDING, - "Root Cause", - "disable-blending", - "Disable blending", - "Disable use of blending") -OPT (DISABLE_NPOT_TEXTURES, - "Root Cause", - "disable-npot-textures", - "Disable non-power-of-two textures", - "Makes Cogl think that the GL driver doesn't support NPOT textures " - "so that it will create sliced textures or textures with waste instead.") -OPT (DISABLE_SOFTWARE_CLIP, - "Root Cause", - "disable-software-clip", - "Disable software clipping", - "Disables Cogl's attempts to clip some rectangles in software.") -OPT (SHOW_SOURCE, - "Cogl Tracing", - "show-source", - "Show source", - "Show generated ARBfp/GLSL source code") -OPT (OPENGL, - "Cogl Tracing", - "opengl", - "Trace some OpenGL", - "Traces some select OpenGL calls") -OPT (OFFSCREEN, - "Cogl Tracing", - "offscreen", - "Trace offscreen support", - "Debug offscreen support") -OPT (DISABLE_BLENDING, - "Root Cause", - "disable-program-caches", - "Disable program caches", - "Disable fallback caches for arbfp and glsl programs") -OPT (DISABLE_FAST_READ_PIXEL, - "Root Cause", - "disable-fast-read-pixel", - "Disable read pixel optimization", - "Disable optimization for reading 1px for simple " - "scenes of opaque rectangles") -OPT (CLIPPING, - "Cogl Tracing", - "clipping", - "Trace clipping", - "Logs information about how Cogl is implementing clipping") diff --git a/clutter/cogl/cogl/cogl-debug.c b/clutter/cogl/cogl/cogl-debug.c deleted file mode 100644 index 5b3ecc8..0000000 --- a/clutter/cogl/cogl/cogl-debug.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "cogl-debug.h" - -#ifdef COGL_ENABLE_DEBUG - -/* XXX: If you add a debug option, please also add an option - * definition to cogl-debug-options.h. This will enable us - for - * example - to emit a "help" description for the option. - */ - -/* NB: Only these options get enabled if COGL_DEBUG=all is - * used since they don't affect the behaviour of Cogl they - * simply print out verbose information */ -static const GDebugKey cogl_log_debug_keys[] = { - { "handle", COGL_DEBUG_HANDLE }, - { "slicing", COGL_DEBUG_SLICING }, - { "atlas", COGL_DEBUG_ATLAS }, - { "blend-strings", COGL_DEBUG_BLEND_STRINGS }, - { "journal", COGL_DEBUG_JOURNAL }, - { "batching", COGL_DEBUG_BATCHING }, - { "matrices", COGL_DEBUG_MATRICES }, - { "draw", COGL_DEBUG_DRAW }, - { "opengl", COGL_DEBUG_OPENGL }, - { "pango", COGL_DEBUG_PANGO }, - { "show-source", COGL_DEBUG_SHOW_SOURCE}, - { "offscreen", COGL_DEBUG_OFFSCREEN }, - { "texture-pixmap", COGL_DEBUG_TEXTURE_PIXMAP }, - { "bitmap", COGL_DEBUG_BITMAP }, - { "clipping", COGL_DEBUG_CLIPPING } -}; -static const int n_cogl_log_debug_keys = - G_N_ELEMENTS (cogl_log_debug_keys); - -static const GDebugKey cogl_behavioural_debug_keys[] = { - { "rectangles", COGL_DEBUG_RECTANGLES }, - { "disable-batching", COGL_DEBUG_DISABLE_BATCHING }, - { "disable-vbos", COGL_DEBUG_DISABLE_VBOS }, - { "disable-pbos", COGL_DEBUG_DISABLE_PBOS }, - { "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM }, - { "dump-atlas-image", COGL_DEBUG_DUMP_ATLAS_IMAGE }, - { "disable-atlas", COGL_DEBUG_DISABLE_ATLAS }, - { "disable-shared-atlas", COGL_DEBUG_DISABLE_SHARED_ATLAS }, - { "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING}, - { "disable-arbfp", COGL_DEBUG_DISABLE_ARBFP}, - { "disable-fixed", COGL_DEBUG_DISABLE_FIXED}, - { "disable-glsl", COGL_DEBUG_DISABLE_GLSL}, - { "disable-blending", COGL_DEBUG_DISABLE_BLENDING}, - { "disable-npot-textures", COGL_DEBUG_DISABLE_NPOT_TEXTURES}, - { "wireframe", COGL_DEBUG_WIREFRAME}, - { "disable-software-clip", COGL_DEBUG_DISABLE_SOFTWARE_CLIP}, - { "disable-program-caches", COGL_DEBUG_DISABLE_PROGRAM_CACHES}, - { "disable-fast-read-pixel", COGL_DEBUG_DISABLE_FAST_READ_PIXEL} -}; -static const int n_cogl_behavioural_debug_keys = - G_N_ELEMENTS (cogl_behavioural_debug_keys); - -unsigned int _cogl_debug_flags[COGL_DEBUG_N_INTS]; - -static void -_cogl_parse_debug_string_for_keys (const char *value, - gboolean enable, - const GDebugKey *keys, - unsigned int nkeys) -{ - int int_num, key_num; - - /* g_parse_debug_string expects the value field in GDebugKey to be a - mask in a guint but we may have multiple guints so we need to - build a separate array for each possible guint */ - - for (int_num = 0; int_num < COGL_DEBUG_N_INTS; int_num++) - { - GDebugKey keys_for_int[sizeof (unsigned int) * 8]; - unsigned int mask_for_int; - int nkeys_for_int = 0; - - for (key_num = 0; key_num < nkeys; key_num++) - if (COGL_FLAGS_GET_INDEX (keys[key_num].value) == int_num) - { - keys_for_int[nkeys_for_int] = keys[key_num]; - keys_for_int[nkeys_for_int].value = - COGL_FLAGS_GET_MASK (keys[key_num].value); - nkeys_for_int++; - } - - if (nkeys_for_int > 0) - { - mask_for_int = g_parse_debug_string (value, - keys_for_int, - nkeys_for_int); - if (enable) - _cogl_debug_flags[int_num] |= mask_for_int; - else - _cogl_debug_flags[int_num] &= ~mask_for_int; - } - } -} - -static void -_cogl_parse_debug_string (const char *value, - gboolean enable, - gboolean ignore_help) -{ - if (ignore_help && strcmp (value, "help") == 0) - return; - - /* We don't want to let g_parse_debug_string handle "all" because - * literally enabling all the debug options wouldn't be useful to - * anyone; instead the all option enables all non behavioural - * options. - */ - if (strcmp (value, "all") == 0 || - strcmp (value, "verbose") == 0) - { - int i; - for (i = 0; i < n_cogl_log_debug_keys; i++) - if (enable) - COGL_DEBUG_SET_FLAG (cogl_log_debug_keys[i].value); - else - COGL_DEBUG_CLEAR_FLAG (cogl_log_debug_keys[i].value); - } - else if (strcmp (value, "help") == 0) - { - g_printerr ("\n\n%28s\n", "Supported debug values:"); -#define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \ - g_printerr ("%28s %s\n", NAME ":", DESCRIPTION); -#include "cogl-debug-options.h" - g_printerr ("\n%28s\n", "Special debug values:"); - OPT (IGNORED, "ignored", "all", "ignored", \ - "Enables all non-behavioural debug options"); - OPT (IGNORED, "ignored", "verbose", "ignored", \ - "Enables all non-behavioural debug options"); -#undef OPT - exit (1); - } - else - { - _cogl_parse_debug_string_for_keys (value, - enable, - cogl_log_debug_keys, - n_cogl_log_debug_keys); - _cogl_parse_debug_string_for_keys (value, - enable, - cogl_behavioural_debug_keys, - n_cogl_behavioural_debug_keys); - } -} - -static gboolean -cogl_arg_debug_cb (const char *key, - const char *value, - gpointer user_data) -{ - _cogl_parse_debug_string (value, - TRUE /* enable the flags */, - FALSE /* don't ignore help */); - return TRUE; -} - -static gboolean -cogl_arg_no_debug_cb (const char *key, - const char *value, - gpointer user_data) -{ - _cogl_parse_debug_string (value, - FALSE, /* disable the flags */ - TRUE /* ignore help */); - return TRUE; -} -#endif /* COGL_ENABLE_DEBUG */ - -static GOptionEntry cogl_args[] = { -#ifdef COGL_ENABLE_DEBUG - { "cogl-debug", 0, 0, G_OPTION_ARG_CALLBACK, cogl_arg_debug_cb, - N_("Cogl debugging flags to set"), "FLAGS" }, - { "cogl-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, cogl_arg_no_debug_cb, - N_("Cogl debugging flags to unset"), "FLAGS" }, -#endif /* COGL_ENABLE_DEBUG */ - { NULL, }, -}; - -static gboolean -pre_parse_hook (GOptionContext *context, - GOptionGroup *group, - gpointer data, - GError **error) -{ -#ifdef COGL_ENABLE_DEBUG - const char *env_string; - - env_string = g_getenv ("COGL_DEBUG"); - if (env_string != NULL) - { - _cogl_parse_debug_string (env_string, - TRUE /* enable the flags */, - FALSE /* don't ignore help */); - env_string = NULL; - } -#endif /* COGL_ENABLE_DEBUG */ - - return TRUE; -} - -GOptionGroup * -cogl_get_option_group (void) -{ - GOptionGroup *group; - - group = g_option_group_new ("cogl", - _("Cogl Options"), - _("Show Cogl options"), - NULL, NULL); - - g_option_group_set_parse_hooks (group, pre_parse_hook, NULL); - g_option_group_add_entries (group, cogl_args); - g_option_group_set_translation_domain (group, GETTEXT_PACKAGE); - - return group; -} diff --git a/clutter/cogl/cogl/cogl-debug.h b/clutter/cogl/cogl/cogl-debug.h deleted file mode 100644 index 294de84..0000000 --- a/clutter/cogl/cogl/cogl-debug.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_DEBUG_H__ -#define __COGL_DEBUG_H__ - -#include "cogl-profile.h" -#include "cogl-flags.h" - -#include - -G_BEGIN_DECLS - -typedef enum { - COGL_DEBUG_SLICING, - COGL_DEBUG_OFFSCREEN, - COGL_DEBUG_DRAW, - COGL_DEBUG_PANGO, - COGL_DEBUG_RECTANGLES, - COGL_DEBUG_HANDLE, - COGL_DEBUG_BLEND_STRINGS, - COGL_DEBUG_DISABLE_BATCHING, - COGL_DEBUG_DISABLE_VBOS, - COGL_DEBUG_DISABLE_PBOS, - COGL_DEBUG_JOURNAL, - COGL_DEBUG_BATCHING, - COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM, - COGL_DEBUG_MATRICES, - COGL_DEBUG_ATLAS, - COGL_DEBUG_DUMP_ATLAS_IMAGE, - COGL_DEBUG_DISABLE_ATLAS, - COGL_DEBUG_DISABLE_SHARED_ATLAS, - COGL_DEBUG_OPENGL, - COGL_DEBUG_DISABLE_TEXTURING, - COGL_DEBUG_DISABLE_ARBFP, - COGL_DEBUG_DISABLE_FIXED, - COGL_DEBUG_DISABLE_GLSL, - COGL_DEBUG_SHOW_SOURCE, - COGL_DEBUG_DISABLE_BLENDING, - COGL_DEBUG_TEXTURE_PIXMAP, - COGL_DEBUG_BITMAP, - COGL_DEBUG_DISABLE_NPOT_TEXTURES, - COGL_DEBUG_WIREFRAME, - COGL_DEBUG_DISABLE_SOFTWARE_CLIP, - COGL_DEBUG_DISABLE_PROGRAM_CACHES, - COGL_DEBUG_DISABLE_FAST_READ_PIXEL, - COGL_DEBUG_CLIPPING, - COGL_DEBUG_WINSYS, - - COGL_DEBUG_N_FLAGS -} CoglDebugFlags; - -#ifdef COGL_ENABLE_DEBUG - -#define COGL_DEBUG_N_INTS COGL_FLAGS_N_INTS_FOR_SIZE (COGL_DEBUG_N_FLAGS) - -extern unsigned int _cogl_debug_flags[COGL_DEBUG_N_INTS]; - -#define COGL_DEBUG_ENABLED(flag) \ - COGL_FLAGS_GET (_cogl_debug_flags, flag) - -#define COGL_DEBUG_SET_FLAG(flag) \ - COGL_FLAGS_SET (_cogl_debug_flags, flag, TRUE) - -#define COGL_DEBUG_CLEAR_FLAG(flag) \ - COGL_FLAGS_SET (_cogl_debug_flags, flag, FALSE) - -#ifdef __GNUC__ -#define COGL_NOTE(type,x,a...) G_STMT_START { \ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_##type))) { \ - _cogl_profile_trace_message ("[" #type "] " G_STRLOC " & " x, ##a); \ - } } G_STMT_END - -#else -#define COGL_NOTE(type,...) G_STMT_START { \ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_##type)) { \ - char *_fmt = g_strdup_printf (__VA_ARGS__); \ - _cogl_profile_trace_message ("[" #type "] " G_STRLOC " & %s", _fmt);\ - g_free (_fmt); \ - } } G_STMT_END - -#endif /* __GNUC__ */ - -#else /* !COGL_ENABLE_DEBUG */ - -#define COGL_NOTE(type,...) G_STMT_START {} G_STMT_END - -#define COGL_DEBUG_ENABLED(flag) FALSE - -#define COGL_DEBUG_SET_FLAG(flag) \ - G_STMT_START { } G_STMT_END - -#define COGL_DEBUG_CLEAR_FLAG(flag) \ - G_STMT_START { } G_STMT_END - -#endif /* COGL_ENABLE_DEBUG */ - -G_END_DECLS - -#endif /* __COGL_DEBUG_H__ */ - diff --git a/clutter/cogl/cogl/cogl-defines.h.in b/clutter/cogl/cogl/cogl-defines.h.in deleted file mode 100644 index ccc7673..0000000 --- a/clutter/cogl/cogl/cogl-defines.h.in +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_DEFINES_H__ -#define __COGL_DEFINES_H__ - -#include -@COGL_GL_HEADER_INCLUDES@ - -G_BEGIN_DECLS - -@COGL_DEFINES@ - -G_END_DECLS - -#endif diff --git a/clutter/cogl/cogl/cogl-deprecated.h b/clutter/cogl/cogl/cogl-deprecated.h deleted file mode 100644 index aee5b1c..0000000 --- a/clutter/cogl/cogl/cogl-deprecated.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef COGL_DEPRECATED_H - -#define cogl_color cogl_color_REPLACED_BY_cogl_set_source_color -#define cogl_enable_depth_test cogl_enable_depth_test_RENAMED_TO_cogl_set_depth_test_enabled -#define cogl_enable_backface_culling cogl_enable_backface_culling_RENAMED_TO_cogl_set_backface_culling_enabled - -#define cogl_texture_rectangle cogl_texture_rectangle_REPLACE_BY_cogl_set_source_texture_AND_cogl_rectangle_with_texture_coords - -#define cogl_texture_multiple_rectangles cogl_texture_multiple_rectangles_REPLACED_BY_cogl_set_source_texture_AND_cogl_rectangles_with_texture_coords - -#define cogl_texture_polygon cogl_texture_polygon_REPLACED_BY_cogl_set_source_texture_AND_cogl_polygon - -#endif diff --git a/clutter/cogl/cogl/cogl-display-glx-private.h b/clutter/cogl/cogl/cogl-display-glx-private.h deleted file mode 100644 index 279b653..0000000 --- a/clutter/cogl/cogl/cogl-display-glx-private.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -#ifndef __COGL_DISPLAY_GLX_PRIVATE_H -#define __COGL_DISPLAY_GLX_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-display-xlib-private.h" - -typedef struct _CoglGLXCachedConfig -{ - /* This will be -1 if there is no cached config in this slot */ - int depth; - gboolean found; - GLXFBConfig fb_config; - gboolean can_mipmap; -} CoglGLXCachedConfig; - -#define COGL_GLX_N_CACHED_CONFIGS 3 - -typedef struct _CoglDisplayGLX -{ - CoglDisplayXlib _parent; - - CoglGLXCachedConfig glx_cached_configs[COGL_GLX_N_CACHED_CONFIGS]; - - gboolean found_fbconfig; - gboolean fbconfig_has_rgba_visual; - GLXFBConfig fbconfig; - - /* Single context for all wins */ - GLXContext glx_context; - GLXWindow dummy_glxwin; -} CoglDisplayGLX; - -#endif /* __COGL_DISPLAY_GLX_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-display-private.h b/clutter/cogl/cogl/cogl-display-private.h deleted file mode 100644 index 964dfb6..0000000 --- a/clutter/cogl/cogl/cogl-display-private.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -#ifndef __COGL_DISPLAY_PRIVATE_H -#define __COGL_DISPLAY_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-display.h" -#include "cogl-renderer.h" -#include "cogl-onscreen-template.h" - -struct _CoglDisplay -{ - CoglObject _parent; - - gboolean setup; - CoglRenderer *renderer; - CoglOnscreenTemplate *onscreen_template; - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT - struct gdl_plane *gdl_plane; -#endif - - void *winsys; -}; - -#endif /* __COGL_DISPLAY_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-display-xlib-private.h b/clutter/cogl/cogl/cogl-display-xlib-private.h deleted file mode 100644 index 6e28388..0000000 --- a/clutter/cogl/cogl/cogl-display-xlib-private.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -#ifndef __COGL_DISPLAY_XLIB_PRIVATE_H -#define __COGL_DISPLAY_XLIB_PRIVATE_H - -#include - -typedef struct _CoglDisplayXlib -{ - Window dummy_xwin; -} CoglDisplayXlib; - -#endif /* __COGL_DISPLAY_XLIB_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-display.c b/clutter/cogl/cogl/cogl-display.c deleted file mode 100644 index 0953f1f..0000000 --- a/clutter/cogl/cogl/cogl-display.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-object.h" - -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-winsys-private.h" - -static void _cogl_display_free (CoglDisplay *display); - -COGL_OBJECT_DEFINE (Display, display); - -GQuark -cogl_display_error_quark (void) -{ - return g_quark_from_static_string ("cogl-display-error-quark"); -} - -static void -_cogl_display_free (CoglDisplay *display) -{ - if (display->renderer) - { - cogl_object_unref (display->renderer); - display->renderer = NULL; - } - - if (display->onscreen_template) - { - cogl_object_unref (display->onscreen_template); - display->onscreen_template = NULL; - } - - g_slice_free (CoglDisplay, display); -} - -CoglDisplay * -cogl_display_new (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template) -{ - CoglDisplay *display = g_slice_new0 (CoglDisplay); - GError *error = NULL; - - display->renderer = renderer; - if (renderer) - cogl_object_ref (renderer); - else - display->renderer = cogl_renderer_new (); - - if (!cogl_renderer_connect (display->renderer, &error)) - { - g_warning ("Failed to connect renderer: %s\n", error->message); - g_error_free (error); - g_object_unref (display->renderer); - g_slice_free (CoglDisplay, display); - return NULL; - } - - display->onscreen_template = onscreen_template; - if (onscreen_template) - cogl_object_ref (onscreen_template); - - display->setup = FALSE; - - return _cogl_display_object_new (display); -} - -static const CoglWinsysVtable * -_cogl_display_get_winsys (CoglDisplay *display) -{ - return display->renderer->winsys_vtable; -} - -gboolean -cogl_display_setup (CoglDisplay *display, - GError **error) -{ -#ifdef COGL_HAS_FULL_WINSYS - const CoglWinsysVtable *winsys; -#endif - - if (display->setup) - return TRUE; - -#ifdef COGL_HAS_FULL_WINSYS - winsys = _cogl_display_get_winsys (display); - if (!winsys->display_setup (display, error)) - return FALSE; -#endif - - display->setup = TRUE; - - return TRUE; -} - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT -void -cogl_gdl_display_set_plane (CoglDisplay *display, - struct gdl_plane *plane) -{ - g_return_if_fail (display->setup == FALSE); - - display->gdl_plane = plane; -} -#endif - diff --git a/clutter/cogl/cogl/cogl-display.h b/clutter/cogl/cogl/cogl-display.h deleted file mode 100644 index 720b86b..0000000 --- a/clutter/cogl/cogl/cogl-display.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_DISPLAY_H__ -#define __COGL_DISPLAY_H__ - -#include -#include - -G_BEGIN_DECLS - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT -#include <@CLUTTER_CEX100_LIBGDL_PREFIX@libgdl.h> -#endif - -/** - * SECTION:cogl-display - * @short_description: Represents a display pipeline - * - * TODO: We still need to decide if we really need this object or if - * it's enough to just have the CoglSwapChain CoglOnscreenTemplate - * objects. - * - * The basic intention is for this object to let the application - * specify its display preferences before creating a context, and - * there are a few different aspects to this... - * - * Firstly there is the physical display pipeline that is currently - * being used including the digital to analogue conversion hardware - * and the screen the user sees. Although we don't have a plan to - * expose all the advanced features of arbitrary display hardware with - * a Cogl API, some backends may want to expose limited control over - * this hardware via Cogl and simpler features like providing a list - * of modes to choose from in a UI could be nice too. - * - * Another aspect is that the display configuration may be tightly - * related to how onscreen framebuffers should be configured. In fact - * one of the early rationals for this object was to let us handle - * GLX's requirement that framebuffers must be "compatible" with the - * fbconfig associated with the current context meaning we have to - * force the user to describe how they would like to create their - * onscreen windows before we can choose a suitable fbconfig and - * create a GLContext. - * - * TODO: continue this thought process and come to a decision... - */ - -typedef struct _CoglDisplay CoglDisplay; - -#define COGL_DISPLAY(OBJECT) ((CoglDisplay *)OBJECT) - -#define cogl_display_new cogl_display_new_EXP -CoglDisplay * -cogl_display_new (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template); - -#define cogl_display_setup cogl_display_setup_EXP -gboolean -cogl_display_setup (CoglDisplay *display, - GError **error); - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT -#define cogl_gdl_display_set_plane \ - cogl_gdl_display_set_plane_EXP -void -cogl_gdl_display_set_plane (CoglDisplay *display, - struct gdl_plane *plane); -#endif - -G_END_DECLS - -#endif /* __COGL_DISPLAY_H__ */ - diff --git a/clutter/cogl/cogl/cogl-enum-types.c.in b/clutter/cogl/cogl/cogl-enum-types.c.in deleted file mode 100644 index 157180d..0000000 --- a/clutter/cogl/cogl/cogl-enum-types.c.in +++ /dev/null @@ -1,41 +0,0 @@ -/*** BEGIN file-header ***/ -#include "cogl-enum-types.h" -#include "cogl.h" -/*** END file-header ***/ - -/*** BEGIN file-production ***/ - -/* enumerations from "@filename@" */ -#include "@filename@" - -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -GType -@enum_name@_get_type (void) -{ - static volatile gsize g_enum_type_id__volatile = 0; - - if (g_once_init_enter (&g_enum_type_id__volatile)) - { - static const G@Type@Value values[] = { -/*** END value-header ***/ - -/*** BEGIN value-production ***/ - { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -/*** END value-production ***/ - -/*** BEGIN value-tail ***/ - { 0, NULL, NULL } - }; - GType g_enum_type_id; - - g_enum_type_id = - g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); - - g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id); - } - - return g_enum_type_id__volatile; -} -/*** END value-tail ***/ diff --git a/clutter/cogl/cogl/cogl-enum-types.h.in b/clutter/cogl/cogl/cogl-enum-types.h.in deleted file mode 100644 index 23d705d..0000000 --- a/clutter/cogl/cogl/cogl-enum-types.h.in +++ /dev/null @@ -1,25 +0,0 @@ -/*** BEGIN file-header ***/ -#ifndef __COGL_ENUM_TYPES_H__ -#define __COGL_ENUM_TYPES_H__ - -#include - -G_BEGIN_DECLS - -/*** END file-header ***/ - -/*** BEGIN file-production ***/ -/* enumerations from "@filename@" */ -/*** END file-production ***/ - -/*** BEGIN file-tail ***/ -G_END_DECLS - -#endif /* !__CLUTTER_ENUM_TYPES_H__ */ -/*** END file-tail ***/ - -/*** BEGIN value-header ***/ -GType @enum_name@_get_type (void) G_GNUC_CONST; -#define COGL_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) - -/*** END value-header ***/ diff --git a/clutter/cogl/cogl/cogl-feature-private.c b/clutter/cogl/cogl/cogl-feature-private.c deleted file mode 100644 index d3904b4..0000000 --- a/clutter/cogl/cogl/cogl-feature-private.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl.h" -#include "cogl-context-private.h" - -#include "cogl-feature-private.h" - -gboolean -_cogl_feature_check (const char *driver_prefix, - const CoglFeatureData *data, - unsigned int gl_major, - unsigned int gl_minor, - const char *extensions_string, - void *function_table) - -{ - const char *suffix = NULL; - int func_num; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* First check whether the functions should be directly provided by - GL */ - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, - data->min_gl_major, data->min_gl_minor)) - suffix = ""; - else - { - /* Otherwise try all of the extensions */ - const char *namespace, *namespace_suffix; - unsigned int namespace_len; - - for (namespace = data->namespaces; - *namespace; - namespace += strlen (namespace) + 1) - { - const char *extension; - GString *full_extension_name = g_string_new (""); - - /* If the namespace part contains a ':' then the suffix for - the function names is different from the name space */ - if ((namespace_suffix = strchr (namespace, ':'))) - { - namespace_len = namespace_suffix - namespace; - namespace_suffix++; - } - else - { - namespace_len = strlen (namespace); - namespace_suffix = namespace; - } - - for (extension = data->extension_names; - *extension; - extension += strlen (extension) + 1) - { - g_string_assign (full_extension_name, driver_prefix); - g_string_append_c (full_extension_name, '_'); - g_string_append_len (full_extension_name, - namespace, namespace_len); - g_string_append_c (full_extension_name, '_'); - g_string_append (full_extension_name, extension); - if (!_cogl_check_extension (full_extension_name->str, - extensions_string)) - break; - } - - g_string_free (full_extension_name, TRUE); - - /* If we found all of the extensions with this namespace - then use it as the suffix */ - if (*extension == '\0') - { - suffix = namespace_suffix; - break; - } - } - } - - /* If we couldn't find anything that provides the functions then - give up */ - if (suffix == NULL) - return FALSE; - - /* Try to get all of the entry points */ - for (func_num = 0; data->functions[func_num].name; func_num++) - { - void *func; - char *full_function_name; - - full_function_name = g_strconcat (data->functions[func_num].name, - suffix, NULL); - func = cogl_get_proc_address (full_function_name); - g_free (full_function_name); - - if (func == NULL) - break; - - /* Set the function pointer in the context */ - *(void **) ((guint8 *) function_table + - data->functions[func_num].pointer_offset) = func; - } - - /* If one of the functions wasn't found then we should set all of - the function pointers back to NULL so that the rest of Cogl can - safely do feature testing by just looking at the function - pointers */ - if (data->functions[func_num].name) - { - while (func_num-- > 0) - *(void **) ((guint8 *) ctx + - data->functions[func_num].pointer_offset) = NULL; - return FALSE; - } - else - return TRUE; -} diff --git a/clutter/cogl/cogl/cogl-feature-private.h b/clutter/cogl/cogl/cogl-feature-private.h deleted file mode 100644 index 5d0101e..0000000 --- a/clutter/cogl/cogl/cogl-feature-private.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_FEATURE_PRIVATE_H -#define __COGL_FEATURE_PRIVATE_H - -#include - -#include "cogl-internal.h" - -#define COGL_CHECK_GL_VERSION(driver_major, driver_minor, \ - target_major, target_minor) \ - ((driver_major) > (target_major) || \ - ((driver_major) == (target_major) && (driver_minor) >= (target_minor))) - -typedef struct _CoglFeatureFunction CoglFeatureFunction; - -struct _CoglFeatureFunction -{ - /* The name of the function without the "EXT" or "ARB" suffix */ - const char *name; - /* The offset in the context of where to store the function pointer */ - unsigned int pointer_offset; -}; - -typedef struct _CoglFeatureData CoglFeatureData; - -struct _CoglFeatureData -{ - /* A minimum GL version which the functions should be defined in - without needing an extension. Set to 255,255 if it's only - provided in an extension */ - guint8 min_gl_major, min_gl_minor; - /* \0 separated list of namespaces to try. Eg "EXT\0ARB\0" */ - const char *namespaces; - /* \0 separated list of required extension names without the GL_EXT - or GL_ARB prefix. All of the extensions must be available for the - feature to be considered available. If the suffix for an - extension is different from the namespace, you can specify it - with a ':' after the namespace */ - const char *extension_names; - /* A set of feature flags to enable if the extension is available */ - CoglFeatureFlags feature_flags; - /* FIXME: This is now unused */ - int padding_feature_flags_private; - /* An optional corresponding winsys feature. */ - CoglWinsysFeature winsys_feature; - /* A list of functions required for this feature. Terminated with a - NULL name */ - const CoglFeatureFunction *functions; -}; - -gboolean -_cogl_feature_check (const char *driver_prefix, - const CoglFeatureData *data, - unsigned int gl_major, - unsigned int gl_minor, - const char *extensions_string, - void *function_table); - -#endif /* __COGL_FEATURE_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-fixed.c b/clutter/cogl/cogl/cogl-fixed.c deleted file mode 100644 index 99c7d5b..0000000 --- a/clutter/cogl/cogl/cogl-fixed.c +++ /dev/null @@ -1,950 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#define G_IMPLEMENT_INLINES - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-fixed.h" - -/* pre-computed sin table for 1st quadrant - * - * Currently contains 257 entries. - * - * The current maximum absolute error is about 1.9e-0.5 - * and is greatest around pi/2 where the second derivative - * of sin(x) is greatest. If greater accuracy is needed, - * modestly increasing the table size, or maybe using - * quadratic interpolation would drop the interpolation - * error below the precision limits of CoglFixed. - */ -static const CoglFixed sin_tbl[] = -{ - 0x00000000L, 0x00000192L, 0x00000324L, 0x000004B6L, - 0x00000648L, 0x000007DAL, 0x0000096CL, 0x00000AFEL, - 0x00000C90L, 0x00000E21L, 0x00000FB3L, 0x00001144L, - 0x000012D5L, 0x00001466L, 0x000015F7L, 0x00001787L, - 0x00001918L, 0x00001AA8L, 0x00001C38L, 0x00001DC7L, - 0x00001F56L, 0x000020E5L, 0x00002274L, 0x00002402L, - 0x00002590L, 0x0000271EL, 0x000028ABL, 0x00002A38L, - 0x00002BC4L, 0x00002D50L, 0x00002EDCL, 0x00003067L, - 0x000031F1L, 0x0000337CL, 0x00003505L, 0x0000368EL, - 0x00003817L, 0x0000399FL, 0x00003B27L, 0x00003CAEL, - 0x00003E34L, 0x00003FBAL, 0x0000413FL, 0x000042C3L, - 0x00004447L, 0x000045CBL, 0x0000474DL, 0x000048CFL, - 0x00004A50L, 0x00004BD1L, 0x00004D50L, 0x00004ECFL, - 0x0000504DL, 0x000051CBL, 0x00005348L, 0x000054C3L, - 0x0000563EL, 0x000057B9L, 0x00005932L, 0x00005AAAL, - 0x00005C22L, 0x00005D99L, 0x00005F0FL, 0x00006084L, - 0x000061F8L, 0x0000636BL, 0x000064DDL, 0x0000664EL, - 0x000067BEL, 0x0000692DL, 0x00006A9BL, 0x00006C08L, - 0x00006D74L, 0x00006EDFL, 0x00007049L, 0x000071B2L, - 0x0000731AL, 0x00007480L, 0x000075E6L, 0x0000774AL, - 0x000078ADL, 0x00007A10L, 0x00007B70L, 0x00007CD0L, - 0x00007E2FL, 0x00007F8CL, 0x000080E8L, 0x00008243L, - 0x0000839CL, 0x000084F5L, 0x0000864CL, 0x000087A1L, - 0x000088F6L, 0x00008A49L, 0x00008B9AL, 0x00008CEBL, - 0x00008E3AL, 0x00008F88L, 0x000090D4L, 0x0000921FL, - 0x00009368L, 0x000094B0L, 0x000095F7L, 0x0000973CL, - 0x00009880L, 0x000099C2L, 0x00009B03L, 0x00009C42L, - 0x00009D80L, 0x00009EBCL, 0x00009FF7L, 0x0000A130L, - 0x0000A268L, 0x0000A39EL, 0x0000A4D2L, 0x0000A605L, - 0x0000A736L, 0x0000A866L, 0x0000A994L, 0x0000AAC1L, - 0x0000ABEBL, 0x0000AD14L, 0x0000AE3CL, 0x0000AF62L, - 0x0000B086L, 0x0000B1A8L, 0x0000B2C9L, 0x0000B3E8L, - 0x0000B505L, 0x0000B620L, 0x0000B73AL, 0x0000B852L, - 0x0000B968L, 0x0000BA7DL, 0x0000BB8FL, 0x0000BCA0L, - 0x0000BDAFL, 0x0000BEBCL, 0x0000BFC7L, 0x0000C0D1L, - 0x0000C1D8L, 0x0000C2DEL, 0x0000C3E2L, 0x0000C4E4L, - 0x0000C5E4L, 0x0000C6E2L, 0x0000C7DEL, 0x0000C8D9L, - 0x0000C9D1L, 0x0000CAC7L, 0x0000CBBCL, 0x0000CCAEL, - 0x0000CD9FL, 0x0000CE8EL, 0x0000CF7AL, 0x0000D065L, - 0x0000D14DL, 0x0000D234L, 0x0000D318L, 0x0000D3FBL, - 0x0000D4DBL, 0x0000D5BAL, 0x0000D696L, 0x0000D770L, - 0x0000D848L, 0x0000D91EL, 0x0000D9F2L, 0x0000DAC4L, - 0x0000DB94L, 0x0000DC62L, 0x0000DD2DL, 0x0000DDF7L, - 0x0000DEBEL, 0x0000DF83L, 0x0000E046L, 0x0000E107L, - 0x0000E1C6L, 0x0000E282L, 0x0000E33CL, 0x0000E3F4L, - 0x0000E4AAL, 0x0000E55EL, 0x0000E610L, 0x0000E6BFL, - 0x0000E76CL, 0x0000E817L, 0x0000E8BFL, 0x0000E966L, - 0x0000EA0AL, 0x0000EAABL, 0x0000EB4BL, 0x0000EBE8L, - 0x0000EC83L, 0x0000ED1CL, 0x0000EDB3L, 0x0000EE47L, - 0x0000EED9L, 0x0000EF68L, 0x0000EFF5L, 0x0000F080L, - 0x0000F109L, 0x0000F18FL, 0x0000F213L, 0x0000F295L, - 0x0000F314L, 0x0000F391L, 0x0000F40CL, 0x0000F484L, - 0x0000F4FAL, 0x0000F56EL, 0x0000F5DFL, 0x0000F64EL, - 0x0000F6BAL, 0x0000F724L, 0x0000F78CL, 0x0000F7F1L, - 0x0000F854L, 0x0000F8B4L, 0x0000F913L, 0x0000F96EL, - 0x0000F9C8L, 0x0000FA1FL, 0x0000FA73L, 0x0000FAC5L, - 0x0000FB15L, 0x0000FB62L, 0x0000FBADL, 0x0000FBF5L, - 0x0000FC3BL, 0x0000FC7FL, 0x0000FCC0L, 0x0000FCFEL, - 0x0000FD3BL, 0x0000FD74L, 0x0000FDACL, 0x0000FDE1L, - 0x0000FE13L, 0x0000FE43L, 0x0000FE71L, 0x0000FE9CL, - 0x0000FEC4L, 0x0000FEEBL, 0x0000FF0EL, 0x0000FF30L, - 0x0000FF4EL, 0x0000FF6BL, 0x0000FF85L, 0x0000FF9CL, - 0x0000FFB1L, 0x0000FFC4L, 0x0000FFD4L, 0x0000FFE1L, - 0x0000FFECL, 0x0000FFF5L, 0x0000FFFBL, 0x0000FFFFL, - 0x00010000L, -}; - -/* pre-computed tan table for 1st quadrant */ -static const CoglFixed tan_tbl[] = -{ - 0x00000000L, 0x00000192L, 0x00000324L, 0x000004b7L, - 0x00000649L, 0x000007dbL, 0x0000096eL, 0x00000b01L, - 0x00000c94L, 0x00000e27L, 0x00000fbaL, 0x0000114eL, - 0x000012e2L, 0x00001477L, 0x0000160cL, 0x000017a1L, - 0x00001937L, 0x00001acdL, 0x00001c64L, 0x00001dfbL, - 0x00001f93L, 0x0000212cL, 0x000022c5L, 0x0000245fL, - 0x000025f9L, 0x00002795L, 0x00002931L, 0x00002aceL, - 0x00002c6cL, 0x00002e0aL, 0x00002faaL, 0x0000314aL, - 0x000032ecL, 0x0000348eL, 0x00003632L, 0x000037d7L, - 0x0000397dL, 0x00003b24L, 0x00003cccL, 0x00003e75L, - 0x00004020L, 0x000041ccL, 0x00004379L, 0x00004528L, - 0x000046d8L, 0x0000488aL, 0x00004a3dL, 0x00004bf2L, - 0x00004da8L, 0x00004f60L, 0x0000511aL, 0x000052d5L, - 0x00005492L, 0x00005651L, 0x00005812L, 0x000059d5L, - 0x00005b99L, 0x00005d60L, 0x00005f28L, 0x000060f3L, - 0x000062c0L, 0x0000648fL, 0x00006660L, 0x00006834L, - 0x00006a0aL, 0x00006be2L, 0x00006dbdL, 0x00006f9aL, - 0x0000717aL, 0x0000735dL, 0x00007542L, 0x0000772aL, - 0x00007914L, 0x00007b02L, 0x00007cf2L, 0x00007ee6L, - 0x000080dcL, 0x000082d6L, 0x000084d2L, 0x000086d2L, - 0x000088d6L, 0x00008adcL, 0x00008ce7L, 0x00008ef4L, - 0x00009106L, 0x0000931bL, 0x00009534L, 0x00009750L, - 0x00009971L, 0x00009b95L, 0x00009dbeL, 0x00009febL, - 0x0000a21cL, 0x0000a452L, 0x0000a68cL, 0x0000a8caL, - 0x0000ab0eL, 0x0000ad56L, 0x0000afa3L, 0x0000b1f5L, - 0x0000b44cL, 0x0000b6a8L, 0x0000b909L, 0x0000bb70L, - 0x0000bdddL, 0x0000c04fL, 0x0000c2c7L, 0x0000c545L, - 0x0000c7c9L, 0x0000ca53L, 0x0000cce3L, 0x0000cf7aL, - 0x0000d218L, 0x0000d4bcL, 0x0000d768L, 0x0000da1aL, - 0x0000dcd4L, 0x0000df95L, 0x0000e25eL, 0x0000e52eL, - 0x0000e806L, 0x0000eae7L, 0x0000edd0L, 0x0000f0c1L, - 0x0000f3bbL, 0x0000f6bfL, 0x0000f9cbL, 0x0000fce1L, - 0x00010000L, 0x00010329L, 0x0001065dL, 0x0001099aL, - 0x00010ce3L, 0x00011036L, 0x00011394L, 0x000116feL, - 0x00011a74L, 0x00011df6L, 0x00012184L, 0x0001251fL, - 0x000128c6L, 0x00012c7cL, 0x0001303fL, 0x00013410L, - 0x000137f0L, 0x00013bdfL, 0x00013fddL, 0x000143ebL, - 0x00014809L, 0x00014c37L, 0x00015077L, 0x000154c9L, - 0x0001592dL, 0x00015da4L, 0x0001622eL, 0x000166ccL, - 0x00016b7eL, 0x00017045L, 0x00017523L, 0x00017a17L, - 0x00017f22L, 0x00018444L, 0x00018980L, 0x00018ed5L, - 0x00019445L, 0x000199cfL, 0x00019f76L, 0x0001a53aL, - 0x0001ab1cL, 0x0001b11dL, 0x0001b73fL, 0x0001bd82L, - 0x0001c3e7L, 0x0001ca71L, 0x0001d11fL, 0x0001d7f4L, - 0x0001def1L, 0x0001e618L, 0x0001ed6aL, 0x0001f4e8L, - 0x0001fc96L, 0x00020473L, 0x00020c84L, 0x000214c9L, - 0x00021d44L, 0x000225f9L, 0x00022ee9L, 0x00023818L, - 0x00024187L, 0x00024b3aL, 0x00025534L, 0x00025f78L, - 0x00026a0aL, 0x000274edL, 0x00028026L, 0x00028bb8L, - 0x000297a8L, 0x0002a3fbL, 0x0002b0b5L, 0x0002bdddL, - 0x0002cb79L, 0x0002d98eL, 0x0002e823L, 0x0002f740L, - 0x000306ecL, 0x00031730L, 0x00032816L, 0x000339a6L, - 0x00034bebL, 0x00035ef2L, 0x000372c6L, 0x00038776L, - 0x00039d11L, 0x0003b3a6L, 0x0003cb48L, 0x0003e40aL, - 0x0003fe02L, 0x00041949L, 0x000435f7L, 0x0004542bL, - 0x00047405L, 0x000495a9L, 0x0004b940L, 0x0004def6L, - 0x00050700L, 0x00053196L, 0x00055ef9L, 0x00058f75L, - 0x0005c35dL, 0x0005fb14L, 0x00063709L, 0x000677c0L, - 0x0006bdd0L, 0x000709ecL, 0x00075ce6L, 0x0007b7bbL, - 0x00081b98L, 0x000889e9L, 0x0009046eL, 0x00098d4dL, - 0x000a2736L, 0x000ad593L, 0x000b9cc6L, 0x000c828aL, - 0x000d8e82L, 0x000ecb1bL, 0x001046eaL, 0x00121703L, - 0x00145b00L, 0x0017448dL, 0x001b2672L, 0x002095afL, - 0x0028bc49L, 0x0036519aL, 0x00517bb6L, 0x00a2f8fdL, - 0x46d3eab2L, -}; - -/* 257-value table of atan. - * - * atan_tbl[0] is atan(0.0) and atan_tbl[256] is atan(1). - * The angles are radians in CoglFixed truncated to 16-bit (they're - * all less than one) - */ -static const guint16 atan_tbl[] = -{ - 0x0000, 0x00FF, 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, - 0x07FF, 0x08FF, 0x09FE, 0x0AFE, 0x0BFD, 0x0CFD, 0x0DFC, 0x0EFB, - 0x0FFA, 0x10F9, 0x11F8, 0x12F7, 0x13F5, 0x14F3, 0x15F2, 0x16F0, - 0x17EE, 0x18EB, 0x19E9, 0x1AE6, 0x1BE3, 0x1CE0, 0x1DDD, 0x1ED9, - 0x1FD5, 0x20D1, 0x21CD, 0x22C8, 0x23C3, 0x24BE, 0x25B9, 0x26B3, - 0x27AD, 0x28A7, 0x29A1, 0x2A9A, 0x2B93, 0x2C8B, 0x2D83, 0x2E7B, - 0x2F72, 0x306A, 0x3160, 0x3257, 0x334D, 0x3442, 0x3538, 0x362D, - 0x3721, 0x3815, 0x3909, 0x39FC, 0x3AEF, 0x3BE2, 0x3CD4, 0x3DC5, - 0x3EB6, 0x3FA7, 0x4097, 0x4187, 0x4277, 0x4365, 0x4454, 0x4542, - 0x462F, 0x471C, 0x4809, 0x48F5, 0x49E0, 0x4ACB, 0x4BB6, 0x4CA0, - 0x4D89, 0x4E72, 0x4F5B, 0x5043, 0x512A, 0x5211, 0x52F7, 0x53DD, - 0x54C2, 0x55A7, 0x568B, 0x576F, 0x5852, 0x5934, 0x5A16, 0x5AF7, - 0x5BD8, 0x5CB8, 0x5D98, 0x5E77, 0x5F55, 0x6033, 0x6110, 0x61ED, - 0x62C9, 0x63A4, 0x647F, 0x6559, 0x6633, 0x670C, 0x67E4, 0x68BC, - 0x6993, 0x6A6A, 0x6B40, 0x6C15, 0x6CEA, 0x6DBE, 0x6E91, 0x6F64, - 0x7036, 0x7108, 0x71D9, 0x72A9, 0x7379, 0x7448, 0x7516, 0x75E4, - 0x76B1, 0x777E, 0x7849, 0x7915, 0x79DF, 0x7AA9, 0x7B72, 0x7C3B, - 0x7D03, 0x7DCA, 0x7E91, 0x7F57, 0x801C, 0x80E1, 0x81A5, 0x8269, - 0x832B, 0x83EE, 0x84AF, 0x8570, 0x8630, 0x86F0, 0x87AF, 0x886D, - 0x892A, 0x89E7, 0x8AA4, 0x8B5F, 0x8C1A, 0x8CD5, 0x8D8E, 0x8E47, - 0x8F00, 0x8FB8, 0x906F, 0x9125, 0x91DB, 0x9290, 0x9345, 0x93F9, - 0x94AC, 0x955F, 0x9611, 0x96C2, 0x9773, 0x9823, 0x98D2, 0x9981, - 0x9A2F, 0x9ADD, 0x9B89, 0x9C36, 0x9CE1, 0x9D8C, 0x9E37, 0x9EE0, - 0x9F89, 0xA032, 0xA0DA, 0xA181, 0xA228, 0xA2CE, 0xA373, 0xA418, - 0xA4BC, 0xA560, 0xA602, 0xA6A5, 0xA746, 0xA7E8, 0xA888, 0xA928, - 0xA9C7, 0xAA66, 0xAB04, 0xABA1, 0xAC3E, 0xACDB, 0xAD76, 0xAE11, - 0xAEAC, 0xAF46, 0xAFDF, 0xB078, 0xB110, 0xB1A7, 0xB23E, 0xB2D5, - 0xB36B, 0xB400, 0xB495, 0xB529, 0xB5BC, 0xB64F, 0xB6E2, 0xB773, - 0xB805, 0xB895, 0xB926, 0xB9B5, 0xBA44, 0xBAD3, 0xBB61, 0xBBEE, - 0xBC7B, 0xBD07, 0xBD93, 0xBE1E, 0xBEA9, 0xBF33, 0xBFBC, 0xC046, - 0xC0CE, 0xC156, 0xC1DD, 0xC264, 0xC2EB, 0xC371, 0xC3F6, 0xC47B, - 0xC4FF, 0xC583, 0xC606, 0xC689, 0xC70B, 0xC78D, 0xC80E, 0xC88F, - 0xC90F -}; - -/* look up table for square root */ -static const CoglFixed sqrt_tbl[] = -{ - 0x00000000L, 0x00010000L, 0x00016A0AL, 0x0001BB68L, - 0x00020000L, 0x00023C6FL, 0x00027312L, 0x0002A550L, - 0x0002D414L, 0x00030000L, 0x0003298BL, 0x0003510EL, - 0x000376CFL, 0x00039B05L, 0x0003BDDDL, 0x0003DF7CL, - 0x00040000L, 0x00041F84L, 0x00043E1EL, 0x00045BE1L, - 0x000478DEL, 0x00049524L, 0x0004B0BFL, 0x0004CBBCL, - 0x0004E624L, 0x00050000L, 0x00051959L, 0x00053237L, - 0x00054AA0L, 0x0005629AL, 0x00057A2BL, 0x00059159L, - 0x0005A828L, 0x0005BE9CL, 0x0005D4B9L, 0x0005EA84L, - 0x00060000L, 0x00061530L, 0x00062A17L, 0x00063EB8L, - 0x00065316L, 0x00066733L, 0x00067B12L, 0x00068EB4L, - 0x0006A21DL, 0x0006B54DL, 0x0006C847L, 0x0006DB0CL, - 0x0006ED9FL, 0x00070000L, 0x00071232L, 0x00072435L, - 0x0007360BL, 0x000747B5L, 0x00075935L, 0x00076A8CL, - 0x00077BBBL, 0x00078CC2L, 0x00079DA3L, 0x0007AE60L, - 0x0007BEF8L, 0x0007CF6DL, 0x0007DFBFL, 0x0007EFF0L, - 0x00080000L, 0x00080FF0L, 0x00081FC1L, 0x00082F73L, - 0x00083F08L, 0x00084E7FL, 0x00085DDAL, 0x00086D18L, - 0x00087C3BL, 0x00088B44L, 0x00089A32L, 0x0008A906L, - 0x0008B7C2L, 0x0008C664L, 0x0008D4EEL, 0x0008E361L, - 0x0008F1BCL, 0x00090000L, 0x00090E2EL, 0x00091C45L, - 0x00092A47L, 0x00093834L, 0x0009460CL, 0x000953CFL, - 0x0009617EL, 0x00096F19L, 0x00097CA1L, 0x00098A16L, - 0x00099777L, 0x0009A4C6L, 0x0009B203L, 0x0009BF2EL, - 0x0009CC47L, 0x0009D94FL, 0x0009E645L, 0x0009F32BL, - 0x000A0000L, 0x000A0CC5L, 0x000A1979L, 0x000A261EL, - 0x000A32B3L, 0x000A3F38L, 0x000A4BAEL, 0x000A5816L, - 0x000A646EL, 0x000A70B8L, 0x000A7CF3L, 0x000A8921L, - 0x000A9540L, 0x000AA151L, 0x000AAD55L, 0x000AB94BL, - 0x000AC534L, 0x000AD110L, 0x000ADCDFL, 0x000AE8A1L, - 0x000AF457L, 0x000B0000L, 0x000B0B9DL, 0x000B172DL, - 0x000B22B2L, 0x000B2E2BL, 0x000B3998L, 0x000B44F9L, - 0x000B504FL, 0x000B5B9AL, 0x000B66D9L, 0x000B720EL, - 0x000B7D37L, 0x000B8856L, 0x000B936AL, 0x000B9E74L, - 0x000BA973L, 0x000BB467L, 0x000BBF52L, 0x000BCA32L, - 0x000BD508L, 0x000BDFD5L, 0x000BEA98L, 0x000BF551L, - 0x000C0000L, 0x000C0AA6L, 0x000C1543L, 0x000C1FD6L, - 0x000C2A60L, 0x000C34E1L, 0x000C3F59L, 0x000C49C8L, - 0x000C542EL, 0x000C5E8CL, 0x000C68E0L, 0x000C732DL, - 0x000C7D70L, 0x000C87ACL, 0x000C91DFL, 0x000C9C0AL, - 0x000CA62CL, 0x000CB047L, 0x000CBA59L, 0x000CC464L, - 0x000CCE66L, 0x000CD861L, 0x000CE254L, 0x000CEC40L, - 0x000CF624L, 0x000D0000L, 0x000D09D5L, 0x000D13A2L, - 0x000D1D69L, 0x000D2727L, 0x000D30DFL, 0x000D3A90L, - 0x000D4439L, 0x000D4DDCL, 0x000D5777L, 0x000D610CL, - 0x000D6A9AL, 0x000D7421L, 0x000D7DA1L, 0x000D871BL, - 0x000D908EL, 0x000D99FAL, 0x000DA360L, 0x000DACBFL, - 0x000DB618L, 0x000DBF6BL, 0x000DC8B7L, 0x000DD1FEL, - 0x000DDB3DL, 0x000DE477L, 0x000DEDABL, 0x000DF6D8L, - 0x000E0000L, 0x000E0922L, 0x000E123DL, 0x000E1B53L, - 0x000E2463L, 0x000E2D6DL, 0x000E3672L, 0x000E3F70L, - 0x000E4869L, 0x000E515DL, 0x000E5A4BL, 0x000E6333L, - 0x000E6C16L, 0x000E74F3L, 0x000E7DCBL, 0x000E869DL, - 0x000E8F6BL, 0x000E9832L, 0x000EA0F5L, 0x000EA9B2L, - 0x000EB26BL, 0x000EBB1EL, 0x000EC3CBL, 0x000ECC74L, - 0x000ED518L, 0x000EDDB7L, 0x000EE650L, 0x000EEEE5L, - 0x000EF775L, 0x000F0000L, 0x000F0886L, 0x000F1107L, - 0x000F1984L, 0x000F21FCL, 0x000F2A6FL, 0x000F32DDL, - 0x000F3B47L, 0x000F43ACL, 0x000F4C0CL, 0x000F5468L, - 0x000F5CBFL, 0x000F6512L, 0x000F6D60L, 0x000F75AAL, - 0x000F7DEFL, 0x000F8630L, 0x000F8E6DL, 0x000F96A5L, - 0x000F9ED9L, 0x000FA709L, 0x000FAF34L, 0x000FB75BL, - 0x000FBF7EL, 0x000FC79DL, 0x000FCFB7L, 0x000FD7CEL, - 0x000FDFE0L, 0x000FE7EEL, 0x000FEFF8L, 0x000FF7FEL, - 0x00100000L, -}; - -/* the difference of the angle for two adjacent values in the - * sin_tbl table, expressed as CoglFixed number - */ -static const int sin_tbl_size = G_N_ELEMENTS (sin_tbl) - 1; - -static const double _magic = 68719476736.0 * 1.5; - -/* Where in the 64 bits of double is the mantissa. - * - * FIXME - this should go inside the configure.ac - */ -#if (__FLOAT_WORD_ORDER == 1234) -#define _COGL_MAN 0 -#elif (__FLOAT_WORD_ORDER == 4321) -#define _COGL_MAN 1 -#else -#define COGL_NO_FAST_CONVERSIONS -#endif - -/* - * cogl_double_to_fixed : - * @value: value to be converted - * - * A fast conversion from double precision floating to fixed point - * - * Return value: Fixed point representation of the value - */ -CoglFixed -cogl_double_to_fixed (double val) -{ -#ifdef COGL_NO_FAST_CONVERSIONS - return (CoglFixed) (val * (double) COGL_FIXED_1); -#else - union { - double d; - unsigned int i[2]; - } dbl; - - dbl.d = val; - dbl.d = dbl.d + _magic; - - return dbl.i[_COGL_MAN]; -#endif -} - -/* - * cogl_double_to_int : - * @value: value to be converted - * - * A fast conversion from doulbe precision floatint point to int; - * used this instead of casting double/float to int. - * - * Return value: Integer part of the double - */ -int -cogl_double_to_int (double val) -{ -#ifdef COGL_NO_FAST_CONVERSIONS - return (int) (val); -#else - union { - double d; - unsigned int i[2]; - } dbl; - - dbl.d = val; - dbl.d = dbl.d + _magic; - - return ((int) dbl.i[_COGL_MAN]) >> 16; -#endif -} - -unsigned int -cogl_double_to_uint (double val) -{ -#ifdef COGL_NO_FAST_CONVERSIONS - return (unsigned int)(val); -#else - union { - double d; - unsigned int i[2]; - } dbl; - - dbl.d = val; - dbl.d = dbl.d + _magic; - - return (dbl.i[_COGL_MAN]) >> 16; -#endif -} - -#undef _COGL_MAN - -CoglFixed -cogl_fixed_sin (CoglFixed angle) -{ - int sign = 1, indx1, indx2; - CoglFixed low, high; - CoglFixed p1, p2; - CoglFixed d1, d2; - - /* convert negative angle to positive + sign */ - if ((int) angle < 0) - { - sign = -sign; - angle = -angle; - } - - /* reduce to <0, 2*pi) */ - angle = angle % COGL_FIXED_2_PI; - - /* reduce to first quadrant and sign */ - if (angle > COGL_FIXED_PI) - { - sign = -sign; - - if (angle > COGL_FIXED_PI + COGL_FIXED_PI_2) - { - /* fourth qudrant */ - angle = COGL_FIXED_2_PI - angle; - } - else - { - /* third quadrant */ - angle -= COGL_FIXED_PI; - } - } - else - { - if (angle > COGL_FIXED_PI_2) - { - /* second quadrant */ - angle = COGL_FIXED_PI - angle; - } - } - - /* Calculate indices of the two nearest values in our table - * and return weighted average. - * - * We multiple first than divide to preserve precision. Since - * angle is in the first quadrant, angle * SIN_TBL_SIZE (=256) - * can't overflow. - * - * Handle the end of the table gracefully - */ - indx1 = (angle * sin_tbl_size) / COGL_FIXED_PI_2; - - if (indx1 == sin_tbl_size) - { - indx2 = indx1; - indx1 = indx2 - 1; - } - else - { - indx2 = indx1 + 1; - } - - low = sin_tbl[indx1]; - high = sin_tbl[indx2]; - - /* Again multiply the divide; no danger of overflow */ - p1 = (indx1 * COGL_FIXED_PI_2) / sin_tbl_size; - p2 = (indx2 * COGL_FIXED_PI_2) / sin_tbl_size; - d1 = angle - p1; - d2 = p2 - angle; - - angle = ((low * d2 + high * d1) / (p2 - p1)); - - if (sign < 0) - angle = -angle; - - return angle; -} - -CoglFixed -cogl_angle_sin (CoglAngle angle) -{ - int sign = 1; - CoglFixed result; - - /* reduce negative angle to positive + sign */ - if (angle < 0) - { - sign = -sign; - angle = -angle; - } - - /* reduce to <0, 2*pi) */ - angle &= 0x3ff; - - /* reduce to first quadrant and sign */ - if (angle > 512) - { - sign = -sign; - - if (angle > 768) - { - /* fourth qudrant */ - angle = 1024 - angle; - } - else - { - /* third quadrant */ - angle -= 512; - } - } - else - { - if (angle > 256) - { - /* second quadrant */ - angle = 512 - angle; - } - } - - result = sin_tbl[angle]; - - if (sign < 0) - result = -result; - - return result; -} - -CoglFixed -cogl_fixed_tan (CoglFixed angle) -{ - return cogl_angle_tan (COGL_ANGLE_FROM_DEGX (angle)); -} - -CoglFixed -cogl_angle_tan (CoglAngle angle) -{ - int sign = 1; - CoglFixed result; - - /* reduce negative angle to positive + sign */ - if (angle < 0) - { - sign = -sign; - angle = -angle; - } - - /* reduce to <0, pi) */ - angle &= 0x1ff; - - /* reduce to first quadrant and sign */ - if (angle > 256) - { - sign = -sign; - angle = 512 - angle; - } - - result = tan_tbl[angle]; - - if (sign < 0) - result = -result; - - return result; -} - -CoglFixed -cogl_fixed_atan (CoglFixed x) -{ - gboolean negative = FALSE; - CoglFixed angle; - - if (x < 0) - { - negative = TRUE; - x = -x; - } - - if (x > COGL_FIXED_1) - { - /* if x > 1 then atan(x) = pi/2 - atan(1/x) */ - angle = COGL_FIXED_PI / 2 - - atan_tbl[COGL_FIXED_DIV (COGL_FIXED_1, x) >> 8]; - } - else - angle = atan_tbl[x >> 8]; - - return negative ? -angle : angle; -} - -CoglFixed -cogl_fixed_atan2 (CoglFixed y, CoglFixed x) -{ - CoglFixed angle; - - if (x == 0) - angle = y >= 0 ? COGL_FIXED_PI_2 : -COGL_FIXED_PI_2; - else - { - angle = cogl_fixed_atan (COGL_FIXED_DIV (y, x)); - - if (x < 0) - angle += y >= 0 ? COGL_FIXED_PI : -COGL_FIXED_PI; - } - - return angle; -} - -CoglFixed -cogl_fixed_sqrt (CoglFixed x) -{ - /* The idea for this comes from the Alegro library, exploiting the - * fact that, - * sqrt (x) = sqrt (x/d) * sqrt (d); - * - * For d == 2^(n): - * - * sqrt (x) = sqrt (x/2^(2n)) * 2^n - * - * By locating suitable n for given x such that x >> 2n is in <0,255> - * we can use a LUT of precomputed values. - * - * This algorithm provides both good performance and precision; - * on ARM this function is about 5 times faster than c-lib sqrt, - * whilst producing errors < 1%. - */ - int t = 0; - int sh = 0; - unsigned int mask = 0x40000000; - unsigned fract = x & 0x0000ffff; - unsigned int d1, d2; - CoglFixed v1, v2; - - if (x <= 0) - return 0; - - if (x > COGL_FIXED_255 || x < COGL_FIXED_1) - { - /* - * Find the highest bit set - */ -#if __arm__ - /* This actually requires at least arm v5, but gcc does not seem - * to set the architecture defines correctly, and it is I think - * very unlikely that anyone will want to use clutter on anything - * less than v5. - */ - int bit; - __asm__ ("clz %0, %1\n" - "rsb %0, %0, #31\n" - :"=r"(bit) - :"r" (x)); - - /* make even (2n) */ - bit &= 0xfffffffe; -#else - /* TODO -- add i386 branch using bshr - * - * NB: it's been said that the bshr instruction is poorly implemented - * and that it is possible to write a faster code in C using binary - * search -- at some point we should explore this - */ - int bit = 30; - while (bit >= 0) - { - if (x & mask) - break; - - mask = (mask >> 1 | mask >> 2); - bit -= 2; - } -#endif - - /* now bit indicates the highest bit set; there are two scenarios - * - * 1) bit < 23: Our number is smaller so we shift it left to maximase - * precision (< 16 really, since <16,23> never goes - * through here. - * - * 2) bit > 23: our number is above the table, so we shift right - */ - - sh = ((bit - 22) >> 1); - if (bit >= 8) - t = (x >> (16 - 22 + bit)); - else - t = (x << (22 - 16 - bit)); - } - else - { - t = COGL_FIXED_TO_INT (x); - } - - /* Do a weighted average of the two nearest values */ - v1 = sqrt_tbl[t]; - v2 = sqrt_tbl[t+1]; - - /* - * 12 is fairly arbitrary -- we want integer that is not too big to cost - * us precision - */ - d1 = (unsigned)(fract) >> 12; - d2 = ((unsigned)COGL_FIXED_1 >> 12) - d1; - - x = ((v1*d2) + (v2*d1))/(COGL_FIXED_1 >> 12); - - if (sh > 0) - x = x << sh; - else if (sh < 0) - x = x >> -sh; - - return x; -} - -/** - * cogl_sqrti: - * @x: integer value - * - * Very fast fixed point implementation of square root for integers. - * - * This function is at least 6x faster than clib sqrt() on x86, and (this is - * not a typo!) about 500x faster on ARM without FPU. It's error is < 5% - * for arguments < %COGL_SQRTI_ARG_5_PERCENT and < 10% for arguments < - * %COGL_SQRTI_ARG_10_PERCENT. The maximum argument that can be passed to - * this function is COGL_SQRTI_ARG_MAX. - * - * Return value: integer square root. - * - * - * Since: 0.2 - */ -int -cogl_sqrti (int number) -{ -#if defined __SSE2__ - /* The GCC built-in with SSE2 (sqrtsd) is up to twice as fast as - * the pure integer code below. It is also more accurate. - */ - return __builtin_sqrt (number); -#else - /* This is a fixed point implementation of the Quake III sqrt algorithm, - * described, for example, at - * http://www.codemaestro.com/reviews/review00000105.html - * - * While the original QIII is extremely fast, the use of floating division - * and multiplication makes it perform very on arm processors without FPU. - * - * The key to successfully replacing the floating point operations with - * fixed point is in the choice of the fixed point format. The QIII - * algorithm does not calculate the square root, but its reciprocal ('y' - * below), which is only at the end turned to the inverse value. In order - * for the algorithm to produce satisfactory results, the reciprocal value - * must be represented with sufficient precission; the 16.16 we use - * elsewhere in clutter is not good enough, and 10.22 is used instead. - */ - CoglFixed x; - guint32 y_1; /* 10.22 fixed point */ - guint32 f = 0x600000; /* '1.5' as 10.22 fixed */ - - union - { - float f; - guint32 i; - } flt, flt2; - - flt.f = number; - - x = COGL_FIXED_FROM_INT (number) / 2; - - /* The QIII initial estimate */ - flt.i = 0x5f3759df - ( flt.i >> 1 ); - - /* Now, we convert the float to 10.22 fixed. We exploit the mechanism - * described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf. - * - * We want 22 bit fraction; a single precission float uses 23 bit - * mantisa, so we only need to add 2^(23-22) (no need for the 1.5 - * multiplier as we are only dealing with positive numbers). - * - * Note: we have to use two separate variables here -- for some reason, - * if we try to use just the flt variable, gcc on ARM optimises the whole - * addition out, and it all goes pear shape, since without it, the bits - * in the float will not be correctly aligned. - */ - flt2.f = flt.f + 2.0; - flt2.i &= 0x7FFFFF; - - /* Now we correct the estimate */ - y_1 = (flt2.i >> 11) * (flt2.i >> 11); - y_1 = (y_1 >> 8) * (x >> 8); - - y_1 = f - y_1; - flt2.i = (flt2.i >> 11) * (y_1 >> 11); - - /* If the original argument is less than 342, we do another - * iteration to improve precission (for arguments >= 342, the single - * iteration produces generally better results). - */ - if (x < 171) - { - y_1 = (flt2.i >> 11) * (flt2.i >> 11); - y_1 = (y_1 >> 8) * (x >> 8); - - y_1 = f - y_1; - flt2.i = (flt2.i >> 11) * (y_1 >> 11); - } - - /* Invert, round and convert from 10.22 to an integer - * 0x1e3c68 is a magical rounding constant that produces slightly - * better results than 0x200000. - */ - return (number * flt2.i + 0x1e3c68) >> 22; -#endif -} - -CoglFixed -cogl_fixed_mul (CoglFixed a, - CoglFixed b) -{ -#ifdef __arm__ - /* This provides about 12% speedeup on the gcc -O2 optimised - * C version - * - * Based on code found in the following thread: - * http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2006-August/014405.html - */ - int res_low, res_hi; - - __asm__ ("smull %0, %1, %2, %3 \n" - "mov %0, %0, lsr %4 \n" - "add %1, %0, %1, lsl %5 \n" - : "=r"(res_hi), "=r"(res_low) \ - : "r"(a), "r"(b), "i"(COGL_FIXED_Q), "i"(32 - COGL_FIXED_Q)); - - return (CoglFixed) res_low; -#else - gint64 r = (gint64) a * (gint64) b; - - return (CoglFixed) (r >> COGL_FIXED_Q); -#endif -} - -CoglFixed -cogl_fixed_div (CoglFixed a, - CoglFixed b) -{ - return (CoglFixed) ((((gint64) a) << COGL_FIXED_Q) / b); -} - -CoglFixed -cogl_fixed_mul_div (CoglFixed a, - CoglFixed b, - CoglFixed c) -{ - CoglFixed ab = cogl_fixed_mul (a, b); - CoglFixed quo = cogl_fixed_div (ab, c); - - return quo; -} - -/* - * The log2x() and pow2x() functions - * - * The implementation of the log2x() and pow2x() exploits the - * well-documented fact that the exponent part of IEEE floating - * number provides a good estimate of log2 of that number, while - * the mantissa serves as a good error-correction. - * - * The implementation here uses a quadratic error correction as - * described by Ian Stephenson at: - * http://www.dctsystems.co.uk/Software/power.html. - */ - -CoglFixed -cogl_fixed_log2 (unsigned int x) -{ - /* Note: we could easily have a version for CoglFixed x, but the int - * precision is enough for the current purposes. - */ - union - { - float f; - CoglFixed i; - } flt; - - CoglFixed magic = 0x58bb; - CoglFixed y; - - /* - * Convert x to float, then extract exponent. - * - * We want the result to be 16.16 fixed, so we shift (23-16) bits only - */ - flt.f = x; - flt.i >>= 7; - flt.i -= COGL_FIXED_FROM_INT (127); - - y = COGL_FIXED_FRACTION (flt.i); - - y = COGL_FIXED_MUL ((y - COGL_FIXED_MUL (y, y)), magic); - - return flt.i + y; -} - -unsigned int -cogl_fixed_pow2 (CoglFixed x) -{ - /* Note: we could easily have a version that produces CoglFixed result, - * but the range would be limited to x < 15, and the int precision - * is enough for the current purposes. - */ - - union - { - float f; - guint32 i; - } flt; - - CoglFixed magic = 0x56f7; - CoglFixed y; - - flt.i = x; - - /* - * Reverse of the log2x function -- convert the fixed value to a suitable - * floating point exponent, and mantisa adjusted with quadratic error - * correction y. - */ - y = COGL_FIXED_FRACTION (x); - y = COGL_FIXED_MUL ((y - COGL_FIXED_MUL (y, y)), magic); - - /* Shift the exponent into it's position in the floating point - * representation; as our number is not int but 16.16 fixed, shift only - * by (23 - 16) - */ - flt.i += (COGL_FIXED_FROM_INT (127) - y); - flt.i <<= 7; - - return COGL_FLOAT_TO_UINT (flt.f); -} - -unsigned int -cogl_fixed_pow (unsigned int x, - CoglFixed y) -{ - return cogl_fixed_pow2 (COGL_FIXED_MUL (y, cogl_fixed_log2 (x))); -} - -CoglFixed -cogl_angle_cos (CoglAngle angle) -{ - CoglAngle a = angle + 256; - - return cogl_angle_sin (a); -} - -CoglFixed -cogl_fixed_cos (CoglFixed angle) -{ - CoglFixed a = angle + COGL_FIXED_PI_2; - - return cogl_fixed_sin (a); -} diff --git a/clutter/cogl/cogl/cogl-fixed.h b/clutter/cogl/cogl/cogl-fixed.h deleted file mode 100644 index 5d7e567..0000000 --- a/clutter/cogl/cogl/cogl-fixed.h +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_FIXED_H__ -#define __COGL_FIXED_H__ - -#include - -/** - * SECTION:cogl-fixed - * @short_description: Fixed Point API - * - * COGL has a fixed point API targeted at platforms without a floating - * point unit, such as embedded devices. On such platforms this API should - * be preferred to the floating point one as it does not trigger the slow - * path of software emulation, relying on integer math for fixed-to-floating - * and floating-to-fixed notations conversion. - * - * It is not recommened for use on platforms with a floating point unit - * (e.g. desktop systems), nor for use in language bindings. - * - * Basic rules of Fixed Point arithmethic: - * - * - * Two fixed point numbers can be directly added, subtracted and - * have their modulus taken. - * - * - * To add other numerical type to a fixed point number it has to - * be first converted to fixed point. - * - * - * A fixed point number can be directly multiplied or divided by - * an integer. - * - * - * Two fixed point numbers can only be multiplied and divided by - * the provided %COGL_FIXED_MUL and %COGL_FIXED_DIV macros. - * - * - * - * The fixed point API is available since COGL 1.0. - */ - -G_BEGIN_DECLS - -/** - * COGL_FIXED_BITS: - * - * Evaluates to the number of bits used by the #CoglFixed type. - * - * Since: 1.0 - */ -#define COGL_FIXED_BITS (32) - -/** - * COGL_FIXED_Q: - * - * Evaluates to the number of bits used for the non-integer part - * of the #CoglFixed type. - * - * Since: 1.0 - */ -#define COGL_FIXED_Q (COGL_FIXED_BITS - 16) - -/** - * COGL_FIXED_1: - * - * The number 1 expressed as a #CoglFixed number. - * - * Since: 1.0 - */ -#define COGL_FIXED_1 (1 << COGL_FIXED_Q) - -/** - * COGL_FIXED_0_5: - * - * The number 0.5 expressed as a #CoglFixed number. - * - * Since: 1.0 - */ -#define COGL_FIXED_0_5 (32768) - -/** - * COGL_FIXED_EPSILON: - * - * A very small number expressed as a #CoglFixed number. - * - * Since: 1.0 - */ -#define COGL_FIXED_EPSILON (1) - -/** - * COGL_FIXED_MAX: - * - * The biggest number representable using #CoglFixed - * - * Since: 1.0 - */ -#define COGL_FIXED_MAX (0x7fffffff) - -/** - * COGL_FIXED_MIN: - * - * The smallest number representable using #CoglFixed - * - * Since: 1.0 - */ -#define COGL_FIXED_MIN (0x80000000) - -/** - * COGL_FIXED_PI: - * - * The number pi, expressed as a #CoglFixed number. - * - * Since: 1.0 - */ -#define COGL_FIXED_PI (0x0003243f) - -/** - * COGL_FIXED_2_PI: - * - * Two times pi, expressed as a #CoglFixed number. - * - * Since: 1.0 - */ -#define COGL_FIXED_2_PI (0x0006487f) - -/** - * COGL_FIXED_PI_2: - * - * Half pi, expressed as a #CoglFixed number. - * - * Since: 1.0 - */ -#define COGL_FIXED_PI_2 (0x00019220) - -/** - * COGL_FIXED_PI_4: - * - * pi / 4, expressed as #CoglFixed number. - * - * Since: 1.0 - */ -#define COGL_FIXED_PI_4 (0x0000c910) - -/** - * COGL_FIXED_360: - * - * Evaluates to the number 360 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_360 (COGL_FIXED_FROM_INT (360)) - -/** - * COGL_FIXED_270: - * - * Evaluates to the number 270 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_270 (COGL_FIXED_FROM_INT (270)) - -/** - * COGL_FIXED_255: - * - * Evaluates to the number 255 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_255 (COGL_FIXED_FROM_INT (255)) - -/** - * COGL_FIXED_240: - * - * Evaluates to the number 240 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_240 (COGL_FIXED_FROM_INT (240)) - -/** - * COGL_FIXED_180: - * - * Evaluates to the number 180 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_180 (COGL_FIXED_FROM_INT (180)) - -/** - * COGL_FIXED_120: - * - * Evaluates to the number 120 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_120 (COGL_FIXED_FROM_INT (120)) - -/** - * COGL_FIXED_90: - * - * Evaluates to the number 90 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_90 (COGL_FIXED_FROM_INT (90)) - -/** - * COGL_FIXED_60: - * - * Evaluates to the number 60 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_60 (COGL_FIXED_FROM_INT (60)) - -/** - * COGL_FIXED_45: - * - * Evaluates to the number 45 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_45 (COGL_FIXED_FROM_INT (45)) - -/** - * COGL_FIXED_30: - * - * Evaluates to the number 30 in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_30 (COGL_FIXED_FROM_INT (30)) - -/** - * COGL_RADIANS_TO_DEGREES: - * - * Evaluates to 180 / pi in fixed point notation. - * - * Since: 1.0 - */ -#define COGL_RADIANS_TO_DEGREES (0x394bb8) - -/* - * conversion macros - */ - -/** - * COGL_FIXED_FROM_FLOAT: - * @x: a floating point number - * - * Converts @x from a floating point to a fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_FROM_FLOAT(x) ((float) cogl_double_to_fixed (x)) - -/** - * COGL_FIXED_TO_FLOAT: - * @x: a #CoglFixed number - * - * Converts @x from a fixed point to a floating point notation, in - * single precision. - * - * Since: 1.0 - */ -#define COGL_FIXED_TO_FLOAT(x) ((float) ((int)(x) / 65536.0)) - -/** - * COGL_FIXED_FROM_DOUBLE: - * @x: a floating point number - * - * Converts @x from a double precision, floating point to a fixed - * point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_FROM_DOUBLE(x) (cogl_double_to_fixed (x)) - -/** - * COGL_FIXED_TO_DOUBLE: - * @x: a #CoglFixed number - * - * Converts @x from a fixed point to a floating point notation, in - * double precision. - * - * Since: 1.0 - */ -#define COGL_FIXED_TO_DOUBLE(x) ((double) ((int)(x) / 65536.0)) - -/** - * COGL_FIXED_FROM_INT: - * @x: an integer number - * - * Converts @x from an integer to a fixed point notation. - * - * Since: 1.0 - */ -#define COGL_FIXED_FROM_INT(x) ((x) << COGL_FIXED_Q) - -/** - * COGL_FIXED_TO_INT: - * @x: a #CoglFixed number - * - * Converts @x from a fixed point notation to an integer, dropping - * the fractional part without rounding. - * - * Since: 1.0 - */ -#define COGL_FIXED_TO_INT(x) ((x) >> COGL_FIXED_Q) - -/** - * COGL_FLOAT_TO_INT: - * @x: a floatint point number - * - * Converts @x from a floating point notation to a signed integer. - * - * Since: 1.0 - */ -#define COGL_FLOAT_TO_INT(x) (cogl_double_to_int ((x))) - -/** - * COGL_FLOAT_TO_UINT: - * @x: a floatint point number - * - * Converts @x from a floating point notation to an unsigned integer. - * - * Since: 1.0 - */ -#define COGL_FLOAT_TO_UINT(x) (cogl_double_to_uint ((x))) - -/* - * fixed point math functions - */ - -/** - * COGL_FIXED_FRACTION: - * @x: a #CoglFixed number - * - * Retrieves the fractionary part of @x. - * - * Since: 1.0 - */ -#define COGL_FIXED_FRACTION(x) ((x) & ((1 << COGL_FIXED_Q) - 1)) - -/** - * COGL_FIXED_FLOOR: - * @x: a #CoglFixed number - * - * Rounds down a fixed point number to the previous integer. - * - * Since: 1.0 - */ -#define COGL_FIXED_FLOOR(x) (((x) >= 0) ? ((x) >> COGL_FIXED_Q) \ - : ~((~(x)) >> COGL_FIXED_Q)) - -/** - * COGL_FIXED_CEIL: - * @x: a #CoglFixed number - * - * Rounds up a fixed point number to the next integer. - * - * Since: 1.0 - */ -#define COGL_FIXED_CEIL(x) (COGL_FIXED_FLOOR ((x) + 0xffff)) - -/** - * COGL_FIXED_MUL: - * @a: a #CoglFixed number - * @b: a #CoglFixed number - * - * Computes (a * b). - * - * Since: 1.0 - */ -#define COGL_FIXED_MUL(a,b) (cogl_fixed_mul ((a), (b))) - -/** - * COGL_FIXED_DIV: - * @a: a #CoglFixed number - * @b: a #CoglFixed number - * - * Computes (a / b). - * - * Since: 1.0 - */ -#define COGL_FIXED_DIV(a,b) (cogl_fixed_div ((a), (b))) - -/** - * COGL_FIXED_MUL_DIV: - * @a: a #CoglFixed number - * @b: a #CoglFixed number - * @c: a #CoglFixed number - * - * Computes ((a * b) / c). It is logically equivalent to: - * - * |[ - * res = COGL_FIXED_DIV (COGL_FIXED_MUL (a, b), c); - * ]| - * - * But it is shorter to type. - * - * Since: 1.0 - */ -#define COGL_FIXED_MUL_DIV(a,b,c) (cogl_fixed_mul_div ((a), (b), (c))) - -/** - * COGL_FIXED_FAST_MUL: - * @a: a #CoglFixed number - * @b: a #CoglFixed number - * - * Fast version of %COGL_FIXED_MUL, implemented as a macro. - * - * This macro might lose precision. If the precision of the result - * is important use %COGL_FIXED_MUL instead. - * - * Since: 1.0 - */ -#define COGL_FIXED_FAST_MUL(a,b) ((a) >> 8) * ((b) >> 8) - -/** - * COGL_FIXED_FAST_DIV: - * @a: a #CoglFixed number - * @b: a #CoglFixed number - * - * Fast version of %COGL_FIXED_DIV, implemented as a macro. - * - * This macro might lose precision. If the precision of the result - * is important use %COGL_FIXED_DIV instead. - * - * Since: 1.0 - */ -#define COGL_FIXED_FAST_DIV(a,b) ((((a) << 8) / (b)) << 8) - -/** - * cogl_fixed_sin: - * @angle: a #CoglFixed number - * - * Computes the sine of @angle. - * - * Return value: the sine of the passed angle, in fixed point notation - * - * Since: 1.0 - */ -CoglFixed -cogl_fixed_sin (CoglFixed angle); - -/** - * cogl_fixed_tan: - * @angle: a #CoglFixed number - * - * Computes the tangent of @angle. - * - * Return value: the tangent of the passed angle, in fixed point notation - * - * Since: 1.0 - */ -CoglFixed -cogl_fixed_tan (CoglFixed angle); - -/** - * cogl_fixed_cos: - * @angle: a #CoglFixed number - * - * Computes the cosine of @angle. - * - * Return value: the cosine of the passed angle, in fixed point notation - * - * Since: 1.0 - */ -CoglFixed cogl_fixed_cos (CoglFixed angle); - -/** - * cogl_fixed_atan: - * @a: a #CoglFixed number - * - * Computes the arc tangent of @a. - * - * Return value: the arc tangent of the passed value, in fixed point notation - * - * Since: 1.0 - */ -CoglFixed -cogl_fixed_atan (CoglFixed a); - -/** - * cogl_fixed_atan2: - * @a: the numerator as a #CoglFixed number - * @b: the denominator as a #CoglFixed number - * - * Computes the arc tangent of @a / @b but uses the sign of both - * arguments to return the angle in right quadrant. - * - * Return value: the arc tangent of the passed fraction, in fixed point - * notation - * - * Since: 1.0 - */ -CoglFixed -cogl_fixed_atan2 (CoglFixed a, - CoglFixed b); - -/*< public >*/ - -/* Fixed point math routines */ -G_INLINE_FUNC CoglFixed -cogl_fixed_mul (CoglFixed a, - CoglFixed b); - -G_INLINE_FUNC CoglFixed -cogl_fixed_div (CoglFixed a, - CoglFixed b); - -G_INLINE_FUNC CoglFixed -cogl_fixed_mul_div (CoglFixed a, - CoglFixed b, - CoglFixed c); - -/** - * COGL_SQRTI_ARG_MAX: - * - * Maximum argument that can be passed to cogl_sqrti() function. - * - * Since: 1.0 - */ -#ifndef __SSE2__ -#define COGL_SQRTI_ARG_MAX 0x3fffff -#else -#define COGL_SQRTI_ARG_MAX INT_MAX -#endif - -/** - * COGL_SQRTI_ARG_5_PERCENT: - * - * Maximum argument that can be passed to cogl_sqrti() for which the - * resulting error is < 5% - * - * Since: 1.0 - */ -#ifndef __SSE2__ -#define COGL_SQRTI_ARG_5_PERCENT 210 -#else -#define COGL_SQRTI_ARG_5_PERCENT INT_MAX -#endif - -/** - * COGL_SQRTI_ARG_10_PERCENT: - * - * Maximum argument that can be passed to cogl_sqrti() for which the - * resulting error is < 10% - * - * Since: 1.0 - */ -#ifndef __SSE2__ -#define COGL_SQRTI_ARG_10_PERCENT 5590 -#else -#define COGL_SQRTI_ARG_10_PERCENT INT_MAX -#endif - -/** - * cogl_fixed_sqrt: - * @x: a #CoglFixed number - * - * Computes the square root of @x. - * - * Return value: the square root of the passed value, in floating point - * notation - * - * Since: 1.0 - */ -CoglFixed -cogl_fixed_sqrt (CoglFixed x); - -/** - * cogl_fixed_log2: - * @x: value to calculate base 2 logarithm from - * - * Calculates base 2 logarithm. - * - * This function is some 2.5 times faster on x86, and over 12 times faster on - * fpu-less arm, than using libc log(). - * - * Return value: base 2 logarithm. - * - * Since: 1.0 - */ -CoglFixed -cogl_fixed_log2 (unsigned int x); - -/** - * cogl_fixed_pow2: - * @x: a #CoglFixed number - * - * Calculates 2 to the @x power. - * - * This function is around 11 times faster on x86, and around 22 times faster - * on fpu-less arm than libc pow(2, x). - * - * Return value: the power of 2 to the passed value - * - * Since: 1.0 - */ -unsigned int -cogl_fixed_pow2 (CoglFixed x); - -/** - * cogl_fixed_pow: - * @x: base - * @y: #CoglFixed exponent - * - * Calculates @x to the @y power. - * - * Return value: the power of @x to the @y - * - * Since: 1.0 - */ -unsigned int -cogl_fixed_pow (unsigned int x, - CoglFixed y); - -/** - * cogl_sqrti: - * @x: integer value - * - * Very fast fixed point implementation of square root for integers. - * - * This function is at least 6x faster than clib sqrt() on x86, and (this is - * not a typo!) about 500x faster on ARM without FPU. It's error is less than - * 5% for arguments smaller than %COGL_SQRTI_ARG_5_PERCENT and less than 10% - * for narguments smaller than %COGL_SQRTI_ARG_10_PERCENT. The maximum - * argument that can be passed to this function is %COGL_SQRTI_ARG_MAX. - * - * Return value: integer square root. - * - * Since: 1.0 - */ -int -cogl_sqrti (int x); - -/** - * COGL_ANGLE_FROM_DEG: - * @x: an angle in degrees in floating point notation - * - * Converts an angle in degrees into a #CoglAngle. - * - * Since: 1.0 - */ -#define COGL_ANGLE_FROM_DEG(x) (COGL_FLOAT_TO_INT (((float)(x) * 1024.0f) / 360.0f)) - -/** - * COGL_ANGLE_TO_DEG: - * @x: a #CoglAngle - * - * Converts a #CoglAngle into an angle in degrees, using floatint point - * notation. - * - * Since: 1.0 - */ -#define COGL_ANGLE_TO_DEG(x) (((float)(x) * 360.0) / 1024.0) - -/** - * COGL_ANGLE_FROM_DEGX: - * @x: an angle in degrees in fixed point notation - * - * Converts an angle in degrees into a #CoglAngle. - * - * Since: 1.0 - */ -#define COGL_ANGLE_FROM_DEGX(x) (COGL_FIXED_TO_INT ((((x) / 360) * 1024) + COGL_FIXED_0_5)) - -/** - * COGL_ANGLE_TO_DEGX: - * @x: a #CoglAngle - * - * Converts a #CoglAngle into an angle in degrees, using fixed point notation - * - * Since: 1.0 - */ -#define COGL_ANGLE_TO_DEGX(x) (COGL_FIXED_FROM_INT ((x) * 45) / 128) - -/** - * cogl_angle_sin: - * @angle: an angle expressed using #CoglAngle - * - * Computes the sine of @angle - * - * Return value: the sine of the passed angle - * - * Since: 1.0 - */ -CoglFixed -cogl_angle_sin (CoglAngle angle); - -/** - * cogl_angle_tan: - * @angle: an angle expressed using #CoglAngle - * - * Computes the tangent of @angle - * - * Return value: the tangent of the passed angle - * - * Since: 1.0 - */ -CoglFixed -cogl_angle_tan (CoglAngle angle); - -/** - * cogl_angle_cos: - * @angle: an angle expressed using #CoglAngle - * - * Computes the cosine of @angle - * - * Return value: the cosine of the passed angle - * - * Since: 1.0 - */ -CoglFixed -cogl_angle_cos (CoglAngle angle); - -/*< private >*/ - -#if defined (G_CAN_INLINE) -G_INLINE_FUNC CoglFixed -cogl_fixed_mul (CoglFixed a, - CoglFixed b) -{ -# ifdef __arm__ - int res_low, res_hi; - - __asm__ ("smull %0, %1, %2, %3 \n" - "mov %0, %0, lsr %4 \n" - "add %1, %0, %1, lsl %5 \n" - : "=r"(res_hi), "=r"(res_low)\ - : "r"(a), "r"(b), "i"(COGL_FIXED_Q), "i"(32 - COGL_FIXED_Q)); - - return (CoglFixed) res_low; -# else - long long r = (long long) a * (long long) b; - - return (unsigned int)(r >> COGL_FIXED_Q); -# endif -} -#endif - -#if defined (G_CAN_INLINE) -G_INLINE_FUNC CoglFixed -cogl_fixed_div (CoglFixed a, - CoglFixed b) -{ - return (CoglFixed) ((((gint64) a) << COGL_FIXED_Q) / b); -} -#endif - -#if defined(G_CAN_INLINE) -G_INLINE_FUNC CoglFixed -cogl_fixed_mul_div (CoglFixed a, - CoglFixed b, - CoglFixed c) -{ - CoglFixed ab = cogl_fixed_mul (a, b); - CoglFixed quo = cogl_fixed_div (ab, c); - - return quo; -} -#endif - -CoglFixed -cogl_double_to_fixed (double value); - -int -cogl_double_to_int (double value); - -unsigned int -cogl_double_to_uint (double value); - -G_END_DECLS - -#endif /* __COGL_FIXED_H__ */ diff --git a/clutter/cogl/cogl/cogl-flags.h b/clutter/cogl/cogl/cogl-flags.h deleted file mode 100644 index af07532..0000000 --- a/clutter/cogl/cogl/cogl-flags.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_FLAGS_H -#define __COGL_FLAGS_H - -#include - -G_BEGIN_DECLS - -/* These are macros used to implement a fixed-size array of bits. This - should be used instead of CoglBitmask when the maximum bit number - that will be set is known at compile time, for example when setting - for recording a set of known available features */ - -/* The bits are stored in an array of unsigned ints. It would probably - make sense to use unsigned long instead because then on 64-bit - systems where it can handle 64-bits just as easily and it can test - more bits. However GDebugKey uses a guint for the mask and we need - to fit the masks into this */ - -/* To use these macros, you would typically have an enum defining the - available bits with an extra last enum to define the maximum - value. Then to store the flags you would declare an array of - unsigned ints sized using COGL_FLAGS_N_INTS_FOR_SIZE, eg: - - typedef enum { FEATURE_A, FEATURE_B, FEATURE_C, N_FEATURES } Features; - - unsigned int feature_flags[COGL_FLAGS_N_INTS_FOR_SIZE (N_FEATURES)]; -*/ - -#define COGL_FLAGS_N_INTS_FOR_SIZE(size) \ - (((size) + \ - (sizeof (unsigned int) * 8 - 1)) \ - / (sizeof (unsigned int) * 8)) - -/* @flag is expected to be constant so these should result in a - constant expression. This means that setting a flag is equivalent - to just setting in a bit in a global variable at a known - location */ -#define COGL_FLAGS_GET_INDEX(flag) \ - ((flag) / (sizeof (unsigned int) * 8)) -#define COGL_FLAGS_GET_MASK(flag) \ - (1U << ((unsigned int) (flag) & \ - (sizeof (unsigned int) * 8 - 1))) - -#define COGL_FLAGS_GET(array, flag) \ - (!!((array)[COGL_FLAGS_GET_INDEX (flag)] & \ - COGL_FLAGS_GET_MASK (flag))) - -/* The expectation here is that @value will be constant so the if - statement will be optimised out */ -#define COGL_FLAGS_SET(array, flag, value) \ - G_STMT_START { \ - if (value) \ - ((array)[COGL_FLAGS_GET_INDEX (flag)] |= \ - COGL_FLAGS_GET_MASK (flag)); \ - else \ - ((array)[COGL_FLAGS_GET_INDEX (flag)] &= \ - ~COGL_FLAGS_GET_MASK (flag)); \ - } G_STMT_END - -G_END_DECLS - -#endif /* __COGL_FLAGS_H */ - diff --git a/clutter/cogl/cogl/cogl-framebuffer-private.h b/clutter/cogl/cogl/cogl-framebuffer-private.h deleted file mode 100644 index f48938f..0000000 --- a/clutter/cogl/cogl/cogl-framebuffer-private.h +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_FRAMEBUFFER_PRIVATE_H -#define __COGL_FRAMEBUFFER_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-matrix-stack.h" -#include "cogl-clip-state-private.h" -#include "cogl-journal-private.h" - -#ifdef COGL_HAS_XLIB_SUPPORT -#include -#endif - -#ifdef COGL_HAS_GLX_SUPPORT -#include -#include -#endif - -typedef enum _CoglFramebufferType { - COGL_FRAMEBUFFER_TYPE_ONSCREEN, - COGL_FRAMEBUFFER_TYPE_OFFSCREEN -} CoglFramebufferType; - -struct _CoglFramebuffer -{ - CoglObject _parent; - CoglContext *context; - CoglFramebufferType type; - int width; - int height; - /* Format of the pixels in the framebuffer (including the expected - premult state) */ - CoglPixelFormat format; - gboolean allocated; - - CoglMatrixStack *modelview_stack; - CoglMatrixStack *projection_stack; - float viewport_x; - float viewport_y; - float viewport_width; - float viewport_height; - - CoglClipState clip_state; - - gboolean dirty_bitmasks; - int red_bits; - int blue_bits; - int green_bits; - int alpha_bits; - - /* We journal the textured rectangles we want to submit to OpenGL so - * we have an oppertunity to batch them together into less draw - * calls. */ - CoglJournal *journal; - - /* The scene of a given framebuffer may depend on images in other - * framebuffers... */ - GList *deps; - - /* As part of an optimization for reading-back single pixels from a - * framebuffer in some simple cases where the geometry is still - * available in the journal we need to track the bounds of the last - * region cleared, its color and we need to track when something - * does in fact draw to that region so it is no longer clear. - */ - float clear_color_red; - float clear_color_green; - float clear_color_blue; - float clear_color_alpha; - int clear_clip_x0; - int clear_clip_y0; - int clear_clip_x1; - int clear_clip_y1; - gboolean clear_clip_dirty; -}; - -typedef struct _CoglOffscreen -{ - CoglFramebuffer _parent; - GLuint fbo_handle; - GSList *renderbuffers; - CoglHandle texture; -} CoglOffscreen; - -/* Flags to pass to _cogl_offscreen_new_to_texture_full */ -typedef enum -{ - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL = 1 -} CoglOffscreenFlags; - -#define COGL_OFFSCREEN(X) ((CoglOffscreen *)(X)) - -struct _CoglOnscreen -{ - CoglFramebuffer _parent; - -#ifdef COGL_HAS_X11_SUPPORT - guint32 foreign_xid; - CoglOnscreenX11MaskCallback foreign_update_mask_callback; - void *foreign_update_mask_data; -#endif - - gboolean swap_throttled; - - void *winsys; -}; - -void -_cogl_framebuffer_state_init (void); - -void -_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, - int width, int height); - -void -_cogl_clear4f (unsigned long buffers, - float red, - float green, - float blue, - float alpha); - -void -_cogl_framebuffer_clear (CoglFramebuffer *framebuffer, - unsigned long buffers, - const CoglColor *color); - -void -_cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - -void -_cogl_framebuffer_dirty (CoglFramebuffer *framebuffer); - -CoglClipState * -_cogl_framebuffer_get_clip_state (CoglFramebuffer *framebuffer); - -/* - * _cogl_framebuffer_get_clip_stack: - * @framebuffer: A #CoglFramebuffer - * - * Gets a pointer to the current clip stack. This can be used to later - * return to the same clip stack state with - * _cogl_framebuffer_set_clip_stack(). A reference is not taken on the - * stack so if you want to keep it you should call - * _cogl_clip_stack_ref(). - * - * Return value: a pointer to the @framebuffer clip stack. - */ -CoglClipStack * -_cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer); - -/* - * _cogl_framebuffer_set_clip_stack: - * @framebuffer: A #CoglFramebuffer - * @stack: a pointer to the replacement clip stack - * - * Replaces the @framebuffer clip stack with @stack. - */ -void -_cogl_framebuffer_set_clip_stack (CoglFramebuffer *framebuffer, - CoglClipStack *stack); - -void -_cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, - float x, - float y, - float width, - float height); -float -_cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer); - -float -_cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer); - -float -_cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer); - -float -_cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport); - -CoglMatrixStack * -_cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer); - -CoglMatrixStack * -_cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer, - CoglFramebuffer *dependency); - -void -_cogl_framebuffer_remove_all_dependencies (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer); - -gboolean -_cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglPixelFormat format, - guint8 *pixel); - -typedef enum _CoglFramebufferFlushFlags -{ - /* XXX: When using this, that imples you are going to manually load the - * modelview matrix (via glLoadMatrix). _cogl_matrix_stack_flush_to_gl wont - * be called for framebuffer->modelview_stack, and the modelview_stack will - * also be marked as dirty. */ - COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW = 1L<<0, - /* Similarly this flag implies you are going to flush the clip state - yourself */ - COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE = 1L<<1, - /* When using this all that will be updated is the glBindFramebuffer - * state and corresponding winsys state to make the framebuffer - * current if it is a CoglOnscreen framebuffer. */ - COGL_FRAMEBUFFER_FLUSH_BIND_ONLY = 1L<<2 -} CoglFramebufferFlushFlags; - -void -_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferFlushFlags flags); - -CoglFramebuffer * -_cogl_get_read_framebuffer (void); - -GSList * -_cogl_create_framebuffer_stack (void); - -void -_cogl_free_framebuffer_stack (GSList *stack); - -/* - * _cogl_offscreen_new_to_texture_full: - * @texhandle: A handle to the texture to target - * @create_flags: Flags specifying how to create the FBO - * @level: The mipmap level within the texture to target - * - * Creates a new offscreen buffer which will target the given - * texture. By default the buffer will have a depth and stencil - * buffer. This can be disabled by passing - * %COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL in @create_flags. - * - * Return value: the new CoglOffscreen object. - */ -CoglHandle -_cogl_offscreen_new_to_texture_full (CoglHandle texhandle, - CoglOffscreenFlags create_flags, - unsigned int level); - -/* - * _cogl_push_framebuffers: - * @draw_buffer: A pointer to the buffer used for drawing - * @read_buffer: A pointer to the buffer used for reading back pixels - * - * Redirects drawing and reading to the specified framebuffers as in - * cogl_push_framebuffer() except that it allows the draw and read - * buffer to be different. The buffers are pushed as a pair so that - * they can later both be restored with a single call to - * cogl_pop_framebuffer(). - */ -void -_cogl_push_framebuffers (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer); - -/* - * _cogl_blit_framebuffer: - * @src_x: Source x position - * @src_y: Source y position - * @dst_x: Destination x position - * @dst_y: Destination y position - * @width: Width of region to copy - * @height: Height of region to copy - * - * This blits a region of the color buffer of the current draw buffer - * to the current read buffer. The draw and read buffers can be set up - * using _cogl_push_framebuffers(). This function should only be - * called if the COGL_FEATURE_OFFSCREEN_BLIT feature is - * advertised. The two buffers must both be offscreen and have the - * same format. - * - * Note that this function differs a lot from the glBlitFramebuffer - * function provided by the GL_EXT_framebuffer_blit extension. Notably - * it doesn't support having different sizes for the source and - * destination rectangle. This isn't supported by the corresponding - * GL_ANGLE_framebuffer_blit extension on GLES2.0 and it doesn't seem - * like a particularly useful feature. If the application wanted to - * scale the results it may make more sense to draw a primitive - * instead. - * - * We can only really support blitting between two offscreen buffers - * for this function on GLES2.0. This is because we effectively render - * upside down to offscreen buffers to maintain Cogl's representation - * of the texture coordinate system where 0,0 is the top left of the - * texture. If we were to blit from an offscreen to an onscreen buffer - * then we would need to mirror the blit along the x-axis but the GLES - * extension does not support this. - * - * The GL function is documented to be affected by the scissor. This - * function therefore ensure that an empty clip stack is flushed - * before performing the blit which means the scissor is effectively - * ignored. - * - * The function also doesn't support specifying the buffers to copy - * and instead only the color buffer is copied. When copying the depth - * or stencil buffers the extension on GLES2.0 only supports copying - * the full buffer which would be awkward to document with this - * API. If we wanted to support that feature it may be better to have - * a separate function to copy the entire buffer for a given mask. - */ -void -_cogl_blit_framebuffer (unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height); - -CoglOnscreen * -_cogl_onscreen_new (void); - -#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-framebuffer.c b/clutter/cogl/cogl/cogl-framebuffer.c deleted file mode 100644 index daf817a..0000000 --- a/clutter/cogl/cogl/cogl-framebuffer.c +++ /dev/null @@ -1,1731 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-handle.h" -#include "cogl-object-private.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-clip-stack.h" -#include "cogl-journal-private.h" -#include "cogl-winsys-private.h" - -#ifndef HAVE_COGL_GLES2 - -#define glGenRenderbuffers ctx->drv.pf_glGenRenderbuffers -#define glDeleteRenderbuffers ctx->drv.pf_glDeleteRenderbuffers -#define glBindRenderbuffer ctx->drv.pf_glBindRenderbuffer -#define glRenderbufferStorage ctx->drv.pf_glRenderbufferStorage -#define glGenFramebuffers ctx->drv.pf_glGenFramebuffers -#define glBindFramebuffer ctx->drv.pf_glBindFramebuffer -#define glFramebufferTexture2D ctx->drv.pf_glFramebufferTexture2D -#define glFramebufferRenderbuffer ctx->drv.pf_glFramebufferRenderbuffer -#define glCheckFramebufferStatus ctx->drv.pf_glCheckFramebufferStatus -#define glDeleteFramebuffers ctx->drv.pf_glDeleteFramebuffers -#define glGetFramebufferAttachmentParameteriv \ - ctx->drv.pf_glGetFramebufferAttachmentParameteriv - -#endif - -#define glBlitFramebuffer ctx->drv.pf_glBlitFramebuffer - -#ifndef GL_FRAMEBUFFER -#define GL_FRAMEBUFFER 0x8D40 -#endif -#ifndef GL_RENDERBUFFER -#define GL_RENDERBUFFER 0x8D41 -#endif -#ifndef GL_STENCIL_ATTACHMENT -#define GL_STENCIL_ATTACHMENT 0x8D00 -#endif -#ifndef GL_COLOR_ATTACHMENT0 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#endif -#ifndef GL_FRAMEBUFFER_COMPLETE -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#endif -#ifndef GL_STENCIL_INDEX8 -#define GL_STENCIL_INDEX8 0x8D48 -#endif -#ifndef GL_DEPTH_STENCIL -#define GL_DEPTH_STENCIL 0x84F9 -#endif -#ifndef GL_DEPTH_ATTACHMENT -#define GL_DEPTH_ATTACHMENT 0x8D00 -#endif -#ifndef GL_DEPTH_COMPONENT16 -#define GL_DEPTH_COMPONENT16 0x81A5 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#endif -#ifndef GL_FRAMEBUFFER_ATTCHMENT_DEPTH_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#endif -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - -typedef enum { - _TRY_DEPTH_STENCIL = 1L<<0, - _TRY_DEPTH = 1L<<1, - _TRY_STENCIL = 1L<<2 -} TryFBOFlags; - -typedef struct _CoglFramebufferStackEntry -{ - CoglFramebuffer *draw_buffer; - CoglFramebuffer *read_buffer; -} CoglFramebufferStackEntry; - -static void _cogl_framebuffer_free (CoglFramebuffer *framebuffer); -static void _cogl_onscreen_free (CoglOnscreen *onscreen); -static void _cogl_offscreen_free (CoglOffscreen *offscreen); - -COGL_OBJECT_INTERNAL_DEFINE (Onscreen, onscreen); -COGL_OBJECT_DEFINE (Offscreen, offscreen); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (offscreen); - -/* XXX: - * The CoglObject macros don't support any form of inheritance, so for - * now we implement the CoglObject support for the CoglFramebuffer - * abstract class manually. - */ - -gboolean -_cogl_is_framebuffer (void *object) -{ - CoglHandleObject *obj = object; - - if (obj == NULL) - return FALSE; - - return obj->klass->type == _cogl_handle_onscreen_get_type () - || obj->klass->type == _cogl_handle_offscreen_get_type (); -} - -static void -_cogl_framebuffer_init (CoglFramebuffer *framebuffer, - CoglContext *ctx, - CoglFramebufferType type, - CoglPixelFormat format, - int width, - int height) -{ - framebuffer->context = cogl_object_ref (ctx); - - framebuffer->type = type; - framebuffer->width = width; - framebuffer->height = height; - framebuffer->format = format; - framebuffer->viewport_x = 0; - framebuffer->viewport_y = 0; - framebuffer->viewport_width = width; - framebuffer->viewport_height = height; - - framebuffer->modelview_stack = _cogl_matrix_stack_new (); - framebuffer->projection_stack = _cogl_matrix_stack_new (); - - framebuffer->dirty_bitmasks = TRUE; - - /* Initialise the clip stack */ - _cogl_clip_state_init (&framebuffer->clip_state); - - framebuffer->journal = _cogl_journal_new (); - - /* Ensure we know the framebuffer->clear_color* members can't be - * referenced for our fast-path read-pixel optimization (see - * _cogl_journal_try_read_pixel()) until some region of the - * framebuffer is initialized. - */ - framebuffer->clear_clip_dirty = TRUE; - - /* XXX: We have to maintain a central list of all framebuffers - * because at times we need to be able to flush all known journals. - * - * Examples where we need to flush all journals are: - * - because journal entries can reference OpenGL texture - * coordinates that may not survive texture-atlas reorganization - * so we need the ability to flush those entries. - * - because although we generally advise against modifying - * pipelines after construction we have to handle that possibility - * and since pipelines may be referenced in journal entries we - * need to be able to flush them before allowing the pipelines to - * be changed. - * - * Note we don't maintain a list of journals and associate - * framebuffers with journals by e.g. having a journal->framebuffer - * reference since that would introduce a circular reference. - * - * Note: As a future change to try and remove the need to index all - * journals it might be possible to defer resolving of OpenGL - * texture coordinates for rectangle primitives until we come to - * flush a journal. This would mean for instance that a single - * rectangle entry in a journal could later be expanded into - * multiple quad primitives to handle sliced textures but would mean - * we don't have to worry about retaining references to OpenGL - * texture coordinates that may later become invalid. - */ - ctx->framebuffers = g_list_prepend (ctx->framebuffers, framebuffer); -} - -void -_cogl_framebuffer_free (CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = framebuffer->context; - - _cogl_clip_state_destroy (&framebuffer->clip_state); - - cogl_object_unref (framebuffer->modelview_stack); - framebuffer->modelview_stack = NULL; - - cogl_object_unref (framebuffer->projection_stack); - framebuffer->projection_stack = NULL; - - cogl_object_unref (framebuffer->journal); - - ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer); - cogl_object_unref (ctx); -} - -static const CoglWinsysVtable * -_cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer) -{ - return framebuffer->context->display->renderer->winsys_vtable; -} - -/* This version of cogl_clear can be used internally as an alternative - * to avoid flushing the journal or the framebuffer state. This is - * needed when doing operations that may be called whiling flushing - * the journal */ -void -_cogl_clear4f (unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - GLbitfield gl_buffers = 0; - - if (buffers & COGL_BUFFER_BIT_COLOR) - { - GE( glClearColor (red, green, blue, alpha) ); - gl_buffers |= GL_COLOR_BUFFER_BIT; - } - - if (buffers & COGL_BUFFER_BIT_DEPTH) - gl_buffers |= GL_DEPTH_BUFFER_BIT; - - if (buffers & COGL_BUFFER_BIT_STENCIL) - gl_buffers |= GL_STENCIL_BUFFER_BIT; - - if (!gl_buffers) - { - static gboolean shown = FALSE; - - if (!shown) - { - g_warning ("You should specify at least one auxiliary buffer " - "when calling cogl_clear"); - } - - return; - } - - GE (glClear (gl_buffers)); -} - -void -_cogl_framebuffer_dirty (CoglFramebuffer *framebuffer) -{ - framebuffer->clear_clip_dirty = TRUE; -} - -void -_cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); - int scissor_x0; - int scissor_y0; - int scissor_x1; - int scissor_y1; - - g_return_if_fail (framebuffer->allocated); - - _cogl_clip_stack_get_bounds (clip_stack, - &scissor_x0, &scissor_y0, - &scissor_x1, &scissor_y1); - - /* NB: the previous clear could have had an arbitrary clip. - * NB: everything for the last frame might still be in the journal - * but we can't assume anything about how each entry was - * clipped. - * NB: Clutter will scissor its pick renders which would mean all - * journal entries have a common ClipStack entry, but without - * a layering violation Cogl has to explicitly walk the journal - * entries to determine if this is the case. - * NB: We have a software only read-pixel optimization in the - * journal that determines the color at a given framebuffer - * coordinate for simple scenes without rendering with the GPU. - * When Clutter is hitting this fast-path we can expect to - * receive calls to clear the framebuffer with an un-flushed - * journal. - * NB: To fully support software based picking for Clutter we - * need to be able to reliably detect when the contents of a - * journal can be discarded and when we can skip the call to - * glClear because it matches the previous clear request. - */ - - /* Note: we don't check for the stencil buffer being cleared here - * since there isn't any public cogl api to manipulate the stencil - * buffer. - * - * Note: we check for an exact clip match here because - * 1) a smaller clip could mean existing journal entries may - * need to contribute to regions outside the new clear-clip - * 2) a larger clip would mean we need to issue a real - * glClear and we only care about cases avoiding a - * glClear. - * - * Note: Comparing without an epsilon is considered - * appropriate here. - */ - if (buffers & COGL_BUFFER_BIT_COLOR && - buffers & COGL_BUFFER_BIT_DEPTH && - !framebuffer->clear_clip_dirty && - framebuffer->clear_color_red == red && - framebuffer->clear_color_green == green && - framebuffer->clear_color_blue == blue && - framebuffer->clear_color_alpha == alpha && - scissor_x0 == framebuffer->clear_clip_x0 && - scissor_y0 == framebuffer->clear_clip_y0 && - scissor_x1 == framebuffer->clear_clip_x1 && - scissor_y1 == framebuffer->clear_clip_y1) - { - /* NB: We only have to consider the clip state of journal - * entries if the current clear is clipped since otherwise we - * know every pixel of the framebuffer is affected by the clear - * and so all journal entries become redundant and can simply be - * discarded. - */ - if (clip_stack) - { - /* - * Note: the function for checking the journal entries is - * quite strict. It avoids detailed checking of all entry - * clip_stacks by only checking the details of the first - * entry and then it only verifies that the remaining - * entries share the same clip_stack ancestry. This means - * it's possible for some false negatives here but that will - * just result in us falling back to a real clear. - */ - if (_cogl_journal_all_entries_within_bounds (framebuffer->journal, - scissor_x0, scissor_y0, - scissor_x1, scissor_y1)) - { - _cogl_journal_discard (framebuffer->journal); - goto cleared; - } - } - else - { - _cogl_journal_discard (framebuffer->journal); - goto cleared; - } - } - - COGL_NOTE (DRAW, "Clear begin"); - - _cogl_framebuffer_flush_journal (framebuffer); - - /* NB: _cogl_framebuffer_flush_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. */ - _cogl_framebuffer_flush_state (framebuffer, framebuffer, 0); - - _cogl_clear4f (buffers, red, green, blue, alpha);; - - /* This is a debugging variable used to visually display the quad - * batches from the journal. It is reset here to increase the - * chances of getting the same colours for each frame during an - * animation */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_RECTANGLES)) && - buffers & COGL_BUFFER_BIT_COLOR) - { - framebuffer->context->journal_rectangles_color = 1; - } - - COGL_NOTE (DRAW, "Clear end"); - -cleared: - - if (buffers & COGL_BUFFER_BIT_COLOR && buffers & COGL_BUFFER_BIT_DEPTH) - { - /* For our fast-path for reading back a single pixel of simple - * scenes where the whole frame is in the journal we need to - * track the cleared color of the framebuffer in case the point - * read doesn't intersect any of the journal rectangles. */ - framebuffer->clear_clip_dirty = FALSE; - framebuffer->clear_color_red = red; - framebuffer->clear_color_green = green; - framebuffer->clear_color_blue = blue; - framebuffer->clear_color_alpha = alpha; - - /* NB: A clear may be scissored so we need to track the extents - * that the clear is applicable too... */ - if (clip_stack) - { - _cogl_clip_stack_get_bounds (clip_stack, - &framebuffer->clear_clip_x0, - &framebuffer->clear_clip_y0, - &framebuffer->clear_clip_x1, - &framebuffer->clear_clip_y1); - } - else - { - /* FIXME: set degenerate clip */ - } - } - else - _cogl_framebuffer_dirty (framebuffer); -} - -/* XXX: We'll need to consider if this API is a good approach for the - * planned, public, CoglFramebuffer API. A framebuffer may have - * multiple color buffers associated with it and the user may want to - * only clear a subset of those buffers. Flags aren't a great - * mechanism for handling this, but I don't think it would be very - * convenient if you had to explicitly enumerate the individual - * ancillary buffers to clear them. - * - * My current expectation is that we'll keep this flag based API but - * also add a way to enumerate the individual color buffers for - * clearing individually. - * - * Note: the 'buffers' and 'color' arguments were switched around on - * purpose compared to the original cogl_clear API since it was odd - * that you would be expected to specify a color before even - * necessarily choosing to clear the color buffer. - */ -void -_cogl_framebuffer_clear (CoglFramebuffer *framebuffer, - unsigned long buffers, - const CoglColor *color) -{ - g_return_if_fail (framebuffer->allocated); - - _cogl_framebuffer_clear4f (framebuffer, buffers, - cogl_color_get_red_float (color), - cogl_color_get_green_float (color), - cogl_color_get_blue_float (color), - cogl_color_get_alpha_float (color)); -} - -int -cogl_framebuffer_get_width (CoglFramebuffer *framebuffer) -{ - return framebuffer->width; -} - -int -cogl_framebuffer_get_height (CoglFramebuffer *framebuffer) -{ - return framebuffer->height; -} - -CoglClipState * -_cogl_framebuffer_get_clip_state (CoglFramebuffer *framebuffer) -{ - return &framebuffer->clip_state; -} - -CoglClipStack * -_cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer) -{ - CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - return _cogl_clip_state_get_stack (clip_state); -} - -void -_cogl_framebuffer_set_clip_stack (CoglFramebuffer *framebuffer, - CoglClipStack *stack) -{ - CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - _cogl_clip_state_set_stack (clip_state, stack); -} - -void -_cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, - float x, - float y, - float width, - float height) -{ - if (framebuffer->viewport_x == x && - framebuffer->viewport_y == y && - framebuffer->viewport_width == width && - framebuffer->viewport_height == height) - return; - - _cogl_framebuffer_flush_journal (framebuffer); - - framebuffer->viewport_x = x; - framebuffer->viewport_y = y; - framebuffer->viewport_width = width; - framebuffer->viewport_height = height; - - if (framebuffer->context && cogl_get_draw_framebuffer () == framebuffer) - framebuffer->context->dirty_gl_viewport = TRUE; -} - -float -_cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer) -{ - return framebuffer->viewport_x; -} - -float -_cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer) -{ - return framebuffer->viewport_y; -} - -float -_cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer) -{ - return framebuffer->viewport_width; -} - -float -_cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer) -{ - return framebuffer->viewport_height; -} - -void -_cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport) -{ - viewport[0] = framebuffer->viewport_x; - viewport[1] = framebuffer->viewport_y; - viewport[2] = framebuffer->viewport_width; - viewport[3] = framebuffer->viewport_height; -} - -CoglMatrixStack * -_cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer) -{ - return framebuffer->modelview_stack; -} - -CoglMatrixStack * -_cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer) -{ - return framebuffer->projection_stack; -} - -void -_cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer, - CoglFramebuffer *dependency) -{ - GList *l; - - for (l = framebuffer->deps; l; l = l->next) - { - CoglFramebuffer *existing_dep = l->data; - if (existing_dep == dependency) - return; - } - - /* TODO: generalize the primed-array type structure we e.g. use for - * cogl_object_set_user_data or for pipeline children as a way to - * avoid quite a lot of mid-scene micro allocations here... */ - framebuffer->deps = - g_list_prepend (framebuffer->deps, cogl_object_ref (dependency)); -} - -void -_cogl_framebuffer_remove_all_dependencies (CoglFramebuffer *framebuffer) -{ - GList *l; - for (l = framebuffer->deps; l; l = l->next) - cogl_object_unref (l->data); - g_list_free (framebuffer->deps); - framebuffer->deps = NULL; -} - -void -_cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer) -{ - _cogl_journal_flush (framebuffer->journal, framebuffer); -} - -void -_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer) -{ - GList *l; - for (l = framebuffer->deps; l; l = l->next) - _cogl_framebuffer_flush_journal (l->data); - _cogl_framebuffer_remove_all_dependencies (framebuffer); -} - -static inline void -_cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer) -{ -#ifdef HAVE_COGL_GL - CoglContext *ctx = framebuffer->context; -#endif - - if (G_LIKELY (!framebuffer->dirty_bitmasks)) - return; - -#ifdef HAVE_COGL_GL - if (cogl_features_available (COGL_FEATURE_OFFSCREEN) - && framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) - { - GLenum attachment, pname; - - attachment = GL_COLOR_ATTACHMENT0; - - pname = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE; - GE( glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - attachment, - pname, - &framebuffer->red_bits) ); - - pname = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE; - GE( glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - attachment, - pname, - &framebuffer->green_bits) ); - - pname = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE; - GE( glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - attachment, - pname, - &framebuffer->blue_bits) ); - - pname = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE; - GE( glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - attachment, - pname, - &framebuffer->alpha_bits) ); - } - else -#endif /* HAVE_COGL_GL */ - { - GE( glGetIntegerv (GL_RED_BITS, &framebuffer->red_bits) ); - GE( glGetIntegerv (GL_GREEN_BITS, &framebuffer->green_bits) ); - GE( glGetIntegerv (GL_BLUE_BITS, &framebuffer->blue_bits) ); - GE( glGetIntegerv (GL_ALPHA_BITS, &framebuffer->alpha_bits) ); - } - - - COGL_NOTE (OFFSCREEN, - "RGBA Bits for framebuffer[%p, %s]: %d, %d, %d, %d", - framebuffer, - framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN - ? "offscreen" - : "onscreen", - framebuffer->red_bits, - framebuffer->blue_bits, - framebuffer->green_bits, - framebuffer->alpha_bits); - - framebuffer->dirty_bitmasks = FALSE; -} - -typedef struct -{ - CoglHandle texture; - unsigned int level; - unsigned int level_width; - unsigned int level_height; -} CoglFramebufferTryFBOData; - -static gboolean -try_creating_fbo (CoglOffscreen *offscreen, - TryFBOFlags flags, - CoglFramebufferTryFBOData *data) -{ - GLuint gl_depth_stencil_handle; - GLuint gl_depth_handle; - GLuint gl_stencil_handle; - GLuint tex_gl_handle; - GLenum tex_gl_target; - GLuint fbo_gl_handle; - GLenum status; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!cogl_texture_get_gl_texture (data->texture, - &tex_gl_handle, &tex_gl_target)) - return FALSE; - - if (tex_gl_target != GL_TEXTURE_2D -#ifdef HAVE_COGL_GL - && tex_gl_target != GL_TEXTURE_RECTANGLE_ARB -#endif - ) - return FALSE; - - /* We are about to generate and bind a new fbo, so we pretend to - * change framebuffer state so that the old framebuffer will be - * rebound again before drawing. */ - ctx->dirty_bound_framebuffer = 1; - - /* Generate framebuffer */ - glGenFramebuffers (1, &fbo_gl_handle); - GE (glBindFramebuffer (GL_FRAMEBUFFER, fbo_gl_handle)); - offscreen->fbo_handle = fbo_gl_handle; - - GE (glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - tex_gl_target, tex_gl_handle, data->level)); - - if (flags & _TRY_DEPTH_STENCIL) - { - /* Create a renderbuffer for depth and stenciling */ - GE (glGenRenderbuffers (1, &gl_depth_stencil_handle)); - GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_stencil_handle)); - GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_STENCIL, - data->level_width, - data->level_height)); - GE (glBindRenderbuffer (GL_RENDERBUFFER, 0)); - GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, gl_depth_stencil_handle)); - GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, gl_depth_stencil_handle)); - offscreen->renderbuffers = - g_slist_prepend (offscreen->renderbuffers, - GUINT_TO_POINTER (gl_depth_stencil_handle)); - } - - if (flags & _TRY_DEPTH) - { - GE (glGenRenderbuffers (1, &gl_depth_handle)); - GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_handle)); - /* For now we just ask for GL_DEPTH_COMPONENT16 since this is all that's - * available under GLES */ - GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, - data->level_width, - data->level_height)); - GE (glBindRenderbuffer (GL_RENDERBUFFER, 0)); - GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, gl_depth_handle)); - offscreen->renderbuffers = - g_slist_prepend (offscreen->renderbuffers, - GUINT_TO_POINTER (gl_depth_handle)); - } - - if (flags & _TRY_STENCIL) - { - GE (glGenRenderbuffers (1, &gl_stencil_handle)); - GE (glBindRenderbuffer (GL_RENDERBUFFER, gl_stencil_handle)); - GE (glRenderbufferStorage (GL_RENDERBUFFER, GL_STENCIL_INDEX8, - data->level_width, - data->level_height)); - GE (glBindRenderbuffer (GL_RENDERBUFFER, 0)); - GE (glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, gl_stencil_handle)); - offscreen->renderbuffers = - g_slist_prepend (offscreen->renderbuffers, - GUINT_TO_POINTER (gl_stencil_handle)); - } - - /* Make sure it's complete */ - status = glCheckFramebufferStatus (GL_FRAMEBUFFER); - - if (status != GL_FRAMEBUFFER_COMPLETE) - { - GSList *l; - - GE (glDeleteFramebuffers (1, &fbo_gl_handle)); - - for (l = offscreen->renderbuffers; l; l = l->next) - { - GLuint renderbuffer = GPOINTER_TO_UINT (l->data); - GE (glDeleteRenderbuffers (1, &renderbuffer)); - } - - g_slist_free (offscreen->renderbuffers); - offscreen->renderbuffers = NULL; - - return FALSE; - } - - return TRUE; -} - -CoglHandle -_cogl_offscreen_new_to_texture_full (CoglHandle texhandle, - CoglOffscreenFlags create_flags, - unsigned int level) -{ - CoglOffscreen *offscreen; - static TryFBOFlags flags; - static gboolean have_working_flags = FALSE; - unsigned int i; - CoglFramebufferTryFBOData data; - gboolean fbo_created; - - if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) - return COGL_INVALID_HANDLE; - - /* Make texhandle is a valid texture object */ - if (!cogl_is_texture (texhandle)) - return COGL_INVALID_HANDLE; - - /* The texture must not be sliced */ - if (cogl_texture_is_sliced (texhandle)) - return COGL_INVALID_HANDLE; - - data.texture = texhandle; - data.level = level; - - /* Calculate the size of the texture at this mipmap level to ensure - that it's a valid level */ - data.level_width = cogl_texture_get_width (texhandle); - data.level_height = cogl_texture_get_height (texhandle); - - for (i = 0; i < level; i++) - { - /* If neither dimension can be further divided then the level is - invalid */ - if (data.level_width == 1 && data.level_height == 1) - return COGL_INVALID_HANDLE; - - if (data.level_width > 1) - data.level_width >>= 1; - if (data.level_height > 1) - data.level_height >>= 1; - } - - /* XXX: The framebuffer_object spec isn't clear in defining whether attaching - * a texture as a renderbuffer with mipmap filtering enabled while the - * mipmaps have not been uploaded should result in an incomplete framebuffer - * object. (different drivers make different decisions) - * - * To avoid an error with drivers that do consider this a problem we - * explicitly set non mipmapped filters here. These will later be reset when - * the texture is actually used for rendering according to the filters set on - * the corresponding CoglPipeline. - */ - _cogl_texture_set_filters (texhandle, GL_NEAREST, GL_NEAREST); - - offscreen = g_new0 (CoglOffscreen, 1); - offscreen->texture = texhandle; - - if ((create_flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL)) - fbo_created = try_creating_fbo (offscreen, 0, &data); - else - { - if ((have_working_flags && - try_creating_fbo (offscreen, flags, &data)) || -#ifdef HAVE_COGL_GL - try_creating_fbo (offscreen, flags = _TRY_DEPTH_STENCIL, &data) || -#endif - try_creating_fbo (offscreen, flags = _TRY_DEPTH | _TRY_STENCIL, - &data) || - try_creating_fbo (offscreen, flags = _TRY_STENCIL, &data) || - try_creating_fbo (offscreen, flags = _TRY_DEPTH, &data) || - try_creating_fbo (offscreen, flags = 0, &data)) - { - /* Record that the last set of flags succeeded so that we can - try that set first next time */ - have_working_flags = TRUE; - fbo_created = TRUE; - } - else - fbo_created = FALSE; - } - - if (fbo_created) - { - CoglOffscreen *ret; - CoglFramebuffer *fb = COGL_FRAMEBUFFER (offscreen); - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - _cogl_framebuffer_init (fb, - ctx, - COGL_FRAMEBUFFER_TYPE_OFFSCREEN, - cogl_texture_get_format (texhandle), - data.level_width, - data.level_height); - - /* take a reference on the texture */ - cogl_handle_ref (offscreen->texture); - - ret = _cogl_offscreen_object_new (offscreen); - _cogl_texture_associate_framebuffer (texhandle, COGL_FRAMEBUFFER (ret)); - - fb->allocated = TRUE; - - return ret; - } - else - { - g_free (offscreen); - /* XXX: This API should probably have been defined to take a GError */ - g_warning ("%s: Failed to create an OpenGL framebuffer", G_STRLOC); - - return COGL_INVALID_HANDLE; - } -} - -CoglHandle -cogl_offscreen_new_to_texture (CoglHandle texhandle) -{ - return _cogl_offscreen_new_to_texture_full (texhandle, 0, 0); -} - -static void -_cogl_offscreen_free (CoglOffscreen *offscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen); -#ifndef HAVE_COGL_GLES2 - CoglContext *ctx = framebuffer->context; -#endif - GSList *l; - - /* Chain up to parent */ - _cogl_framebuffer_free (framebuffer); - - for (l = offscreen->renderbuffers; l; l = l->next) - { - GLuint renderbuffer = GPOINTER_TO_UINT (l->data); - GE (glDeleteRenderbuffers (1, &renderbuffer)); - } - g_slist_free (offscreen->renderbuffers); - - GE (glDeleteFramebuffers (1, &offscreen->fbo_handle)); - - if (offscreen->texture != COGL_INVALID_HANDLE) - cogl_handle_unref (offscreen->texture); - - g_free (offscreen); -} - -/* XXX: While we still have backend in Clutter we need a dummy object - * to represent the CoglOnscreen framebuffer that the backend - * creates... */ -CoglOnscreen * -_cogl_onscreen_new (void) -{ - CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1); - - _COGL_GET_CONTEXT (ctx, NULL); - - _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen), - ctx, - COGL_FRAMEBUFFER_TYPE_ONSCREEN, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 0xdeadbeef, /* width */ - 0xdeadbeef); /* height */ - - COGL_FRAMEBUFFER (onscreen)->allocated = TRUE; - - /* XXX: Note we don't initialize onscreen->winsys in this case. */ - - return _cogl_onscreen_object_new (onscreen); -} - -CoglOnscreen * -cogl_onscreen_new (CoglContext *ctx, int width, int height) -{ - CoglOnscreen *onscreen; - - /* FIXME: We are assuming onscreen buffers will always be - premultiplied so we'll set the premult flag on the bitmap - format. This will usually be correct because the result of the - default blending operations for Cogl ends up with premultiplied - data in the framebuffer. However it is possible for the - framebuffer to be in whatever format depending on what - CoglPipeline is used to render to it. Eventually we may want to - add a way for an application to inform Cogl that the framebuffer - is not premultiplied in case it is being used for some special - purpose. */ - - onscreen = g_new0 (CoglOnscreen, 1); - _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen), - ctx, - COGL_FRAMEBUFFER_TYPE_ONSCREEN, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - width, /* width */ - height); /* height */ - - onscreen->swap_throttled = TRUE; - - return _cogl_onscreen_object_new (onscreen); -} - -gboolean -cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - - if (framebuffer->allocated) - return TRUE; - - /* XXX: with the current cogl_offscreen_new_to_texture() API the - * framebuffer is implicitly allocated before returning. */ - g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, - TRUE); - - if (!winsys->onscreen_init (onscreen, error)) - return FALSE; - - framebuffer->allocated = TRUE; - - return TRUE; -} - -static void -_cogl_onscreen_free (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - - winsys->onscreen_deinit (onscreen); - g_return_if_fail (onscreen->winsys == NULL); - - /* Chain up to parent */ - _cogl_framebuffer_free (framebuffer); - - g_free (onscreen); -} - -void -_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, - int width, int height) -{ - CoglContext *ctx = framebuffer->context; - - if (framebuffer->width == width && framebuffer->height == height) - return; - - framebuffer->width = width; - framebuffer->height = height; - - /* We'll need to recalculate the GL viewport state derived - * from the Cogl viewport */ - ctx->dirty_gl_viewport = 1; -} - -static CoglFramebufferStackEntry * -create_stack_entry (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebufferStackEntry *entry = g_slice_new (CoglFramebufferStackEntry); - - entry->draw_buffer = draw_buffer; - entry->read_buffer = read_buffer; - - return entry; -} - -GSList * -_cogl_create_framebuffer_stack (void) -{ - CoglFramebufferStackEntry *entry; - GSList *stack = NULL; - - entry = create_stack_entry (COGL_INVALID_HANDLE, COGL_INVALID_HANDLE); - - return g_slist_prepend (stack, entry); -} - -void -_cogl_free_framebuffer_stack (GSList *stack) -{ - GSList *l; - - for (l = stack; l != NULL; l = l->next) - { - CoglFramebufferStackEntry *entry = l->data; - - if (entry->draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) - _cogl_offscreen_free (COGL_OFFSCREEN (entry->draw_buffer)); - else - _cogl_onscreen_free (COGL_ONSCREEN (entry->draw_buffer)); - - if (entry->read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) - _cogl_offscreen_free (COGL_OFFSCREEN (entry->read_buffer)); - else - _cogl_onscreen_free (COGL_ONSCREEN (entry->read_buffer)); - - g_slice_free (CoglFramebufferStackEntry, entry); - } - g_slist_free (stack); -} - -/* Set the current framebuffer without checking if it's already the - * current framebuffer. This is used by cogl_pop_framebuffer while - * the top of the stack is currently not up to date. */ -static void -_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebufferStackEntry *entry; - GSList *l; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (ctx != NULL); - g_return_if_fail (draw_buffer && read_buffer ? - draw_buffer->context == read_buffer->context : TRUE); - - entry = ctx->framebuffer_stack->data; - - ctx->dirty_bound_framebuffer = 1; - ctx->dirty_gl_viewport = 1; - - if (draw_buffer) - cogl_object_ref (draw_buffer); - if (entry->draw_buffer) - cogl_object_unref (entry->draw_buffer); - - if (read_buffer) - cogl_object_ref (read_buffer); - if (entry->read_buffer) - cogl_object_unref (entry->read_buffer); - - entry->draw_buffer = draw_buffer; - entry->read_buffer = read_buffer; - - /* We've effectively just switched the current modelview and - * projection matrix stacks and clip state so we need to dirty - * them to ensure they get flushed for the next batch of geometry - * we flush */ - if (draw_buffer) - { - _cogl_matrix_stack_dirty (draw_buffer->modelview_stack); - _cogl_matrix_stack_dirty (draw_buffer->projection_stack); - } - - _cogl_clip_stack_dirty (); - - /* XXX: - * To support the deprecated cogl_set_draw_buffer API we keep track - * of the last onscreen framebuffer that was pushed so that it can - * be restored if the COGL_WINDOW_BUFFER enum is used. */ - ctx->window_buffer = NULL; - for (l = ctx->framebuffer_stack; l; l = l->next) - { - entry = l->data; - if (entry->draw_buffer && - entry->draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - ctx->window_buffer = entry->draw_buffer; - } -} - -static void -_cogl_set_framebuffers (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebuffer *current_draw_buffer; - CoglFramebuffer *current_read_buffer; - - g_return_if_fail (_cogl_is_framebuffer (draw_buffer)); - g_return_if_fail (_cogl_is_framebuffer (read_buffer)); - - current_draw_buffer = cogl_get_draw_framebuffer (); - current_read_buffer = _cogl_get_read_framebuffer (); - - if (current_draw_buffer != draw_buffer || - current_read_buffer != read_buffer) - { - /* XXX: eventually we want to remove this implicit journal flush - * so we can log into the journal beyond framebuffer changes to - * support batching scenes that depend on the results of - * mid-scene renders to textures. Current will be NULL when the - * framebuffer stack is first created so we need to guard - * against that here */ - if (current_draw_buffer) - _cogl_framebuffer_flush_journal (current_draw_buffer); - if (current_read_buffer) - _cogl_framebuffer_flush_journal (current_read_buffer); - _cogl_set_framebuffers_real (draw_buffer, read_buffer); - } -} - -void -cogl_set_framebuffer (CoglFramebuffer *framebuffer) -{ - _cogl_set_framebuffers (framebuffer, framebuffer); -} - -/* XXX: deprecated API */ -void -cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (target == COGL_WINDOW_BUFFER) - handle = ctx->window_buffer; - - /* This is deprecated public API. The public API doesn't currently - really expose the concept of separate draw and read buffers so - for the time being this actually just sets both buffers */ - cogl_set_framebuffer (handle); -} - -CoglFramebuffer * -cogl_get_draw_framebuffer (void) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_assert (ctx->framebuffer_stack); - - entry = ctx->framebuffer_stack->data; - - return entry->draw_buffer; -} - -CoglFramebuffer * -_cogl_get_read_framebuffer (void) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_assert (ctx->framebuffer_stack); - - entry = ctx->framebuffer_stack->data; - - return entry->read_buffer; -} - -void -_cogl_push_framebuffers (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglContext *ctx; - CoglFramebuffer *old_draw_buffer, *old_read_buffer; - - g_return_if_fail (_cogl_is_framebuffer (draw_buffer)); - g_return_if_fail (_cogl_is_framebuffer (read_buffer)); - - ctx = draw_buffer->context; - g_return_if_fail (ctx != NULL); - g_return_if_fail (draw_buffer->context == read_buffer->context); - - g_return_if_fail (ctx->framebuffer_stack != NULL); - - /* Copy the top of the stack so that when we call cogl_set_framebuffer - it will still know what the old framebuffer was */ - old_draw_buffer = cogl_get_draw_framebuffer (); - if (old_draw_buffer) - cogl_object_ref (old_draw_buffer); - old_read_buffer = _cogl_get_read_framebuffer (); - if (old_read_buffer) - cogl_object_ref (old_read_buffer); - ctx->framebuffer_stack = - g_slist_prepend (ctx->framebuffer_stack, - create_stack_entry (old_draw_buffer, - old_read_buffer)); - - _cogl_set_framebuffers (draw_buffer, read_buffer); -} - -void -cogl_push_framebuffer (CoglFramebuffer *buffer) -{ - _cogl_push_framebuffers (buffer, buffer); -} - -/* XXX: deprecated API */ -void -cogl_push_draw_buffer (void) -{ - cogl_push_framebuffer (cogl_get_draw_framebuffer ()); -} - -void -cogl_pop_framebuffer (void) -{ - CoglFramebufferStackEntry *to_pop; - CoglFramebufferStackEntry *to_restore; - gboolean changed = FALSE; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_assert (ctx->framebuffer_stack != NULL); - g_assert (ctx->framebuffer_stack->next != NULL); - - to_pop = ctx->framebuffer_stack->data; - to_restore = ctx->framebuffer_stack->next->data; - - if (to_pop->draw_buffer != to_restore->draw_buffer || - to_pop->read_buffer != to_restore->read_buffer) - { - /* XXX: eventually we want to remove this implicit journal flush - * so we can log into the journal beyond framebuffer changes to - * support batching scenes that depend on the results of - * mid-scene renders to textures. */ - _cogl_framebuffer_flush_journal (to_pop->draw_buffer); - _cogl_framebuffer_flush_journal (to_pop->read_buffer); - - changed = TRUE; - } - - cogl_object_unref (to_pop->draw_buffer); - cogl_object_unref (to_pop->read_buffer); - g_slice_free (CoglFramebufferStackEntry, to_pop); - - ctx->framebuffer_stack = - g_slist_delete_link (ctx->framebuffer_stack, - ctx->framebuffer_stack); - - /* If the framebuffer has changed as a result of popping the top - * then re-assert the current buffer so as to dirty state as - * necessary. */ - if (changed) - _cogl_set_framebuffers_real (to_restore->draw_buffer, - to_restore->read_buffer); -} - -/* XXX: deprecated API */ -void -cogl_pop_draw_buffer (void) -{ - cogl_pop_framebuffer (); -} - -static void -bind_gl_framebuffer (CoglContext *ctx, - GLenum target, - CoglFramebuffer *framebuffer) -{ - if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) - GE (glBindFramebuffer (target, - COGL_OFFSCREEN (framebuffer)->fbo_handle)); - else - { -#ifdef COGL_HAS_FULL_WINSYS - const CoglWinsysVtable *winsys = - _cogl_framebuffer_get_winsys (framebuffer); - winsys->onscreen_bind (COGL_ONSCREEN (framebuffer)); -#endif - GE (glBindFramebuffer (target, 0)); - } -} - -void -_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferFlushFlags flags) -{ - CoglContext *ctx = draw_buffer->context; - - if (ctx->dirty_bound_framebuffer) - { - if (draw_buffer == read_buffer) - bind_gl_framebuffer (ctx, GL_FRAMEBUFFER, draw_buffer); - else - { - /* NB: Currently we only take advantage of binding separate - * read/write buffers for offscreen framebuffer blit - * purposes. */ - g_return_if_fail (cogl_features_available (COGL_FEATURE_OFFSCREEN_BLIT)); - g_return_if_fail (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN); - g_return_if_fail (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN); - - bind_gl_framebuffer (ctx, GL_DRAW_FRAMEBUFFER, draw_buffer); - bind_gl_framebuffer (ctx, GL_READ_FRAMEBUFFER, read_buffer); - } - } - - ctx->dirty_bound_framebuffer = FALSE; - - if (flags & COGL_FRAMEBUFFER_FLUSH_BIND_ONLY) - return; - - if (ctx->dirty_gl_viewport) - { - float gl_viewport_y; - - /* Convert the Cogl viewport y offset to an OpenGL viewport y offset - * NB: OpenGL defines its window and viewport origins to be bottom - * left, while Cogl defines them to be top left. - * NB: We render upside down to offscreen framebuffers so we don't - * need to convert the y offset in this case. */ - if (cogl_is_offscreen (draw_buffer)) - gl_viewport_y = draw_buffer->viewport_y; - else - gl_viewport_y = draw_buffer->height - - (draw_buffer->viewport_y + draw_buffer->viewport_height); - - COGL_NOTE (OPENGL, "Calling glViewport(%f, %f, %f, %f)", - draw_buffer->viewport_x, - gl_viewport_y, - draw_buffer->viewport_width, - draw_buffer->viewport_height); - - GE (glViewport (draw_buffer->viewport_x, - gl_viewport_y, - draw_buffer->viewport_width, - draw_buffer->viewport_height)); - ctx->dirty_gl_viewport = FALSE; - } - - /* since we might have changed the framebuffer, we should initialize - * the bits; this is a no-op if they have already been initialized - */ - _cogl_framebuffer_init_bits (draw_buffer); - _cogl_framebuffer_init_bits (read_buffer); - - /* XXX: Flushing clip state may trash the modelview and projection - * matrices so we must do it before flushing the matrices... - */ - if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE)) - _cogl_clip_state_flush (&draw_buffer->clip_state); - - if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW)) - _cogl_matrix_stack_flush_to_gl (draw_buffer->modelview_stack, - COGL_MATRIX_MODELVIEW); - - _cogl_matrix_stack_flush_to_gl (draw_buffer->projection_stack, - COGL_MATRIX_PROJECTION); -} - -int -_cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer) -{ - _cogl_framebuffer_init_bits (framebuffer); - - return framebuffer->red_bits; -} - -int -_cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer) -{ - _cogl_framebuffer_init_bits (framebuffer); - - return framebuffer->green_bits; -} - -int -_cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer) -{ - _cogl_framebuffer_init_bits (framebuffer); - - return framebuffer->blue_bits; -} - -int -_cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer) -{ - _cogl_framebuffer_init_bits (framebuffer); - - return framebuffer->alpha_bits; -} - -gboolean -_cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglPixelFormat format, - guint8 *pixel) -{ - gboolean found_intersection; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FAST_READ_PIXEL))) - return FALSE; - - if (source != COGL_READ_PIXELS_COLOR_BUFFER) - return FALSE; - - if (format != COGL_PIXEL_FORMAT_RGBA_8888_PRE && - format != COGL_PIXEL_FORMAT_RGBA_8888) - return FALSE; - - if (!_cogl_journal_try_read_pixel (framebuffer->journal, - x, y, format, pixel, - &found_intersection)) - return FALSE; - - /* If we can't determine the color from the primitives in the - * journal then see if we can use the last recorded clear color - */ - - /* If _cogl_journal_try_read_pixel() failed even though there was an - * intersection of the given point with a primitive in the journal - * then we can't fallback to the framebuffer's last clear color... - * */ - if (found_intersection) - return TRUE; - - /* If the framebuffer has been rendered too since it was last - * cleared then we can't return the last known clear color. */ - if (framebuffer->clear_clip_dirty) - return FALSE; - - if (x >= framebuffer->clear_clip_x0 && - x < framebuffer->clear_clip_x1 && - y >= framebuffer->clear_clip_y0 && - y < framebuffer->clear_clip_y1) - { - - /* we currently only care about cases where the premultiplied or - * unpremultipled colors are equivalent... */ - if (framebuffer->clear_color_alpha != 1.0) - return FALSE; - - pixel[0] = framebuffer->clear_color_red * 255.0; - pixel[1] = framebuffer->clear_color_green * 255.0; - pixel[2] = framebuffer->clear_color_blue * 255.0; - pixel[3] = framebuffer->clear_color_alpha * 255.0; - - return TRUE; - } - - return FALSE; -} - -void -_cogl_blit_framebuffer (unsigned int src_x, - unsigned int src_y, - unsigned int dst_x, - unsigned int dst_y, - unsigned int width, - unsigned int height) -{ - CoglFramebuffer *draw_buffer; - CoglFramebuffer *read_buffer; - CoglContext *ctx; - - /* FIXME: this function should take explit src and dst framebuffer - * arguments. */ - draw_buffer = cogl_get_draw_framebuffer (); - read_buffer = _cogl_get_read_framebuffer (); - ctx = draw_buffer->context; - - g_return_if_fail (cogl_features_available (COGL_FEATURE_OFFSCREEN_BLIT)); - /* We can only support blitting between offscreen buffers because - otherwise we would need to mirror the image and GLES2.0 doesn't - support this */ - g_return_if_fail (cogl_is_offscreen (draw_buffer)); - g_return_if_fail (cogl_is_offscreen (read_buffer)); - /* The buffers must be the same format */ - g_return_if_fail (draw_buffer->format == read_buffer->format); - - /* Make sure the current framebuffers are bound. We explicitly avoid - flushing the clip state so we can bind our own empty state */ - _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), - _cogl_get_read_framebuffer (), - COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE); - - /* Flush any empty clip stack because glBlitFramebuffer is affected - by the scissor and we want to hide this feature for the Cogl API - because it's not obvious to an app how the clip state will affect - the scissor */ - _cogl_clip_stack_flush (NULL); - - glBlitFramebuffer (src_x, src_y, - src_x + width, src_y + height, - dst_x, dst_y, - dst_x + width, dst_y + height, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); -} - -void -cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer) -{ - /* FIXME: we shouldn't need to flush *all* journals here! */ - cogl_flush (); - if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - { - const CoglWinsysVtable *winsys = - _cogl_framebuffer_get_winsys (framebuffer); - winsys->onscreen_swap_buffers (COGL_ONSCREEN (framebuffer)); - } -} - -void -cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer, - int *rectangles, - int n_rectangles) -{ - /* FIXME: we shouldn't need to flush *all* journals here! */ - cogl_flush (); - if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - { - const CoglWinsysVtable *winsys = - _cogl_framebuffer_get_winsys (framebuffer); - winsys->onscreen_swap_region (COGL_ONSCREEN (framebuffer), - rectangles, - n_rectangles); - } -} - -#ifdef COGL_HAS_X11_SUPPORT -void -cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen, - guint32 xid, - CoglOnscreenX11MaskCallback update, - void *user_data) -{ - /* We don't wan't applications to get away with being lazy here and not - * passing an update callback... */ - g_return_if_fail (update); - - onscreen->foreign_xid = xid; - onscreen->foreign_update_mask_callback = update; - onscreen->foreign_update_mask_data = user_data; -} - -guint32 -cogl_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - - return winsys->onscreen_x11_get_window_xid (onscreen); -} - -guint32 -cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - XVisualInfo *visinfo = winsys->xlib_get_visual_info (); - guint32 id = (guint32)visinfo->visualid; - - XFree (visinfo); - return id; -} -#endif /* COGL_HAS_X11_SUPPORT */ - -unsigned int -cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer, - CoglSwapBuffersNotify callback, - void *user_data) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - - /* Should this just be cogl_onscreen API instead? */ - g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0); - - return winsys->onscreen_add_swap_buffers_callback (onscreen, - callback, - user_data); -} - -void -cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer, - unsigned int id) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - - winsys->onscreen_remove_swap_buffers_callback (onscreen, id); -} - -void -cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, - gboolean throttled) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - onscreen->swap_throttled = throttled; - if (framebuffer->allocated) - { - const CoglWinsysVtable *winsys = - _cogl_framebuffer_get_winsys (framebuffer); - winsys->onscreen_update_swap_throttled (onscreen); - } -} - -void -cogl_onscreen_show (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - const CoglWinsysVtable *winsys; - - if (!framebuffer->allocated) - { - if (!cogl_framebuffer_allocate (framebuffer, NULL)) - return; - } - - winsys = _cogl_framebuffer_get_winsys (framebuffer); - if (winsys->onscreen_set_visibility) - winsys->onscreen_set_visibility (onscreen, TRUE); -} - -void -cogl_onscreen_hide (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - if (framebuffer->allocated) - { - const CoglWinsysVtable *winsys = - _cogl_framebuffer_get_winsys (framebuffer); - if (winsys->onscreen_set_visibility) - winsys->onscreen_set_visibility (onscreen, FALSE); - } -} diff --git a/clutter/cogl/cogl/cogl-framebuffer.h b/clutter/cogl/cogl/cogl-framebuffer.h deleted file mode 100644 index b685031..0000000 --- a/clutter/cogl/cogl/cogl-framebuffer.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_FRAMEBUFFER_H -#define __COGL_FRAMEBUFFER_H - -#include - - -G_BEGIN_DECLS - -#ifdef COGL_ENABLE_EXPERIMENTAL_API -#define cogl_onscreen_new cogl_onscreen_new_EXP - -#define COGL_FRAMEBUFFER(X) ((CoglFramebuffer *)(X)) - -#define cogl_framebuffer_allocate cogl_framebuffer_allocate_EXP -gboolean -cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - GError **error); - -#define cogl_framebuffer_get_width cogl_framebuffer_get_width_EXP -int -cogl_framebuffer_get_width (CoglFramebuffer *framebuffer); - -#define cogl_framebuffer_get_height cogl_framebuffer_get_height_EXP -int -cogl_framebuffer_get_height (CoglFramebuffer *framebuffer); - -#define cogl_framebuffer_swap_buffers cogl_framebuffer_swap_buffers_EXP -void -cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer); - -#define cogl_framebuffer_swap_region cogl_framebuffer_swap_region_EXP -void -cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer, - int *rectangles, - int n_rectangles); - - -typedef void (*CoglSwapBuffersNotify) (CoglFramebuffer *framebuffer, - void *user_data); - -#define cogl_framebuffer_add_swap_buffers_callback \ - cogl_framebuffer_add_swap_buffers_callback_EXP -unsigned int -cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer, - CoglSwapBuffersNotify callback, - void *user_data); - -#define cogl_framebuffer_remove_swap_buffers_callback \ - cogl_framebuffer_remove_swap_buffers_callback_EXP -void -cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer, - unsigned int id); - - -typedef struct _CoglOnscreen CoglOnscreen; -#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X)) - -CoglOnscreen * -cogl_onscreen_new (CoglContext *context, int width, int height); - -#ifdef COGL_HAS_X11 -typedef void (*CoglOnscreenX11MaskCallback) (CoglOnscreen *onscreen, - guint32 event_mask, - void *user_data); - -/** - * cogl_onscreen_x11_set_foreign_window_xid: - * @onscreen: The unallocated framebuffer to associated with an X - * window. - * @xid: The XID of an existing X window - * @update: A callback that notifies of updates to what Cogl requires - * to be in the core X protocol event mask. - * - * Ideally we would recommend that you let Cogl be responsible for - * creating any X window required to back an onscreen framebuffer but - * if you really need to target a window created manually this - * function can be called before @onscreen has been allocated to set a - * foreign XID for your existing X window. - * - * Since Cogl needs, for example, to track changes to the size of an X - * window it requires that certain events be selected for via the core - * X protocol. This requirement may also be changed asynchronously so - * you must pass in an @update callback to inform you of Cogl's - * required event mask. - * - * For example if you are using Xlib you could use this API roughly - * as follows: - * [{ - * static void - * my_update_cogl_x11_event_mask (CoglOnscreen *onscreen, - * guint32 event_mask, - * void *user_data) - * { - * XSetWindowAttributes attrs; - * MyData *data = user_data; - * attrs.event_mask = event_mask | data->my_event_mask; - * XChangeWindowAttributes (data->xdpy, - * data->xwin, - * CWEventMask, - * &attrs); - * } - * - * { - * *snip* - * cogl_onscreen_x11_set_foreign_window_xid (onscreen, - * data->xwin, - * my_update_cogl_x11_event_mask, - * data); - * *snip* - * } - * }] - * - * Since: 2.0 - * Stability: Unstable - */ -#define cogl_onscreen_x11_set_foreign_window_xid \ - cogl_onscreen_x11_set_foreign_window_xid_EXP -void -cogl_onscreen_x11_set_foreign_window_xid (CoglOnscreen *onscreen, - guint32 xid, - CoglOnscreenX11MaskCallback update, - void *user_data); - -#define cogl_onscreen_x11_get_window_xid cogl_onscreen_x11_get_window_xid_EXP -guint32 -cogl_onscreen_x11_get_window_xid (CoglOnscreen *onscreen); - -#define cogl_onscreen_x11_get_visual_xid cogl_onscreen_x11_get_visual_xid_EXP -guint32 -cogl_onscreen_x11_get_visual_xid (CoglOnscreen *onscreen); -#endif /* COGL_HAS_X11 */ - -#define cogl_onscreen_set_swap_throttled cogl_onscreen_set_swap_throttled_EXP -void -cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, - gboolean throttled); - -/** - * cogl_onscreen_show: - * @onscreen: The onscreen framebuffer to make visible - * - * This requests to make @onscreen visible to the user. - * - * Actually the precise semantics of this function depend on the - * window system currently in use, and if you don't have a - * multi-windowining system this function may in-fact do nothing. - * - * This function will implicitly allocate the given @onscreen - * framebuffer before showing it if it hasn't already been allocated. - * - * Since Cogl doesn't explicitly track the visibility status of - * onscreen framebuffers it wont try to avoid redundant window system - * requests e.g. to show an already visible window. This also means - * that it's acceptable to alternatively use native APIs to show and - * hide windows without confusing Cogl. - * - * Since: 2.0 - * Stability: Unstable - */ -#define cogl_onscreen_show cogl_onscreen_show_EXP -void -cogl_onscreen_show (CoglOnscreen *onscreen); - -/** - * cogl_onscreen_hide: - * @onscreen: The onscreen framebuffer to make invisible - * - * This requests to make @onscreen invisible to the user. - * - * Actually the precise semantics of this function depend on the - * window system currently in use, and if you don't have a - * multi-windowining system this function may in-fact do nothing. - * - * This function does not implicitly allocate the given @onscreen - * framebuffer before hiding it. - * - * Since Cogl doesn't explicitly track the visibility status of - * onscreen framebuffers it wont try to avoid redundant window system - * requests e.g. to show an already visible window. This also means - * that it's acceptable to alternatively use native APIs to show and - * hide windows without confusing Cogl. - * - * Since: 2.0 - * Stability: Unstable - */ -#define cogl_onscreen_hide cogl_onscreen_hide_EXP -void -cogl_onscreen_hide (CoglOnscreen *onscreen); - -#define cogl_get_draw_framebuffer cogl_get_draw_framebuffer_EXP -CoglFramebuffer * -cogl_get_draw_framebuffer (void); - -#endif /* COGL_ENABLE_EXPERIMENTAL_API */ - -G_END_DECLS - -#endif /* __COGL_FRAMEBUFFER_H */ - diff --git a/clutter/cogl/cogl/cogl-gtype-private.h b/clutter/cogl/cogl/cogl-gtype-private.h deleted file mode 100644 index 1d12330..0000000 --- a/clutter/cogl/cogl/cogl-gtype-private.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -#include -#include - -#ifndef __COGL_GTYPE_PRIVATE_H__ -#define __COGL_GTYPE_PRIVATE_H__ - -#define COGL_GTYPE_DEFINE_BOXED(Name, underscore_name, copy_func, free_func) \ -GType \ -cogl_gtype_ ## underscore_name ## _get_type (void) \ -{ \ - static volatile gsize type_volatile = 0; \ - if (g_once_init_enter (&type_volatile)) \ - { \ - GType type = \ - g_boxed_type_register_static (g_intern_static_string ("Cogl" Name), \ - (GBoxedCopyFunc)copy_func, \ - (GBoxedFreeFunc)free_func); \ - g_once_init_leave (&type_volatile, type); \ - } \ - return type_volatile; \ -} - -#endif /* __COGL_GTYPE_PRIVATE_H__ */ - diff --git a/clutter/cogl/cogl/cogl-handle.h b/clutter/cogl/cogl/cogl-handle.h deleted file mode 100644 index f69e97e..0000000 --- a/clutter/cogl/cogl/cogl-handle.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -/* This file is just kept for compatability while we eradicate - * CoglHandle - */ - -#ifndef __COGL_HANDLE_H -#define __COGL_HANDLE_H - -#include "cogl-object-private.h" - -#endif /* __COGL_HANDLE_H */ - diff --git a/clutter/cogl/cogl/cogl-index-array-private.h b/clutter/cogl/cogl/cogl-index-array-private.h deleted file mode 100644 index d5c825a..0000000 --- a/clutter/cogl/cogl/cogl-index-array-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_INDEX_ARRAY_PRIVATE_H -#define __COGL_INDEX_ARRAY_PRIVATE_H - -#include "cogl-buffer-private.h" - -struct _CoglIndexArray -{ - CoglBuffer _parent; -}; - -#endif /* __COGL_INDEX_ARRAY_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-index-array.c b/clutter/cogl/cogl/cogl-index-array.c deleted file mode 100644 index 2a85151..0000000 --- a/clutter/cogl/cogl/cogl-index-array.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-object-private.h" -#include "cogl-indices.h" -#include "cogl-indices-private.h" - -static void _cogl_index_array_free (CoglIndexArray *indices); - -COGL_BUFFER_DEFINE (IndexArray, index_array); - -/* XXX: Unlike the wiki design this just takes a size. A single - * indices buffer should be able to contain multiple ranges of indices - * which the wiki design doesn't currently consider. */ -CoglIndexArray * -cogl_index_array_new (gsize bytes) -{ - CoglIndexArray *indices = g_slice_new (CoglIndexArray); - gboolean use_malloc; - - if (!cogl_features_available (COGL_FEATURE_VBOS)) - use_malloc = TRUE; - else - use_malloc = FALSE; - - /* parent's constructor */ - _cogl_buffer_initialize (COGL_BUFFER (indices), - bytes, - use_malloc, - COGL_BUFFER_BIND_TARGET_INDEX_ARRAY, - COGL_BUFFER_USAGE_HINT_INDEX_ARRAY, - COGL_BUFFER_UPDATE_HINT_STATIC); - - return _cogl_index_array_object_new (indices); -} - -static void -_cogl_index_array_free (CoglIndexArray *indices) -{ - /* parent's destructor */ - _cogl_buffer_fini (COGL_BUFFER (indices)); - - g_slice_free (CoglIndexArray, indices); -} - -gboolean -cogl_index_array_allocate (CoglIndexArray *indices, - GError *error) -{ - /* TODO */ - return TRUE; -} - -/* XXX: do we want a convenience function like this as an alternative - * to using cogl_buffer_set_data? The advantage of this is that we can - * track meta data such as the indices type and max_index_value for a - * range as part of the indices array. If we just leave people to use - * cogl_buffer_set_data then we either need a way to specify the type - * and max index value at draw time or we'll want a separate way to - * declare the type and max value for a range after uploading the - * data. - * - * XXX: I think in the end it'll be that CoglIndices are to - * CoglIndexArrays as CoglAttributes are to CoglVertices. I.e - * a CoglIndexArray is a lite subclass of CoglBuffer that simply - * implies that the buffer will later be bound as indices but doesn't - * track more detailed meta data. CoglIndices build on a - * CoglIndexArray and define the type and max_index_value for some - * sub-range of a CoglIndexArray. - * - * XXX: The double plurel form that "Indices" "Array" implies could be - * a bit confusing. Also to be a bit more consistent with - * CoglVertexArray vs CoglAttribute it might be best to rename so - * we have CoglIndexArray vs CoglIndices? maybe even - * CoglIndexRange :-/ ? - * - * CoglBuffer - * CoglVertexArray (buffer sub-class) - * CoglPrimitive (defines meta data for sub-region of array) - * CoglPixelArray (buffer sub-class) - * CoglIndexArray (buffer sub-class) - * CoglIndices (defines meta data for sub-region of array) - * - */ -#if 0 -void -cogl_index_array_set_data (CoglIndexArray *indices, - CoglIndicesType type, - int max_index_value, - gsize write_offset, - void *user_indices, - int n_indices) -{ - GList *l; - - for (l = indices->ranges; l; l = l->next) - { - - } - cogl_buffer_set -} -#endif - diff --git a/clutter/cogl/cogl/cogl-index-array.h b/clutter/cogl/cogl/cogl-index-array.h deleted file mode 100644 index 498449f..0000000 --- a/clutter/cogl/cogl/cogl-index-array.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_INDEX_ARRAY_H__ -#define __COGL_INDEX_ARRAY_H__ - -G_BEGIN_DECLS - -/** - * SECTION:cogl-vertex-indices - * @short_description: Functions for creating and manipulating vertex - * indices. - * - * FIXME - */ - -typedef struct _CoglIndexArray CoglIndexArray; - -/** - * cogl_index_array_new: - * @bytes: The number of bytes to allocate for vertex attribute data. - * - * Declares a new #CoglIndexArray of @size bytes to contain vertex - * indices. Once declared, data can be set using - * cogl_buffer_set_data() or by mapping it into the application's - * address space using cogl_buffer_map(). - * - * Since: 1.4 - * Stability: Unstable - */ -CoglIndexArray * -cogl_index_array_new (gsize bytes); - -/** - * cogl_is_indices_array: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglIndexArray. - * - * Returns: %TRUE if the handle references a #CoglIndexArray, - * %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_is_indices_array (void *object); - -G_END_DECLS - -#endif /* __COGL_INDEX_ARRAY_H__ */ - diff --git a/clutter/cogl/cogl/cogl-indices-private.h b/clutter/cogl/cogl/cogl-indices-private.h deleted file mode 100644 index e505212..0000000 --- a/clutter/cogl/cogl/cogl-indices-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_INDICES_PRIVATE_H -#define __COGL_INDICES_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-index-array-private.h" -#include "cogl-types.h" - -struct _CoglIndices -{ - CoglObject _parent; - - CoglIndexArray *array; - size_t offset; - - CoglIndicesType type; - - int immutable_ref; -}; - -CoglIndices * -_cogl_indices_immutable_ref (CoglIndices *indices); - -void -_cogl_indices_immutable_unref (CoglIndices *indices); - -#endif /* __COGL_INDICES_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-indices.c b/clutter/cogl/cogl/cogl-indices.c deleted file mode 100644 index 8e8e776..0000000 --- a/clutter/cogl/cogl/cogl-indices.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-object-private.h" -#include "cogl-context-private.h" -#include "cogl-indices.h" -#include "cogl-indices-private.h" -#include "cogl-index-array.h" - -#include - -static void _cogl_indices_free (CoglIndices *indices); - -COGL_OBJECT_DEFINE (Indices, indices); - -static size_t -sizeof_indices_type (CoglIndicesType type) -{ - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return 4; - } - g_return_val_if_reached (0); -} - -CoglIndices * -cogl_indices_new_for_array (CoglIndicesType type, - CoglIndexArray *array, - gsize offset) -{ - CoglIndices *indices = g_slice_new (CoglIndices); - - indices->array = cogl_object_ref (array); - indices->offset = offset; - - indices->type = type; - - indices->immutable_ref = 0; - - return _cogl_indices_object_new (indices); -} - -CoglIndices * -cogl_indices_new (CoglIndicesType type, - const void *indices_data, - int n_indices) -{ - size_t array_bytes = sizeof_indices_type (type) * n_indices; - CoglIndexArray *array = cogl_index_array_new (array_bytes); - CoglBuffer *buffer = COGL_BUFFER (array); - CoglIndices *indices; - - cogl_buffer_set_data (buffer, - 0, - indices_data, - array_bytes); - - indices = cogl_indices_new_for_array (type, array, 0); - cogl_object_unref (array); - - return indices; -} - -CoglIndexArray * -cogl_indices_get_array (CoglIndices *indices) -{ - return indices->array; -} - -CoglIndicesType -cogl_indices_get_type (CoglIndices *indices) -{ - g_return_val_if_fail (cogl_is_indices (indices), - COGL_INDICES_TYPE_UNSIGNED_BYTE); - return indices->type; -} - -gsize -cogl_indices_get_offset (CoglIndices *indices) -{ - g_return_val_if_fail (cogl_is_indices (indices), 0); - - return indices->offset; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of indices has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_indices_set_offset (CoglIndices *indices, - gsize offset) -{ - g_return_if_fail (cogl_is_indices (indices)); - - if (G_UNLIKELY (indices->immutable_ref)) - warn_about_midscene_changes (); - - indices->offset = offset; -} - -static void -_cogl_indices_free (CoglIndices *indices) -{ - cogl_object_unref (indices->array); - g_slice_free (CoglIndices, indices); -} - -CoglIndices * -_cogl_indices_immutable_ref (CoglIndices *indices) -{ - g_return_val_if_fail (cogl_is_indices (indices), NULL); - - indices->immutable_ref++; - _cogl_buffer_immutable_ref (COGL_BUFFER (indices->array)); - return indices; -} - -void -_cogl_indices_immutable_unref (CoglIndices *indices) -{ - g_return_if_fail (cogl_is_indices (indices)); - g_return_if_fail (indices->immutable_ref > 0); - - indices->immutable_ref--; - _cogl_buffer_immutable_unref (COGL_BUFFER (indices->array)); -} - -CoglIndices * -cogl_get_rectangle_indices (int n_rectangles) -{ - int n_indices = n_rectangles * 6; - - _COGL_GET_CONTEXT (ctx, NULL); - - /* Check if the largest index required will fit in a byte array... */ - if (n_indices <= 256 / 4 * 6) - { - /* Generate the byte array if we haven't already */ - if (ctx->rectangle_byte_indices == NULL) - { - guint8 *byte_array = g_malloc (256 / 4 * 6 * sizeof (guint8)); - guint8 *p = byte_array; - int i, vert_num = 0; - - for (i = 0; i < 256 / 4; i++) - { - *(p++) = vert_num + 0; - *(p++) = vert_num + 1; - *(p++) = vert_num + 2; - *(p++) = vert_num + 0; - *(p++) = vert_num + 2; - *(p++) = vert_num + 3; - vert_num += 4; - } - - ctx->rectangle_byte_indices - = cogl_indices_new (COGL_INDICES_TYPE_UNSIGNED_BYTE, - byte_array, - 256 / 4 * 6); - - g_free (byte_array); - } - - return ctx->rectangle_byte_indices; - } - else - { - if (ctx->rectangle_short_indices_len < n_indices) - { - guint16 *short_array; - guint16 *p; - int i, vert_num = 0; - - if (ctx->rectangle_short_indices != NULL) - cogl_object_unref (ctx->rectangle_short_indices); - /* Pick a power of two >= MAX (512, n_indices) */ - if (ctx->rectangle_short_indices_len == 0) - ctx->rectangle_short_indices_len = 512; - while (ctx->rectangle_short_indices_len < n_indices) - ctx->rectangle_short_indices_len *= 2; - - /* Over-allocate to generate a whole number of quads */ - p = short_array = g_malloc ((ctx->rectangle_short_indices_len - + 5) / 6 * 6 - * sizeof (guint16)); - - /* Fill in the complete quads */ - for (i = 0; i < ctx->rectangle_short_indices_len; i += 6) - { - *(p++) = vert_num + 0; - *(p++) = vert_num + 1; - *(p++) = vert_num + 2; - *(p++) = vert_num + 0; - *(p++) = vert_num + 2; - *(p++) = vert_num + 3; - vert_num += 4; - } - - ctx->rectangle_short_indices - = cogl_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT, - short_array, - ctx->rectangle_short_indices_len); - - g_free (short_array); - } - - return ctx->rectangle_short_indices; - } -} - diff --git a/clutter/cogl/cogl/cogl-indices.h b/clutter/cogl/cogl/cogl-indices.h deleted file mode 100644 index ec5ae7c..0000000 --- a/clutter/cogl/cogl/cogl-indices.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_INDICES_H__ -#define __COGL_INDICES_H__ - -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-index-range - * @short_description: Fuctions for declaring a range of vertex indices - * stored in a #CoglIndexArray. - * - * FIXME - */ - -typedef struct _CoglIndices CoglIndices; - -CoglIndices * -cogl_indices_new (CoglIndicesType type, - const void *indices_data, - int n_indices); - -CoglIndices * -cogl_indices_new_for_array (CoglIndicesType type, - CoglIndexArray *array, - gsize offset); - -CoglIndexArray * -cogl_indices_get_array (CoglIndices *indices); - -CoglIndicesType -cogl_indices_get_type (CoglIndices *indices); - -gsize -cogl_indices_get_offset (CoglIndices *indices); - -void -cogl_indices_set_offset (CoglIndices *indices, - gsize offset); - -CoglIndices * -cogl_get_rectangle_indices (int n_rectangles); - -G_END_DECLS - -#endif /* __COGL_INDICES_H__ */ - diff --git a/clutter/cogl/cogl/cogl-internal.h b/clutter/cogl/cogl/cogl-internal.h deleted file mode 100644 index eba62bf..0000000 --- a/clutter/cogl/cogl/cogl-internal.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_INTERNAL_H -#define __COGL_INTERNAL_H - -#include "cogl.h" -#include "cogl-matrix-stack.h" -#include "cogl-bitmask.h" - -#ifdef COGL_HAS_XLIB_SUPPORT -#include -#endif - -typedef enum -{ - COGL_FRONT_WINDING_CLOCKWISE, - COGL_FRONT_WINDING_COUNTER_CLOCKWISE -} CoglFrontWinding; - -typedef enum { - COGL_BOXED_NONE, - COGL_BOXED_INT, - COGL_BOXED_FLOAT, - COGL_BOXED_MATRIX -} CoglBoxedType; - -typedef struct _CoglBoxedValue -{ - CoglBoxedType type; - int size, count; - gboolean transpose; - - union { - float float_value[4]; - int int_value[4]; - float matrix[16]; - float *float_array; - int *int_array; - void *array; - } v; -} CoglBoxedValue; - -#ifdef COGL_GL_DEBUG - -const char * -cogl_gl_error_to_string (GLenum error_code); - -#define GE(x) G_STMT_START { \ - GLenum __err; \ - (x); \ - while ((__err = glGetError ()) != GL_NO_ERROR) \ - { \ - g_warning ("%s: GL error (%d): %s\n", \ - G_STRLOC, \ - __err, \ - cogl_gl_error_to_string (__err)); \ - } } G_STMT_END - -#define GE_RET(ret, x) G_STMT_START { \ - GLenum __err; \ - ret = (x); \ - while ((__err = glGetError ()) != GL_NO_ERROR) \ - { \ - g_warning ("%s: GL error (%d): %s\n", \ - G_STRLOC, \ - __err, \ - cogl_gl_error_to_string (__err)); \ - } } G_STMT_END - -#else /* !COGL_GL_DEBUG */ - -#define GE(x) (x) -#define GE_RET(ret, x) (ret = (x)) - -#endif /* COGL_GL_DEBUG */ - -#define COGL_ENABLE_ALPHA_TEST (1<<1) -#define COGL_ENABLE_VERTEX_ARRAY (1<<2) -#define COGL_ENABLE_COLOR_ARRAY (1<<3) -#define COGL_ENABLE_BACKFACE_CULLING (1<<4) - -int -_cogl_get_format_bpp (CoglPixelFormat format); - -void -_cogl_enable (unsigned long flags); - -unsigned long -_cogl_get_enable (void); - -void -_cogl_flush_face_winding (void); - -void -_cogl_transform_point (const CoglMatrix *matrix_mv, - const CoglMatrix *matrix_p, - const float *viewport, - float *x, - float *y); - -#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ()) - -typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/ - COGL_DRIVER_ERROR_UNKNOWN_VERSION, - COGL_DRIVER_ERROR_INVALID_VERSION -} CoglDriverError; - -gboolean -_cogl_check_extension (const char *name, const char *ext); - -GQuark -_cogl_driver_error_quark (void); - -#endif /* __COGL_INTERNAL_H */ diff --git a/clutter/cogl/cogl/cogl-journal-private.h b/clutter/cogl/cogl/cogl-journal-private.h deleted file mode 100644 index 7212dca..0000000 --- a/clutter/cogl/cogl/cogl-journal-private.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_JOURNAL_PRIVATE_H -#define __COGL_JOURNAL_PRIVATE_H - -#include "cogl.h" -#include "cogl-handle.h" -#include "cogl-clip-stack.h" - -typedef struct _CoglJournal -{ - CoglObject _parent; - - GArray *entries; - GArray *vertices; - size_t needed_vbo_len; - - int fast_read_pixel_count; - -} CoglJournal; - -/* To improve batching of geometry when submitting vertices to OpenGL we - * log the texture rectangles we want to draw to a journal, so when we - * later flush the journal we aim to batch data, and gl draw calls. */ -typedef struct _CoglJournalEntry -{ - CoglPipeline *pipeline; - int n_layers; - CoglMatrix model_view; - CoglClipStack *clip_stack; - /* Offset into ctx->logged_vertices */ - size_t array_offset; - /* XXX: These entries are pretty big now considering the padding in - * CoglPipelineFlushOptions and CoglMatrix, so we might need to optimize this - * later. */ -} CoglJournalEntry; - -CoglJournal * -_cogl_journal_new (void); - -void -_cogl_journal_log_quad (CoglJournal *journal, - const float *position, - CoglPipeline *pipeline, - int n_layers, - CoglHandle layer0_override_texture, - const float *tex_coords, - unsigned int tex_coords_len); - -void -_cogl_journal_flush (CoglJournal *journal, - CoglFramebuffer *framebuffer); - -void -_cogl_journal_discard (CoglJournal *journal); - -gboolean -_cogl_journal_all_entries_within_bounds (CoglJournal *journal, - float clip_x0, - float clip_y0, - float clip_x1, - float clip_y1); - -gboolean -_cogl_journal_try_read_pixel (CoglJournal *journal, - int x, - int y, - CoglPixelFormat format, - guint8 *pixel, - gboolean *found_intersection); - -#endif /* __COGL_JOURNAL_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-journal.c b/clutter/cogl/cogl/cogl-journal.c deleted file mode 100644 index b0fbac7..0000000 --- a/clutter/cogl/cogl/cogl-journal.c +++ /dev/null @@ -1,1805 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-journal-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-vertex-buffer-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-profile.h" -#include "cogl-attribute-private.h" -#include "cogl-point-in-poly-private.h" - -#include -#include -#include - -/* XXX NB: - * The data logged in logged_vertices is formatted as follows: - * - * Per entry: - * 4 RGBA GLubytes for the color - * 2 floats for the top left position - * 2 * n_layers floats for the top left texture coordinates - * 2 floats for the bottom right position - * 2 * n_layers floats for the bottom right texture coordinates - */ -#define GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS(N_LAYERS) \ - (N_LAYERS * 2 + 2) - -/* XXX NB: - * Once in the vertex array, the journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 GLfloats per position (3 when doing software transforms) - * 4 RGBA GLubytes, - * 2 GLfloats per tex coord * n_layers - * - * Where n_layers corresponds to the number of pipeline layers enabled - * - * To avoid frequent changes in the stride of our vertex data we always pad - * n_layers to be >= 2 - * - * There will be four vertices per quad in the vertex array - * - * When we are transforming quads in software we need to also track the z - * coordinate of transformed vertices. - * - * So for a given number of layers this gets the stride in 32bit words: - */ -#define SW_TRANSFORM (!(COGL_DEBUG_ENABLED \ - (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) -#define POS_STRIDE (SW_TRANSFORM ? 3 : 2) /* number of 32bit words */ -#define N_POS_COMPONENTS POS_STRIDE -#define COLOR_STRIDE 1 /* number of 32bit words */ -#define TEX_STRIDE 2 /* number of 32bit words */ -#define MIN_LAYER_PADING 2 -#define GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS(N_LAYERS) \ - (POS_STRIDE + COLOR_STRIDE + \ - TEX_STRIDE * (N_LAYERS < MIN_LAYER_PADING ? MIN_LAYER_PADING : N_LAYERS)) - -/* If a batch is longer than this threshold then we'll assume it's not - worth doing software clipping and it's cheaper to program the GPU - to do the clip */ -#define COGL_JOURNAL_HARDWARE_CLIP_THRESHOLD 8 - -typedef struct _CoglJournalFlushState -{ - CoglJournal *journal; - - CoglVertexArray *vertex_array; - GArray *attributes; - int current_attribute; - - gsize stride; - size_t array_offset; - GLuint current_vertex; -#ifndef HAVE_COGL_GL - CoglIndices *indices; - gsize indices_type_size; -#endif - CoglMatrixStack *modelview_stack; - CoglMatrixStack *projection_stack; - - CoglPipeline *source; -} CoglJournalFlushState; - -typedef void (*CoglJournalBatchCallback) (CoglJournalEntry *start, - int n_entries, - void *data); -typedef gboolean (*CoglJournalBatchTest) (CoglJournalEntry *entry0, - CoglJournalEntry *entry1); - -static void _cogl_journal_free (CoglJournal *journal); - -COGL_OBJECT_DEFINE (Journal, journal); - -static void -_cogl_journal_free (CoglJournal *journal) -{ - if (journal->entries) - g_array_free (journal->entries, TRUE); - if (journal->vertices) - g_array_free (journal->vertices, TRUE); - g_slice_free (CoglJournal, journal); -} - -CoglJournal * -_cogl_journal_new (void) -{ - CoglJournal *journal = g_slice_new0 (CoglJournal); - - journal->entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry)); - journal->vertices = g_array_new (FALSE, FALSE, sizeof (float)); - - return _cogl_journal_object_new (journal); -} - -static void -_cogl_journal_dump_logged_quad (guint8 *data, int n_layers) -{ - gsize stride = GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (n_layers); - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_print ("n_layers = %d; rgba=0x%02X%02X%02X%02X\n", - n_layers, data[0], data[1], data[2], data[3]); - - data += 4; - - for (i = 0; i < 2; i++) - { - float *v = (float *)data + (i * stride); - int j; - - g_print ("v%d: x = %f, y = %f", i, v[0], v[1]); - - for (j = 0; j < n_layers; j++) - { - float *t = v + 2 + TEX_STRIDE * j; - g_print (", tx%d = %f, ty%d = %f", j, t[0], j, t[1]); - } - g_print ("\n"); - } -} - -static void -_cogl_journal_dump_quad_vertices (guint8 *data, int n_layers) -{ - gsize stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers); - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_print ("n_layers = %d; stride = %d; pos stride = %d; color stride = %d; " - "tex stride = %d; stride in bytes = %d\n", - n_layers, (int)stride, POS_STRIDE, COLOR_STRIDE, - TEX_STRIDE, (int)stride * 4); - - for (i = 0; i < 4; i++) - { - float *v = (float *)data + (i * stride); - guint8 *c = data + (POS_STRIDE * 4) + (i * stride * 4); - int j; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - g_print ("v%d: x = %f, y = %f, rgba=0x%02X%02X%02X%02X", - i, v[0], v[1], c[0], c[1], c[2], c[3]); - else - g_print ("v%d: x = %f, y = %f, z = %f, rgba=0x%02X%02X%02X%02X", - i, v[0], v[1], v[2], c[0], c[1], c[2], c[3]); - for (j = 0; j < n_layers; j++) - { - float *t = v + POS_STRIDE + COLOR_STRIDE + TEX_STRIDE * j; - g_print (", tx%d = %f, ty%d = %f", j, t[0], j, t[1]); - } - g_print ("\n"); - } -} - -static void -_cogl_journal_dump_quad_batch (guint8 *data, int n_layers, int n_quads) -{ - gsize byte_stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers) * 4; - int i; - - g_print ("_cogl_journal_dump_quad_batch: n_layers = %d, n_quads = %d\n", - n_layers, n_quads); - for (i = 0; i < n_quads; i++) - _cogl_journal_dump_quad_vertices (data + byte_stride * 2 * i, n_layers); -} - -static void -batch_and_call (CoglJournalEntry *entries, - int n_entries, - CoglJournalBatchTest can_batch_callback, - CoglJournalBatchCallback batch_callback, - void *data) -{ - int i; - int batch_len = 1; - CoglJournalEntry *batch_start = entries; - - if (n_entries < 1) - return; - - for (i = 1; i < n_entries; i++) - { - CoglJournalEntry *entry0 = &entries[i - 1]; - CoglJournalEntry *entry1 = entry0 + 1; - - if (can_batch_callback (entry0, entry1)) - { - batch_len++; - continue; - } - - batch_callback (batch_start, batch_len, data); - - batch_start = entry1; - batch_len = 1; - } - - /* The last batch... */ - batch_callback (batch_start, batch_len, data); -} - -static void -_cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglAttribute **attributes; - CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH | - COGL_DRAW_SKIP_LEGACY_STATE); - - COGL_STATIC_TIMER (time_flush_modelview_and_entries, - "flush: pipeline+entries", /* parent */ - "flush: modelview+entries", - "The time spent flushing modelview + entries", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_modelview_and_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: modelview batch len = %d\n", batch_len); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - { - _cogl_matrix_stack_set (state->modelview_stack, - &batch_start->model_view); - _cogl_matrix_stack_flush_to_gl (state->modelview_stack, - COGL_MATRIX_MODELVIEW); - } - - attributes = (CoglAttribute **)state->attributes->data; - cogl_push_source (state->source); - - if (!_cogl_pipeline_get_real_blend_enabled (state->source)) - draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE; - -#ifdef HAVE_COGL_GL - - /* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */ - _cogl_draw_attributes_array (GL_QUADS, - state->current_vertex, batch_len * 4, - attributes, - draw_flags); - -#else /* HAVE_COGL_GL */ - if (batch_len > 1) - { - _cogl_draw_indexed_attributes_array (COGL_VERTICES_MODE_TRIANGLES, - state->current_vertex * 6 / 4, - batch_len * 6, - state->indices, - attributes, - draw_flags); - - } - else - { - _cogl_draw_attributes_array (COGL_VERTICES_MODE_TRIANGLE_FAN, - state->current_vertex, 4, - attributes, - draw_flags); - } -#endif - - /* DEBUGGING CODE XXX: This path will cause all rectangles to be - * drawn with a coloured outline. Each batch will be rendered with - * the same color. This may e.g. help with debugging texture slicing - * issues, visually seeing what is batched and debugging blending - * issues, plus it looks quite cool. - */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_RECTANGLES))) - { - static CoglPipeline *outline = NULL; - guint8 color_intensity; - int i; - CoglAttribute *loop_attributes[2]; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - if (outline == NULL) - outline = cogl_pipeline_new (); - - /* The least significant three bits represent the three - components so that the order of colours goes red, green, - yellow, blue, magenta, cyan. Black and white are skipped. The - next two bits give four scales of intensity for those colours - in the order 0xff, 0xcc, 0x99, and 0x66. This gives a total - of 24 colours. If there are more than 24 batches on the stage - then it will wrap around */ - color_intensity = 0xff - 0x33 * (ctxt->journal_rectangles_color >> 3); - cogl_pipeline_set_color4ub (outline, - (ctxt->journal_rectangles_color & 1) ? - color_intensity : 0, - (ctxt->journal_rectangles_color & 2) ? - color_intensity : 0, - (ctxt->journal_rectangles_color & 4) ? - color_intensity : 0, - 0xff); - cogl_set_source (outline); - - loop_attributes[0] = attributes[0]; /* we just want the position */ - loop_attributes[1] = NULL; - for (i = 0; i < batch_len; i++) - _cogl_draw_attributes_array (COGL_VERTICES_MODE_LINE_LOOP, - 4 * i + state->current_vertex, 4, - loop_attributes, - draw_flags); - - /* Go to the next color */ - do - ctxt->journal_rectangles_color = ((ctxt->journal_rectangles_color + 1) & - ((1 << 5) - 1)); - /* We don't want to use black or white */ - while ((ctxt->journal_rectangles_color & 0x07) == 0 - || (ctxt->journal_rectangles_color & 0x07) == 0x07); - } - - state->current_vertex += (4 * batch_len); - - cogl_pop_source (); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_modelview_and_entries); -} - -static gboolean -compare_entry_modelviews (CoglJournalEntry *entry0, - CoglJournalEntry *entry1) -{ - /* Batch together quads with the same model view matrix */ - - /* FIXME: this is nasty, there are much nicer ways to track this - * (at the add_quad_vertices level) without resorting to a memcmp! - * - * E.g. If the cogl-current-matrix code maintained an "age" for - * the modelview matrix we could simply check in add_quad_vertices - * if the age has increased, and if so record the change as a - * boolean in the journal. - */ - - if (memcmp (&entry0->model_view, &entry1->model_view, - sizeof (GLfloat) * 16) == 0) - return TRUE; - else - return FALSE; -} - -/* At this point we have a run of quads that we know have compatible - * pipelines, but they may not all have the same modelview matrix */ -static void -_cogl_journal_flush_pipeline_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - COGL_STATIC_TIMER (time_flush_pipeline_entries, - "flush: texcoords+pipeline+entries", /* parent */ - "flush: pipeline+entries", - "The time spent flushing pipeline + entries", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: pipeline batch len = %d\n", batch_len); - - state->source = batch_start->pipeline; - - /* If we haven't transformed the quads in software then we need to also break - * up batches according to changes in the modelview matrix... */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - { - batch_and_call (batch_start, - batch_len, - compare_entry_modelviews, - _cogl_journal_flush_modelview_and_entries, - data); - } - else - _cogl_journal_flush_modelview_and_entries (batch_start, batch_len, data); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_pipeline_entries); -} - -static gboolean -compare_entry_pipelines (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - /* batch rectangles using compatible pipelines */ - - if (_cogl_pipeline_equal (entry0->pipeline, - entry1->pipeline, - (COGL_PIPELINE_STATE_ALL & - ~COGL_PIPELINE_STATE_COLOR), - COGL_PIPELINE_LAYER_STATE_ALL, - 0)) - return TRUE; - else - return FALSE; -} - -/* Since the stride may not reflect the number of texture layers in use - * (due to padding) we deal with texture coordinate offsets separately - * from vertex and color offsets... */ -static void -_cogl_journal_flush_texcoord_vbo_offsets_and_entries ( - CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - int i; - COGL_STATIC_TIMER (time_flush_texcoord_pipeline_entries, - "flush: vbo+texcoords+pipeline+entries", /* parent */ - "flush: texcoords+pipeline+entries", - "The time spent flushing texcoord offsets + pipeline " - "+ entries", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_texcoord_pipeline_entries); - - /* NB: attributes 0 and 1 are position and color */ - - for (i = 2; i < state->attributes->len; i++) - cogl_object_unref (g_array_index (state->attributes, CoglAttribute *, i)); - - g_array_set_size (state->attributes, batch_start->n_layers + 2); - - for (i = 0; i < batch_start->n_layers; i++) - { - CoglAttribute **attribute_entry = - &g_array_index (state->attributes, CoglAttribute *, i + 2); - const char *names[] = { - "cogl_tex_coord0_in", - "cogl_tex_coord1_in", - "cogl_tex_coord2_in", - "cogl_tex_coord3_in", - "cogl_tex_coord4_in", - "cogl_tex_coord5_in", - "cogl_tex_coord6_in", - "cogl_tex_coord7_in" - }; - char *name; - - /* XXX NB: - * Our journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 floats per position (3 when doing software transforms) - * 4 RGBA bytes, - * 2 floats per tex coord * n_layers - * (though n_layers may be padded; see definition of - * GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details) - */ - name = i < 8 ? (char *)names[i] : - g_strdup_printf ("cogl_tex_coord%d_in", i); - - /* XXX: it may be worth having some form of static initializer for - * attributes... */ - *attribute_entry = - cogl_attribute_new (state->vertex_array, - name, - state->stride, - state->array_offset + - (POS_STRIDE + COLOR_STRIDE) * 4 + - TEX_STRIDE * 4 * i, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - if (i >= 8) - g_free (name); - } - - batch_and_call (batch_start, - batch_len, - compare_entry_pipelines, - _cogl_journal_flush_pipeline_and_entries, - data); - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_texcoord_pipeline_entries); -} - -static gboolean -compare_entry_n_layers (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - if (entry0->n_layers == entry1->n_layers) - return TRUE; - else - return FALSE; -} - -/* At this point we know the stride has changed from the previous batch - * of journal entries */ -static void -_cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - gsize stride; - int i; - CoglAttribute **attribute_entry; - COGL_STATIC_TIMER (time_flush_vbo_texcoord_pipeline_entries, - "flush: clip+vbo+texcoords+pipeline+entries", /* parent */ - "flush: vbo+texcoords+pipeline+entries", - "The time spent flushing vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, - time_flush_vbo_texcoord_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: vbo offset batch len = %d\n", batch_len); - - /* XXX NB: - * Our journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 GLfloats per position (3 when doing software transforms) - * 4 RGBA GLubytes, - * 2 GLfloats per tex coord * n_layers - * (though n_layers may be padded; see definition of - * GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details) - */ - stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (batch_start->n_layers); - stride *= sizeof (float); - state->stride = stride; - - for (i = 0; i < state->attributes->len; i++) - cogl_object_unref (g_array_index (state->attributes, CoglAttribute *, i)); - - g_array_set_size (state->attributes, 2); - - attribute_entry = &g_array_index (state->attributes, CoglAttribute *, 0); - *attribute_entry = cogl_attribute_new (state->vertex_array, - "cogl_position_in", - stride, - state->array_offset, - N_POS_COMPONENTS, - COGL_ATTRIBUTE_TYPE_FLOAT); - - attribute_entry = &g_array_index (state->attributes, CoglAttribute *, 1); - *attribute_entry = - cogl_attribute_new (state->vertex_array, - "cogl_color_in", - stride, - state->array_offset + (POS_STRIDE * 4), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - -#ifndef HAVE_COGL_GL - state->indices = cogl_get_rectangle_indices (batch_len); -#endif - - /* We only create new Attributes when the stride within the - * VertexArray changes. (due to a change in the number of pipeline - * layers) While the stride remains constant we walk forward through - * the above VertexArray using a vertex offset passed to - * cogl_draw_attributes - */ - state->current_vertex = 0; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL))) - { - guint8 *verts; - - /* Mapping a buffer for read is probably a really bad thing to - do but this will only happen during debugging so it probably - doesn't matter */ - verts = ((guint8 *) cogl_buffer_map (COGL_BUFFER (state->vertex_array), - COGL_BUFFER_ACCESS_READ, 0) + - state->array_offset); - - _cogl_journal_dump_quad_batch (verts, - batch_start->n_layers, - batch_len); - - cogl_buffer_unmap (COGL_BUFFER (state->vertex_array)); - } - - batch_and_call (batch_start, - batch_len, - compare_entry_n_layers, - _cogl_journal_flush_texcoord_vbo_offsets_and_entries, - data); - - /* progress forward through the VBO containing all our vertices */ - state->array_offset += (stride * 4 * batch_len); - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL))) - g_print ("new vbo offset = %lu\n", (unsigned long)state->array_offset); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_flush_vbo_texcoord_pipeline_entries); -} - -static gboolean -compare_entry_strides (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - /* Currently the only thing that affects the stride for our vertex arrays - * is the number of pipeline layers. We need to update our VBO offsets - * whenever the stride changes. */ - /* TODO: We should be padding the n_layers == 1 case as if it were - * n_layers == 2 so we can reduce the need to split batches. */ - if (entry0->n_layers == entry1->n_layers || - (entry0->n_layers <= MIN_LAYER_PADING && - entry1->n_layers <= MIN_LAYER_PADING)) - return TRUE; - else - return FALSE; -} - -/* At this point we know the batch has a unique clip stack */ -static void -_cogl_journal_flush_clip_stacks_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - - COGL_STATIC_TIMER (time_flush_clip_stack_pipeline_entries, - "Journal Flush", /* parent */ - "flush: clip+vbo+texcoords+pipeline+entries", - "The time spent flushing clip + vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, - time_flush_clip_stack_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: clip stack batch len = %d\n", batch_len); - - _cogl_clip_stack_flush (batch_start->clip_stack); - - _cogl_matrix_stack_push (state->modelview_stack); - - /* If we have transformed all our quads at log time then we ensure - * no further model transform is applied by loading the identity - * matrix here. We need to do this after flushing the clip stack - * because the clip stack flushing code can modify the matrix */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM)))) - { - _cogl_matrix_stack_load_identity (state->modelview_stack); - _cogl_matrix_stack_flush_to_gl (state->modelview_stack, - COGL_MATRIX_MODELVIEW); - } - - /* Setting up the clip state can sometimes also flush the projection - matrix so we should flush it again. This will be a no-op if the - clip code didn't modify the projection */ - _cogl_matrix_stack_flush_to_gl (state->projection_stack, - COGL_MATRIX_PROJECTION); - - batch_and_call (batch_start, - batch_len, - compare_entry_strides, - _cogl_journal_flush_vbo_offsets_and_entries, /* callback */ - data); - - _cogl_matrix_stack_pop (state->modelview_stack); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_flush_clip_stack_pipeline_entries); -} - -static gboolean -calculate_translation (const CoglMatrix *a, - const CoglMatrix *b, - float *tx_p, - float *ty_p) -{ - float tx, ty; - int x, y; - - /* Assuming we had the original matrix in this form: - * - * [ a₁₁, a₁₂, a₁₃, a₁₄ ] - * [ a₂₁, a₂₂, a₂₃, a₂₄ ] - * a = [ a₃₁, a₃₂, a₃₃, a₃₄ ] - * [ a₄₁, a₄₂, a₄₃, a₄₄ ] - * - * then a translation of that matrix would be a multiplication by a - * matrix of this form: - * - * [ 1, 0, 0, x ] - * [ 0, 1, 0, y ] - * t = [ 0, 0, 1, 0 ] - * [ 0, 0, 0, 1 ] - * - * That would give us a matrix of this form. - * - * [ a₁₁, a₁₂, a₁₃, a₁₁ x + a₁₂ y + a₁₄ ] - * [ a₂₁, a₂₂, a₂₃, a₂₁ x + a₂₂ y + a₂₄ ] - * b = a ⋅ t = [ a₃₁, a₃₂, a₃₃, a₃₁ x + a₃₂ y + a₃₄ ] - * [ a₄₁, a₄₂, a₄₃, a₄₁ x + a₄₂ y + a₄₄ ] - * - * We can use the two equations from the top left of the matrix to - * work out the x and y translation given the two matrices: - * - * b₁₄ = a₁₁x + a₁₂y + a₁₄ - * b₂₄ = a₂₁x + a₂₂y + a₂₄ - * - * Rearranging gives us: - * - * a₁₂ b₂₄ - a₂₄ a₁₂ - * ----------------- + a₁₄ - b₁₄ - * a₂₂ - * x = --------------------------------- - * a₁₂ a₂₁ - * ------- - a₁₁ - * a₂₂ - * - * b₂₄ - a₂₁x - a₂₄ - * y = ---------------- - * a₂₂ - * - * Once we've worked out what x and y would be if this was a valid - * translation then we can simply verify that the rest of the matrix - * matches up. - */ - - /* The leftmost 3x4 part of the matrix shouldn't change by a - translation so we can just compare it directly */ - for (y = 0; y < 4; y++) - for (x = 0; x < 3; x++) - if ((&a->xx)[x * 4 + y] != (&b->xx)[x * 4 + y]) - return FALSE; - - tx = (((a->xy * b->yw - a->yw * a->xy) / a->yy + a->xw - b->xw) / - ((a->xy * a->yx) / a->yy - a->xx)); - ty = (b->yw - a->yx * tx - a->yw) / a->yy; - -#define APPROX_EQUAL(a, b) (fabsf ((a) - (b)) < 1e-6f) - - /* Check whether the 4th column of the matrices match up to the - calculation */ - if (!APPROX_EQUAL (b->xw, a->xx * tx + a->xy * ty + a->xw) || - !APPROX_EQUAL (b->yw, a->yx * tx + a->yy * ty + a->yw) || - !APPROX_EQUAL (b->zw, a->zx * tx + a->zy * ty + a->zw) || - !APPROX_EQUAL (b->ww, a->wx * tx + a->wy * ty + a->ww)) - return FALSE; - -#undef APPROX_EQUAL - - *tx_p = tx; - *ty_p = ty; - - return TRUE; -} - -typedef struct -{ - float x_1, y_1; - float x_2, y_2; -} ClipBounds; - -static gboolean -can_software_clip_entry (CoglJournalEntry *journal_entry, - CoglJournalEntry *prev_journal_entry, - CoglClipStack *clip_stack, - ClipBounds *clip_bounds_out) -{ - CoglPipeline *pipeline = journal_entry->pipeline; - CoglClipStack *clip_entry; - int layer_num; - - clip_bounds_out->x_1 = -G_MAXFLOAT; - clip_bounds_out->y_1 = -G_MAXFLOAT; - clip_bounds_out->x_2 = G_MAXFLOAT; - clip_bounds_out->y_2 = G_MAXFLOAT; - - /* Check the pipeline is usable. We can short-cut here for - entries using the same pipeline as the previous entry */ - if (prev_journal_entry == NULL || pipeline != prev_journal_entry->pipeline) - { - /* If the pipeline has a user program then we can't reliably modify - the texture coordinates */ - if (cogl_pipeline_get_user_program (pipeline)) - return FALSE; - - /* If any of the pipeline layers have a texture matrix then we can't - reliably modify the texture coordinates */ - for (layer_num = cogl_pipeline_get_n_layers (pipeline) - 1; - layer_num >= 0; - layer_num--) - if (_cogl_pipeline_layer_has_user_matrix (pipeline, layer_num)) - return FALSE; - } - - /* Now we need to verify that each clip entry's matrix is just a - translation of the journal entry's modelview matrix. We can - also work out the bounds of the clip in modelview space using - this translation */ - for (clip_entry = clip_stack; clip_entry; clip_entry = clip_entry->parent) - { - float rect_x1, rect_y1, rect_x2, rect_y2; - CoglClipStackRect *clip_rect; - float tx, ty; - - clip_rect = (CoglClipStackRect *) clip_entry; - - if (!calculate_translation (&clip_rect->matrix, - &journal_entry->model_view, - &tx, &ty)) - return FALSE; - - if (clip_rect->x0 < clip_rect->x1) - { - rect_x1 = clip_rect->x0; - rect_x2 = clip_rect->x1; - } - else - { - rect_x1 = clip_rect->x1; - rect_x2 = clip_rect->x0; - } - if (clip_rect->y0 < clip_rect->y1) - { - rect_y1 = clip_rect->y0; - rect_y2 = clip_rect->y1; - } - else - { - rect_y1 = clip_rect->y1; - rect_y2 = clip_rect->y0; - } - - clip_bounds_out->x_1 = MAX (clip_bounds_out->x_1, rect_x1 - tx); - clip_bounds_out->y_1 = MAX (clip_bounds_out->y_1, rect_y1 - ty); - clip_bounds_out->x_2 = MIN (clip_bounds_out->x_2, rect_x2 - tx); - clip_bounds_out->y_2 = MIN (clip_bounds_out->y_2, rect_y2 - ty); - } - - return TRUE; -} - -static void -software_clip_entry (CoglJournalEntry *journal_entry, - float *verts, - ClipBounds *clip_bounds) -{ - size_t stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (journal_entry->n_layers); - float rx1, ry1, rx2, ry2; - float vx1, vy1, vx2, vy2; - int layer_num; - - /* Remove the clip on the entry */ - _cogl_clip_stack_unref (journal_entry->clip_stack); - journal_entry->clip_stack = NULL; - - vx1 = verts[0]; - vy1 = verts[1]; - vx2 = verts[stride]; - vy2 = verts[stride + 1]; - - if (vx1 < vx2) - { - rx1 = vx1; - rx2 = vx2; - } - else - { - rx1 = vx2; - rx2 = vx1; - } - if (vy1 < vy2) - { - ry1 = vy1; - ry2 = vy2; - } - else - { - ry1 = vy2; - ry2 = vy1; - } - - rx1 = CLAMP (rx1, clip_bounds->x_1, clip_bounds->x_2); - ry1 = CLAMP (ry1, clip_bounds->y_1, clip_bounds->y_2); - rx2 = CLAMP (rx2, clip_bounds->x_1, clip_bounds->x_2); - ry2 = CLAMP (ry2, clip_bounds->y_1, clip_bounds->y_2); - - /* Check if the rectangle intersects the clip at all */ - if (rx1 == rx2 || ry1 == ry2) - /* Will set all of the vertex data to 0 in the hope that this - will create a degenerate rectangle and the GL driver will - be able to clip it quickly */ - memset (verts, 0, sizeof (float) * stride * 2); - else - { - if (vx1 > vx2) - { - float t = rx1; - rx1 = rx2; - rx2 = t; - } - if (vy1 > vy2) - { - float t = ry1; - ry1 = ry2; - ry2 = t; - } - - verts[0] = rx1; - verts[1] = ry1; - verts[stride] = rx2; - verts[stride + 1] = ry2; - - /* Convert the rectangle coordinates to a fraction of the original - rectangle */ - rx1 = (rx1 - vx1) / (vx2 - vx1); - ry1 = (ry1 - vy1) / (vy2 - vy1); - rx2 = (rx2 - vx1) / (vx2 - vx1); - ry2 = (ry2 - vy1) / (vy2 - vy1); - - for (layer_num = 0; layer_num < journal_entry->n_layers; layer_num++) - { - float *t = verts + 2 + 2 * layer_num; - float tx1 = t[0], ty1 = t[1]; - float tx2 = t[stride], ty2 = t[stride + 1]; - t[0] = rx1 * (tx2 - tx1) + tx1; - t[1] = ry1 * (ty2 - ty1) + ty1; - t[stride] = rx2 * (tx2 - tx1) + tx1; - t[stride + 1] = ry2 * (ty2 - ty1) + ty1; - } - } -} - -static void -maybe_software_clip_entries (CoglJournalEntry *batch_start, - int batch_len, - CoglJournalFlushState *state) -{ - CoglJournal *journal = state->journal; - CoglClipStack *clip_stack, *clip_entry; - int entry_num; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* This tries to find cases where the entry is logged with a clip - but it would be faster to modify the vertex and texture - coordinates rather than flush the clip so that it can batch - better */ - - /* If the batch is reasonably long then it's worthwhile programming - the GPU to do the clip */ - if (batch_len >= COGL_JOURNAL_HARDWARE_CLIP_THRESHOLD) - return; - - clip_stack = batch_start->clip_stack; - - if (clip_stack == NULL) - return; - - /* Verify that all of the clip stack entries are a simple rectangle - clip */ - for (clip_entry = clip_stack; clip_entry; clip_entry = clip_entry->parent) - if (clip_entry->type != COGL_CLIP_STACK_RECT) - return; - - /* This scratch buffer is used to store the translation for each - entry in the journal. We store it in a separate buffer because - it's expensive to calculate but at this point we still don't know - whether we can clip all of the entries so we don't want to do the - rest of the dependant calculations until we're sure we can. */ - if (ctx->journal_clip_bounds == NULL) - ctx->journal_clip_bounds = g_array_new (FALSE, FALSE, sizeof (ClipBounds)); - g_array_set_size (ctx->journal_clip_bounds, batch_len); - - for (entry_num = 0; entry_num < batch_len; entry_num++) - { - CoglJournalEntry *journal_entry = batch_start + entry_num; - CoglJournalEntry *prev_journal_entry = - entry_num ? batch_start + (entry_num - 1) : NULL; - ClipBounds *clip_bounds = &g_array_index (ctx->journal_clip_bounds, - ClipBounds, entry_num); - - if (!can_software_clip_entry (journal_entry, prev_journal_entry, - clip_stack, - clip_bounds)) - return; - } - - /* If we make it here then we know we can software clip the entire batch */ - - COGL_NOTE (CLIPPING, "Software clipping a batch of length %i", batch_len); - - for (entry_num = 0; entry_num < batch_len; entry_num++) - { - CoglJournalEntry *journal_entry = batch_start + entry_num; - float *verts = &g_array_index (journal->vertices, float, - journal_entry->array_offset + 1); - ClipBounds *clip_bounds = &g_array_index (ctx->journal_clip_bounds, - ClipBounds, entry_num); - - software_clip_entry (journal_entry, verts, clip_bounds); - } - - return; -} - -static void -_cogl_journal_maybe_software_clip_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - - COGL_STATIC_TIMER (time_check_software_clip, - "Journal Flush", /* parent */ - "flush: software clipping", - "Time spent software clipping", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, - time_check_software_clip); - - maybe_software_clip_entries (batch_start, batch_len, state); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_check_software_clip); -} - -static gboolean -compare_entry_clip_stacks (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - return entry0->clip_stack == entry1->clip_stack; -} - -static CoglVertexArray * -upload_vertices (const CoglJournalEntry *entries, - int n_entries, - size_t needed_vbo_len, - GArray *vertices) -{ - CoglVertexArray *array; - CoglBuffer *buffer; - const float *vin; - float *vout; - int entry_num; - int i; - - g_assert (needed_vbo_len); - - array = cogl_vertex_array_new (needed_vbo_len * 4, NULL); - buffer = COGL_BUFFER (array); - cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_STATIC); - - vout = _cogl_buffer_map_for_fill_or_fallback (buffer); - vin = &g_array_index (vertices, float, 0); - - /* Expand the number of vertices from 2 to 4 while uploading */ - for (entry_num = 0; entry_num < n_entries; entry_num++) - { - const CoglJournalEntry *entry = entries + entry_num; - size_t vb_stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (entry->n_layers); - size_t array_stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (entry->n_layers); - - /* Copy the color to all four of the vertices */ - for (i = 0; i < 4; i++) - memcpy (vout + vb_stride * i + POS_STRIDE, vin, 4); - vin++; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - { - vout[vb_stride * 0] = vin[0]; - vout[vb_stride * 0 + 1] = vin[1]; - vout[vb_stride * 1] = vin[0]; - vout[vb_stride * 1 + 1] = vin[array_stride + 1]; - vout[vb_stride * 2] = vin[array_stride]; - vout[vb_stride * 2 + 1] = vin[array_stride + 1]; - vout[vb_stride * 3] = vin[array_stride]; - vout[vb_stride * 3 + 1] = vin[1]; - } - else - { - float v[8]; - - v[0] = vin[0]; - v[1] = vin[1]; - v[2] = vin[0]; - v[3] = vin[array_stride + 1]; - v[4] = vin[array_stride]; - v[5] = vin[array_stride + 1]; - v[6] = vin[array_stride]; - v[7] = vin[1]; - - cogl_matrix_transform_points (&entry->model_view, - 2, /* n_components */ - sizeof (float) * 2, /* stride_in */ - v, /* points_in */ - /* strideout */ - vb_stride * sizeof (float), - vout, /* points_out */ - 4 /* n_points */); - } - - for (i = 0; i < entry->n_layers; i++) - { - const float *tin = vin + 2; - float *tout = vout + POS_STRIDE + COLOR_STRIDE; - - tout[vb_stride * 0 + i * 2] = tin[i * 2]; - tout[vb_stride * 0 + 1 + i * 2] = tin[i * 2 + 1]; - tout[vb_stride * 1 + i * 2] = tin[i * 2]; - tout[vb_stride * 1 + 1 + i * 2] = tin[array_stride + i * 2 + 1]; - tout[vb_stride * 2 + i * 2] = tin[array_stride + i * 2]; - tout[vb_stride * 2 + 1 + i * 2] = tin[array_stride + i * 2 + 1]; - tout[vb_stride * 3 + i * 2] = tin[array_stride + i * 2]; - tout[vb_stride * 3 + 1 + i * 2] = tin[i * 2 + 1]; - } - - vin += array_stride * 2; - vout += vb_stride * 4; - } - - _cogl_buffer_unmap_for_fill_or_fallback (buffer); - - return array; -} - -void -_cogl_journal_discard (CoglJournal *journal) -{ - int i; - - for (i = 0; i < journal->entries->len; i++) - { - CoglJournalEntry *entry = - &g_array_index (journal->entries, CoglJournalEntry, i); - _cogl_pipeline_journal_unref (entry->pipeline); - _cogl_clip_stack_unref (entry->clip_stack); - } - - g_array_set_size (journal->entries, 0); - g_array_set_size (journal->vertices, 0); - journal->needed_vbo_len = 0; - journal->fast_read_pixel_count = 0; -} - -/* Note: A return value of FALSE doesn't mean 'no' it means - * 'unknown' */ -gboolean -_cogl_journal_all_entries_within_bounds (CoglJournal *journal, - float clip_x0, - float clip_y0, - float clip_x1, - float clip_y1) -{ - CoglJournalEntry *entry = (CoglJournalEntry *)journal->entries->data; - CoglClipStack *clip_entry; - CoglClipStack *reference = NULL; - int bounds_x0; - int bounds_y0; - int bounds_x1; - int bounds_y1; - int i; - - if (journal->entries->len == 0) - return TRUE; - - /* Find the shortest clip_stack ancestry that leaves us in the - * required bounds */ - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - _cogl_clip_stack_get_bounds (clip_entry, - &bounds_x0, &bounds_y0, - &bounds_x1, &bounds_y1); - - if (bounds_x0 >= clip_x0 && bounds_y0 >= clip_y0 && - bounds_x1 <= clip_x1 && bounds_y1 <= clip_y1) - reference = clip_entry; - else - break; - } - - if (!reference) - return FALSE; - - /* For the remaining journal entries we will only verify they share - * 'reference' as an ancestor in their clip stack since that's - * enough to know that they would be within the required bounds. - */ - for (i = 1; i < journal->entries->len; i++) - { - gboolean found_reference = FALSE; - entry = &g_array_index (journal->entries, CoglJournalEntry, i); - - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - if (clip_entry == reference) - { - found_reference = TRUE; - break; - } - } - - if (!found_reference) - return FALSE; - } - - return TRUE; -} - -/* XXX NB: When _cogl_journal_flush() returns all state relating - * to pipelines, all glEnable flags and current matrix state - * is undefined. - */ -void -_cogl_journal_flush (CoglJournal *journal, - CoglFramebuffer *framebuffer) -{ - CoglJournalFlushState state; - int i; - CoglMatrixStack *modelview_stack; - COGL_STATIC_TIMER (flush_timer, - "Mainloop", /* parent */ - "Journal Flush", - "The time spent flushing the Cogl journal", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (journal->entries->len == 0) - return; - - /* The entries in this journal may depend on images in other - * framebuffers which may require that we flush the journals - * associated with those framebuffers before we can flush - * this journal... */ - _cogl_framebuffer_flush_dependency_journals (framebuffer); - - /* Note: we start the timer after flushing dependency journals so - * that the timer isn't started recursively. */ - COGL_TIMER_START (_cogl_uprof_context, flush_timer); - - cogl_push_framebuffer (framebuffer); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: journal len = %d\n", journal->entries->len); - - /* NB: the journal deals with flushing the modelview stack and clip - state manually */ - _cogl_framebuffer_flush_state (framebuffer, - framebuffer, - COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW | - COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE); - - state.journal = journal; - - state.attributes = ctx->journal_flush_attributes_array; - - modelview_stack = _cogl_framebuffer_get_modelview_stack (framebuffer); - state.modelview_stack = modelview_stack; - state.projection_stack = _cogl_framebuffer_get_projection_stack (framebuffer); - - if (G_UNLIKELY ((COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_CLIP)) == 0)) - { - /* We do an initial walk of the journal to analyse the clip stack - batches to see if we can do software clipping. We do this as a - separate walk of the journal because we can modify entries and - this may end up joining together clip stack batches in the next - iteration. */ - batch_and_call ((CoglJournalEntry *)journal->entries->data, /* first entry */ - journal->entries->len, /* max number of entries to consider */ - compare_entry_clip_stacks, - _cogl_journal_maybe_software_clip_entries, /* callback */ - &state); /* data */ - } - - /* We upload the vertices after the clip stack pass in case it - modifies the entries */ - state.vertex_array = upload_vertices (&g_array_index (journal->entries, - CoglJournalEntry, 0), - journal->entries->len, - journal->needed_vbo_len, - journal->vertices); - state.array_offset = 0; - - /* batch_and_call() batches a list of journal entries according to some - * given criteria and calls a callback once for each determined batch. - * - * The process of flushing the journal is staggered to reduce the amount - * of driver/GPU state changes necessary: - * 1) We split the entries according to the clip state. - * 2) We split the entries according to the stride of the vertices: - * Each time the stride of our vertex data changes we need to call - * gl{Vertex,Color}Pointer to inform GL of new VBO offsets. - * Currently the only thing that affects the stride of our vertex data - * is the number of pipeline layers. - * 3) We split the entries explicitly by the number of pipeline layers: - * We pad our vertex data when the number of layers is < 2 so that we - * can minimize changes in stride. Each time the number of layers - * changes we need to call glTexCoordPointer to inform GL of new VBO - * offsets. - * 4) We then split according to compatible Cogl pipelines: - * This is where we flush pipeline state - * 5) Finally we split according to modelview matrix changes: - * This is when we finally tell GL to draw something. - * Note: Splitting by modelview changes is skipped when are doing the - * vertex transformation in software at log time. - */ - batch_and_call ((CoglJournalEntry *)journal->entries->data, /* first entry */ - journal->entries->len, /* max number of entries to consider */ - compare_entry_clip_stacks, - _cogl_journal_flush_clip_stacks_and_entries, /* callback */ - &state); /* data */ - - for (i = 0; i < state.attributes->len; i++) - cogl_object_unref (g_array_index (state.attributes, CoglAttribute *, i)); - g_array_set_size (state.attributes, 0); - - cogl_object_unref (state.vertex_array); - - _cogl_journal_discard (journal); - - cogl_pop_framebuffer (); - - COGL_TIMER_STOP (_cogl_uprof_context, flush_timer); -} - -static gboolean -add_framebuffer_deps_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglFramebuffer *framebuffer = user_data; - CoglHandle texture = _cogl_pipeline_layer_get_texture_real (layer); - const GList *l; - - if (!texture) - return TRUE; - - for (l = _cogl_texture_get_associated_framebuffers (texture); l; l = l->next) - _cogl_framebuffer_add_dependency (framebuffer, l->data); - - return TRUE; -} - -void -_cogl_journal_log_quad (CoglJournal *journal, - const float *position, - CoglPipeline *pipeline, - int n_layers, - CoglHandle layer0_override_texture, - const float *tex_coords, - unsigned int tex_coords_len) -{ - gsize stride; - int next_vert; - float *v; - int i; - int next_entry; - guint32 disable_layers; - CoglJournalEntry *entry; - CoglPipeline *source; - CoglClipStack *clip_stack; - CoglPipelineFlushOptions flush_options; - COGL_STATIC_TIMER (log_timer, - "Mainloop", /* parent */ - "Journal Log", - "The time spent logging in the Cogl journal", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, log_timer); - - /* The vertex data is logged into a separate array. The data needs - to be copied into a vertex array before it's given to GL so we - only store two vertices per quad and expand it to four while - uploading. */ - - /* XXX: See definition of GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS for details - * about how we pack our vertex data */ - stride = GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (n_layers); - - next_vert = journal->vertices->len; - g_array_set_size (journal->vertices, next_vert + 2 * stride + 1); - v = &g_array_index (journal->vertices, float, next_vert); - - /* We calculate the needed size of the vbo as we go because it - depends on the number of layers in each entry and it's not easy - calculate based on the length of the logged vertices array */ - journal->needed_vbo_len += GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers) * 4; - - /* XXX: All the jumping around to fill in this strided buffer doesn't - * seem ideal. */ - - /* FIXME: This is a hacky optimization, since it will break if we - * change the definition of CoglColor: */ - _cogl_pipeline_get_colorubv (pipeline, (guint8 *) v); - v++; - - memcpy (v, position, sizeof (float) * 2); - memcpy (v + stride, position + 2, sizeof (float) * 2); - - for (i = 0; i < n_layers; i++) - { - /* XXX: See definition of GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS - * for details about how we pack our vertex data */ - GLfloat *t = v + 2 + i * 2; - - memcpy (t, tex_coords + i * 4, sizeof (float) * 2); - memcpy (t + stride, tex_coords + i * 4 + 2, sizeof (float) * 2); - } - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL))) - { - g_print ("Logged new quad:\n"); - v = &g_array_index (journal->vertices, float, next_vert); - _cogl_journal_dump_logged_quad ((guint8 *)v, n_layers); - } - - next_entry = journal->entries->len; - g_array_set_size (journal->entries, next_entry + 1); - entry = &g_array_index (journal->entries, CoglJournalEntry, next_entry); - - entry->n_layers = n_layers; - entry->array_offset = next_vert; - - source = pipeline; - - if (G_UNLIKELY (ctx->legacy_state_set)) - { - source = cogl_pipeline_copy (pipeline); - _cogl_pipeline_apply_legacy_state (source); - } - - flush_options.flags = 0; - if (G_UNLIKELY (cogl_pipeline_get_n_layers (pipeline) != n_layers)) - { - disable_layers = (1 << n_layers) - 1; - disable_layers = ~disable_layers; - flush_options.disable_layers = disable_layers; - flush_options.flags |= COGL_PIPELINE_FLUSH_DISABLE_MASK; - } - if (G_UNLIKELY (layer0_override_texture)) - { - flush_options.flags |= COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE; - flush_options.layer0_override_texture = layer0_override_texture; - } - - if (G_UNLIKELY (flush_options.flags)) - { - /* If we haven't already created a derived pipeline... */ - if (source == pipeline) - source = cogl_pipeline_copy (pipeline); - _cogl_pipeline_apply_overrides (source, &flush_options); - } - - entry->pipeline = _cogl_pipeline_journal_ref (source); - - clip_stack = _cogl_framebuffer_get_clip_stack (cogl_get_draw_framebuffer ()); - entry->clip_stack = _cogl_clip_stack_ref (clip_stack); - - if (G_UNLIKELY (source != pipeline)) - cogl_handle_unref (source); - - cogl_get_modelview_matrix (&entry->model_view); - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_framebuffer_deps_cb, - cogl_get_draw_framebuffer ()); - - /* XXX: It doesn't feel very nice that in this case we just assume - * that the journal is associated with the current framebuffer. I - * think a journal->framebuffer reference would seem nicer here but - * the reason we don't have that currently is that it would - * introduce a circular reference. */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BATCHING))) - _cogl_framebuffer_flush_journal (cogl_get_draw_framebuffer ()); - - COGL_TIMER_STOP (_cogl_uprof_context, log_timer); -} - -static void -entry_to_screen_polygon (const CoglJournalEntry *entry, - float *vertices, - float *poly) -{ - size_t array_stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (entry->n_layers); - CoglMatrixStack *projection_stack; - CoglMatrix projection; - int i; - float viewport[4]; - - poly[0] = vertices[0]; - poly[1] = vertices[1]; - poly[2] = 0; - poly[3] = 1; - - poly[4] = vertices[0]; - poly[5] = vertices[array_stride + 1]; - poly[6] = 0; - poly[7] = 1; - - poly[8] = vertices[array_stride]; - poly[9] = vertices[array_stride + 1]; - poly[10] = 0; - poly[11] = 1; - - poly[12] = vertices[array_stride]; - poly[13] = vertices[1]; - poly[14] = 0; - poly[15] = 1; - - /* TODO: perhaps split the following out into a more generalized - * _cogl_transform_points utility... - */ - - cogl_matrix_transform_points (&entry->model_view, - 2, /* n_components */ - sizeof (float) * 4, /* stride_in */ - poly, /* points_in */ - /* strideout */ - sizeof (float) * 4, - poly, /* points_out */ - 4 /* n_points */); - - projection_stack = - _cogl_framebuffer_get_projection_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_get (projection_stack, &projection); - - cogl_matrix_project_points (&projection, - 3, /* n_components */ - sizeof (float) * 4, /* stride_in */ - poly, /* points_in */ - /* strideout */ - sizeof (float) * 4, - poly, /* points_out */ - 4 /* n_points */); - - _cogl_framebuffer_get_viewport4fv (cogl_get_draw_framebuffer (), - viewport); - -/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) - * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with - * (0,0) being top left. */ -#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \ - ( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) ) -/* Note: for Y we first flip all coordinates around the X axis while in - * normalized device coodinates */ -#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \ - ( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) ) - - /* Scale from normalized device coordinates (in range [-1,1]) to - * window coordinates ranging [0,window-size] ... */ - for (i = 0; i < 4; i++) - { - float w = poly[4 * i + 3]; - - /* Perform perspective division */ - poly[4 * i] /= w; - poly[4 * i + 1] /= w; - - /* Apply viewport transform */ - poly[4 * i] = VIEWPORT_TRANSFORM_X (poly[4 * i], - viewport[0], viewport[2]); - poly[4 * i + 1] = VIEWPORT_TRANSFORM_Y (poly[4 * i + 1], - viewport[1], viewport[3]); - } - -#undef VIEWPORT_TRANSFORM_X -#undef VIEWPORT_TRANSFORM_Y -} - -static gboolean -try_checking_point_hits_entry_after_clipping (CoglJournalEntry *entry, - float *vertices, - float x, - float y, - gboolean *hit) -{ - gboolean can_software_clip = TRUE; - gboolean needs_software_clip = FALSE; - CoglClipStack *clip_entry; - - *hit = TRUE; - - /* Verify that all of the clip stack entries are simple rectangle - * clips */ - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - if (x < clip_entry->bounds_x0 || - x >= clip_entry->bounds_x1 || - y < clip_entry->bounds_y0 || - y >= clip_entry->bounds_y1) - { - *hit = FALSE; - return TRUE; - } - - if (clip_entry->type == COGL_CLIP_STACK_WINDOW_RECT) - { - /* XXX: technically we could still run the software clip in - * this case because for our purposes we know this clip - * can be ignored now, but [can_]sofware_clip_entry() doesn't - * know this and will bail out. */ - can_software_clip = FALSE; - } - else if (clip_entry->type == COGL_CLIP_STACK_RECT) - { - CoglClipStackRect *rect_entry = (CoglClipStackRect *)entry; - - if (rect_entry->can_be_scissor == FALSE) - needs_software_clip = TRUE; - /* If can_be_scissor is TRUE then we know it's screen - * aligned and the hit test we did above has determined - * that we are inside this clip. */ - } - else - return FALSE; - } - - if (needs_software_clip) - { - ClipBounds clip_bounds; - float poly[16]; - - if (!can_software_clip) - return FALSE; - - if (!can_software_clip_entry (entry, NULL, - entry->clip_stack, &clip_bounds)) - return FALSE; - - software_clip_entry (entry, vertices, &clip_bounds); - entry_to_screen_polygon (entry, vertices, poly); - - *hit = _cogl_util_point_in_screen_poly (x, y, poly, sizeof (float) * 4, 4); - return TRUE; - } - - return TRUE; -} - -gboolean -_cogl_journal_try_read_pixel (CoglJournal *journal, - int x, - int y, - CoglPixelFormat format, - guint8 *pixel, - gboolean *found_intersection) -{ - int i; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* XXX: this number has been plucked out of thin air, but the idea - * is that if so many pixels are being read from the same un-changed - * journal than we expect that it will be more efficient to fail - * here so we end up flushing and rendering the journal so that - * further reads can directly read from the framebuffer. There will - * be a bit more lag to flush the render but if there are going to - * continue being lots of arbitrary single pixel reads they will end - * up faster in the end. */ - if (journal->fast_read_pixel_count > 50) - return FALSE; - - if (format != COGL_PIXEL_FORMAT_RGBA_8888_PRE && - format != COGL_PIXEL_FORMAT_RGBA_8888) - return FALSE; - - *found_intersection = FALSE; - - /* NB: The most recently added journal entry is the last entry, and - * assuming this is a simple scene only comprised of opaque coloured - * rectangles with no special pipelines involved (e.g. enabling - * depth testing) then we can assume painter's algorithm for the - * entries and so our fast read-pixel just needs to walk backwards - * through the journal entries trying to intersect each entry with - * the given point of interest. */ - for (i = journal->entries->len - 1; i >= 0; i--) - { - CoglJournalEntry *entry = - &g_array_index (journal->entries, CoglJournalEntry, i); - guint8 *color = (guint8 *)&g_array_index (journal->vertices, float, - entry->array_offset); - float *vertices = (float *)color + 1; - float poly[16]; - - entry_to_screen_polygon (entry, vertices, poly); - - if (!_cogl_util_point_in_screen_poly (x, y, poly, sizeof (float) * 4, 4)) - continue; - - /* FIXME: the journal should have a back pointer to the - * associated framebuffer, because it should be possible to read - * a pixel from arbitrary framebuffers without needing to - * internally call _cogl_push/pop_framebuffer. - */ - if (entry->clip_stack) - { - gboolean hit; - - if (!try_checking_point_hits_entry_after_clipping (entry, vertices, - x, y, &hit)) - return FALSE; /* hit couldn't be determined */ - - if (!hit) - continue; - } - - *found_intersection = TRUE; - - /* If we find that the rectangle the point of interest - * intersects has any state more complex than a constant opaque - * color then we bail out. */ - if (!_cogl_pipeline_equal (ctx->opaque_color_pipeline, entry->pipeline, - (COGL_PIPELINE_STATE_ALL & - ~COGL_PIPELINE_STATE_COLOR), - COGL_PIPELINE_LAYER_STATE_ALL, - 0)) - return FALSE; - - - /* we currently only care about cases where the premultiplied or - * unpremultipled colors are equivalent... */ - if (color[3] != 0xff) - return FALSE; - - pixel[0] = color[0]; - pixel[1] = color[1]; - pixel[2] = color[2]; - pixel[3] = color[3]; - - goto success; - } - -success: - journal->fast_read_pixel_count++; - return TRUE; -} diff --git a/clutter/cogl/cogl/cogl-material-compat.c b/clutter/cogl/cogl/cogl-material-compat.c deleted file mode 100644 index 72349fe..0000000 --- a/clutter/cogl/cogl/cogl-material-compat.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -CoglMaterial * -cogl_material_new (void) -{ - return COGL_MATERIAL (cogl_pipeline_new ()); -} - -CoglMaterial * -cogl_material_copy (CoglMaterial *source) -{ - return COGL_MATERIAL (cogl_pipeline_copy (COGL_PIPELINE (source))); -} - -CoglHandle -cogl_material_ref (CoglHandle handle) -{ - return cogl_object_ref (handle); -} - -void -cogl_material_unref (CoglHandle handle) -{ - cogl_object_unref (handle); -} - -gboolean -cogl_is_material (CoglHandle handle) -{ - return cogl_is_pipeline (handle); -} - -void -cogl_material_set_color (CoglMaterial *material, - const CoglColor *color) -{ - cogl_pipeline_set_color (COGL_PIPELINE (material), color); -} - -void -cogl_material_set_color4ub (CoglMaterial *material, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha) -{ - cogl_pipeline_set_color4ub (COGL_PIPELINE (material), - red, green, blue, alpha); -} - -void -cogl_material_set_color4f (CoglMaterial *material, - float red, - float green, - float blue, - float alpha) -{ - cogl_pipeline_set_color4f (COGL_PIPELINE (material), - red, green, blue, alpha); -} - -void -cogl_material_get_color (CoglMaterial *material, - CoglColor *color) -{ - cogl_pipeline_get_color (COGL_PIPELINE (material), color); -} - -void -cogl_material_set_ambient (CoglMaterial *material, - const CoglColor *ambient) -{ - cogl_pipeline_set_ambient (COGL_PIPELINE (material), ambient); -} - -void -cogl_material_get_ambient (CoglMaterial *material, - CoglColor *ambient) -{ - cogl_pipeline_get_ambient (COGL_PIPELINE (material), ambient); -} - -void -cogl_material_set_diffuse (CoglMaterial *material, - const CoglColor *diffuse) -{ - cogl_pipeline_set_diffuse (COGL_PIPELINE (material), diffuse); -} - -void -cogl_material_get_diffuse (CoglMaterial *material, - CoglColor *diffuse) -{ - cogl_pipeline_get_diffuse (COGL_PIPELINE (material), diffuse); -} - -void -cogl_material_set_ambient_and_diffuse (CoglMaterial *material, - const CoglColor *color) -{ - cogl_pipeline_set_ambient_and_diffuse (COGL_PIPELINE (material), color); - -} - -void -cogl_material_set_specular (CoglMaterial *material, - const CoglColor *specular) -{ - cogl_pipeline_set_specular (COGL_PIPELINE (material), specular); -} - -void -cogl_material_get_specular (CoglMaterial *material, - CoglColor *specular) -{ - cogl_pipeline_get_specular (COGL_PIPELINE (material), specular); -} - -void -cogl_material_set_shininess (CoglMaterial *material, - float shininess) -{ - cogl_pipeline_set_shininess (COGL_PIPELINE (material), shininess); -} - -float -cogl_material_get_shininess (CoglMaterial *material) -{ - return cogl_pipeline_get_shininess (COGL_PIPELINE (material)); -} - -void -cogl_material_set_emission (CoglMaterial *material, - const CoglColor *emission) -{ - cogl_pipeline_set_emission (COGL_PIPELINE (material), emission); - -} - -void -cogl_material_get_emission (CoglMaterial *material, - CoglColor *emission) -{ - cogl_pipeline_get_emission (COGL_PIPELINE (material), emission); - -} - -void -cogl_material_set_alpha_test_function (CoglMaterial *material, - CoglMaterialAlphaFunc alpha_func, - float alpha_reference) -{ - cogl_pipeline_set_alpha_test_function (COGL_PIPELINE (material), - alpha_func, - alpha_reference); -} - -gboolean -cogl_material_set_blend (CoglMaterial *material, - const char *blend_string, - GError **error) -{ - return cogl_pipeline_set_blend (COGL_PIPELINE (material), - blend_string, - error); -} - -void -cogl_material_set_blend_constant (CoglMaterial *material, - const CoglColor *constant_color) -{ - cogl_pipeline_set_blend_constant (COGL_PIPELINE (material), constant_color); -} - -void -cogl_material_set_point_size (CoglMaterial *material, - float point_size) -{ - cogl_pipeline_set_point_size (COGL_PIPELINE (material), point_size); -} - -float -cogl_material_get_point_size (CoglMaterial *material) -{ - return cogl_pipeline_get_point_size (COGL_PIPELINE (material)); -} - -CoglHandle -cogl_material_get_user_program (CoglMaterial *material) -{ - return cogl_pipeline_get_user_program (COGL_PIPELINE (material)); -} - -void -cogl_material_set_user_program (CoglMaterial *material, - CoglHandle program) -{ - cogl_pipeline_set_user_program (COGL_PIPELINE (material), program); -} - -void -cogl_material_set_layer (CoglMaterial *material, - int layer_index, - CoglHandle texture) -{ - cogl_pipeline_set_layer_texture (COGL_PIPELINE (material), - layer_index, texture); -} - -void -cogl_material_remove_layer (CoglMaterial *material, - int layer_index) -{ - cogl_pipeline_remove_layer (COGL_PIPELINE (material), layer_index); -} - -gboolean -cogl_material_set_layer_combine (CoglMaterial *material, - int layer_index, - const char *blend_string, - GError **error) -{ - return cogl_pipeline_set_layer_combine (COGL_PIPELINE (material), - layer_index, - blend_string, - error); -} - -void -cogl_material_set_layer_combine_constant (CoglMaterial *material, - int layer_index, - const CoglColor *constant) -{ - cogl_pipeline_set_layer_combine_constant (COGL_PIPELINE (material), - layer_index, - constant); -} - -void -cogl_material_set_layer_matrix (CoglMaterial *material, - int layer_index, - const CoglMatrix *matrix) -{ - cogl_pipeline_set_layer_matrix (COGL_PIPELINE (material), - layer_index, matrix); -} - -G_CONST_RETURN GList * -cogl_material_get_layers (CoglMaterial *material) -{ - return _cogl_pipeline_get_layers (COGL_PIPELINE (material)); -} - -int -cogl_material_get_n_layers (CoglMaterial *material) -{ - return cogl_pipeline_get_n_layers (COGL_PIPELINE (material)); -} - -CoglMaterialLayerType -cogl_material_layer_get_type (CoglMaterialLayer *layer) -{ - return COGL_MATERIAL_LAYER_TYPE_TEXTURE; -} - -CoglHandle -cogl_material_layer_get_texture (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_texture (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialFilter -cogl_material_layer_get_min_filter (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_min_filter (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialFilter -cogl_material_layer_get_mag_filter (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_mag_filter (COGL_PIPELINE_LAYER (layer)); -} - -void -cogl_material_set_layer_filters (CoglMaterial *material, - int layer_index, - CoglMaterialFilter min_filter, - CoglMaterialFilter mag_filter) -{ - cogl_pipeline_set_layer_filters (COGL_PIPELINE (material), - layer_index, - min_filter, - mag_filter); -} - -gboolean -cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index, - gboolean enable, - GError **error) -{ - CoglPipeline *pipeline = COGL_PIPELINE (material); - return cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline, - layer_index, - enable, - error); -} - -gboolean -cogl_material_get_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index) -{ - CoglPipeline *pipeline = COGL_PIPELINE (material); - return cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline, - layer_index); -} - -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_s (CoglMaterial *material, - int layer_index) -{ - return cogl_pipeline_get_layer_wrap_mode_s (COGL_PIPELINE (material), - layer_index); -} - -void -cogl_material_set_layer_wrap_mode_s (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode_s (COGL_PIPELINE (material), layer_index, - mode); -} - -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_t (CoglMaterial *material, - int layer_index) -{ - return cogl_pipeline_get_layer_wrap_mode_t (COGL_PIPELINE (material), - layer_index); -} - -void -cogl_material_set_layer_wrap_mode_t (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode_t (COGL_PIPELINE (material), layer_index, - mode); -} - -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_p (CoglMaterial *material, - int layer_index) -{ - return cogl_pipeline_get_layer_wrap_mode_p (COGL_PIPELINE (material), - layer_index); -} - -void -cogl_material_set_layer_wrap_mode_p (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode_p (COGL_PIPELINE (material), layer_index, - mode); -} - -void -cogl_material_set_layer_wrap_mode (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode (COGL_PIPELINE (material), layer_index, - mode); -} - -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_s (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_wrap_mode_s (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_t (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_wrap_mode_t (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_wrap_mode_p (COGL_PIPELINE_LAYER (layer)); -} - -void -cogl_material_set_depth_test_enabled (CoglMaterial *material, - gboolean enable) -{ - cogl_pipeline_set_depth_test_enabled (COGL_PIPELINE (material), enable); -} - -gboolean -cogl_material_get_depth_test_enabled (CoglMaterial *material) -{ - return cogl_pipeline_get_depth_test_enabled (COGL_PIPELINE (material)); -} - -void -cogl_material_set_depth_writing_enabled (CoglMaterial *material, - gboolean enable) -{ - cogl_pipeline_set_depth_writing_enabled (COGL_PIPELINE (material), enable); -} - -gboolean -cogl_material_get_depth_writing_enabled (CoglMaterial *material) -{ - return cogl_pipeline_get_depth_writing_enabled (COGL_PIPELINE (material)); -} - -void -cogl_material_set_depth_test_function (CoglMaterial *material, - CoglDepthTestFunction function) -{ - cogl_pipeline_set_depth_test_function (COGL_PIPELINE (material), function); -} - -CoglDepthTestFunction -cogl_material_get_depth_test_function (CoglMaterial *material) -{ - return cogl_pipeline_get_depth_test_function (COGL_PIPELINE (material)); -} - -gboolean -cogl_material_set_depth_range (CoglMaterial *material, - float near_val, - float far_val, - GError **error) -{ - return cogl_pipeline_set_depth_range (COGL_PIPELINE (material), - near_val, far_val, error); -} - -void -cogl_material_get_depth_range (CoglMaterial *material, - float *near_val, - float *far_val) -{ - cogl_pipeline_get_depth_range (COGL_PIPELINE (material), near_val, far_val); -} - -void -cogl_material_foreach_layer (CoglMaterial *material, - CoglMaterialLayerCallback callback, - void *user_data) -{ - cogl_pipeline_foreach_layer (COGL_PIPELINE (material), - (CoglPipelineLayerCallback)callback, user_data); -} - diff --git a/clutter/cogl/cogl/cogl-material-compat.h b/clutter/cogl/cogl/cogl-material-compat.h deleted file mode 100644 index 34c6d29..0000000 --- a/clutter/cogl/cogl/cogl-material-compat.h +++ /dev/null @@ -1,1397 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_MATERIAL_H__ -#define __COGL_MATERIAL_H__ - -G_BEGIN_DECLS - -#include -#include - -/** - * SECTION:cogl-material - * @short_description: Fuctions for creating and manipulating materials - * - * COGL allows creating and manipulating materials used to fill in - * geometry. Materials may simply be lighting attributes (such as an - * ambient and diffuse colour) or might represent one or more textures - * blended together. - */ - -typedef struct _CoglMaterial CoglMaterial; -typedef struct _CoglMaterialLayer CoglMaterialLayer; - -#define COGL_MATERIAL(OBJECT) ((CoglMaterial *)OBJECT) - -/** - * CoglMaterialFilter: - * @COGL_MATERIAL_FILTER_NEAREST: Measuring in manhatten distance from the, - * current pixel center, use the nearest texture texel - * @COGL_MATERIAL_FILTER_LINEAR: Use the weighted average of the 4 texels - * nearest the current pixel center - * @COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_MATERIAL_FILTER_NEAREST criterion - * @COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_MATERIAL_FILTER_LINEAR criterion - * @COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_MATERIAL_FILTER_NEAREST criterion on each one and take - * their weighted average - * @COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_MATERIAL_FILTER_LINEAR criterion on each one and take - * their weighted average - * - * Texture filtering is used whenever the current pixel maps either to more - * than one texture element (texel) or less than one. These filter enums - * correspond to different strategies used to come up with a pixel color, by - * possibly referring to multiple neighbouring texels and taking a weighted - * average or simply using the nearest texel. - */ -typedef enum { - COGL_MATERIAL_FILTER_NEAREST = 0x2600, - COGL_MATERIAL_FILTER_LINEAR = 0x2601, - COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, - COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST = 0x2701, - COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR = 0x2702, - COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR = 0x2703 -} CoglMaterialFilter; -/* NB: these values come from the equivalents in gl.h */ - -/** - * CoglMaterialWrapMode: - * @COGL_MATERIAL_WRAP_MODE_REPEAT: The texture will be repeated. This - * is useful for example to draw a tiled background. - * @COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE: The coordinates outside the - * range 0→1 will sample copies of the edge pixels of the - * texture. This is useful to avoid artifacts if only one copy of - * the texture is being rendered. - * @COGL_MATERIAL_WRAP_MODE_AUTOMATIC: Cogl will try to automatically - * decide which of the above two to use. For cogl_rectangle(), it - * will use repeat mode if any of the texture coordinates are - * outside the range 0→1, otherwise it will use clamp to edge. For - * cogl_polygon() it will always use repeat mode. For - * cogl_vertex_buffer_draw() it will use repeat mode except for - * layers that have point sprite coordinate generation enabled. This - * is the default value. - * - * The wrap mode specifies what happens when texture coordinates - * outside the range 0→1 are used. Note that if the filter mode is - * anything but %COGL_MATERIAL_FILTER_NEAREST then texels outside the - * range 0→1 might be used even when the coordinate is exactly 0 or 1 - * because OpenGL will try to sample neighbouring pixels. For example - * if you are trying to render the full texture then you may get - * artifacts around the edges when the pixels from the other side are - * merged in if the wrap mode is set to repeat. - * - * Since: 1.4 - */ -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes - * - * XXX: keep the values in sync with the CoglMaterialWrapModeInternal - * enum so no conversion is actually needed. - */ -typedef enum { - COGL_MATERIAL_WRAP_MODE_REPEAT = 0x2901, - COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, - COGL_MATERIAL_WRAP_MODE_AUTOMATIC = 0x0207 -} CoglMaterialWrapMode; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_material_new: - * - * Allocates and initializes a blank white material - * - * Return value: a pointer to a new #CoglMaterial - */ -CoglMaterial * -cogl_material_new (void); - -/** - * cogl_material_copy: - * @source: a #CoglMaterial object to copy - * - * Creates a new material with the configuration copied from the - * source material. - * - * We would strongly advise developers to always aim to use - * cogl_material_copy() instead of cogl_material_new() whenever there will - * be any similarity between two materials. Copying a material helps Cogl - * keep track of a materials ancestry which we may use to help minimize GPU - * state changes. - * - * Returns: a pointer to the newly allocated #CoglMaterial - * - * Since: 1.2 - */ -CoglMaterial * -cogl_material_copy (CoglMaterial *source); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_material_ref: - * @material: a #CoglMaterial object. - * - * Increment the reference count for a #CoglMaterial. - * - * Return value: the @material. - * - * Since: 1.0 - * - * Deprecated: 1.2: Use cogl_object_ref() instead - */ -CoglHandle -cogl_material_ref (CoglHandle material) G_GNUC_DEPRECATED; - -/** - * cogl_material_unref: - * @material: a #CoglMaterial object. - * - * Decrement the reference count for a #CoglMaterial. - * - * Since: 1.0 - * - * Deprecated: 1.2: Use cogl_object_unref() instead - */ -void -cogl_material_unref (CoglHandle material) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_is_material: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing material object. - * - * Return value: %TRUE if the handle references a #CoglMaterial, - * %FALSE otherwise - */ -gboolean -cogl_is_material (CoglHandle handle); - -/** - * cogl_material_set_color: - * @material: A #CoglMaterial object - * @color: The components of the color - * - * Sets the basic color of the material, used when no lighting is enabled. - * - * Note that if you don't add any layers to the material then the color - * will be blended unmodified with the destination; the default blend - * expects premultiplied colors: for example, use (0.5, 0.0, 0.0, 0.5) for - * semi-transparent red. See cogl_color_premultiply(). - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 1.0 - */ -void -cogl_material_set_color (CoglMaterial *material, - const CoglColor *color); - -/** - * cogl_material_set_color4ub: - * @material: A #CoglMaterial object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the material, used when no lighting is enabled. - * - * The default value is (0xff, 0xff, 0xff, 0xff) - * - * Since: 1.0 - */ -void -cogl_material_set_color4ub (CoglMaterial *material, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha); - -/** - * cogl_material_set_color4f: - * @material: A #CoglMaterial object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the material, used when no lighting is enabled. - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 1.0 - */ -void -cogl_material_set_color4f (CoglMaterial *material, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_material_get_color: - * @material: A #CoglMaterial object - * @color: (out): The location to store the color - * - * Retrieves the current material color. - * - * Since: 1.0 - */ -void -cogl_material_get_color (CoglMaterial *material, - CoglColor *color); - -/** - * cogl_material_set_ambient: - * @material: A #CoglMaterial object - * @ambient: The components of the desired ambient color - * - * Sets the material's ambient color, in the standard OpenGL lighting - * model. The ambient color affects the overall color of the object. - * - * Since the diffuse color will be intense when the light hits the surface - * directly, the ambient will be most apparent where the light hits at a - * slant. - * - * The default value is (0.2, 0.2, 0.2, 1.0) - * - * Since: 1.0 - */ -void -cogl_material_set_ambient (CoglMaterial *material, - const CoglColor *ambient); - -/** - * cogl_material_get_ambient: - * @material: A #CoglMaterial object - * @ambient: The location to store the ambient color - * - * Retrieves the current ambient color for @material - * - * Since: 1.0 - */ -void -cogl_material_get_ambient (CoglMaterial *material, - CoglColor *ambient); - -/** - * cogl_material_set_diffuse: - * @material: A #CoglMaterial object - * @diffuse: The components of the desired diffuse color - * - * Sets the material's diffuse color, in the standard OpenGL lighting - * model. The diffuse color is most intense where the light hits the - * surface directly - perpendicular to the surface. - * - * The default value is (0.8, 0.8, 0.8, 1.0) - * - * Since: 1.0 - */ -void -cogl_material_set_diffuse (CoglMaterial *material, - const CoglColor *diffuse); - -/** - * cogl_material_get_diffuse: - * @material: A #CoglMaterial object - * @diffuse: The location to store the diffuse color - * - * Retrieves the current diffuse color for @material - * - * Since: 1.0 - */ -void -cogl_material_get_diffuse (CoglMaterial *material, - CoglColor *diffuse); - -/** - * cogl_material_set_ambient_and_diffuse: - * @material: A #CoglMaterial object - * @color: The components of the desired ambient and diffuse colors - * - * Conveniently sets the diffuse and ambient color of @material at the same - * time. See cogl_material_set_ambient() and cogl_material_set_diffuse(). - * - * The default ambient color is (0.2, 0.2, 0.2, 1.0) - * - * The default diffuse color is (0.8, 0.8, 0.8, 1.0) - * - * Since: 1.0 - */ -void -cogl_material_set_ambient_and_diffuse (CoglMaterial *material, - const CoglColor *color); - -/** - * cogl_material_set_specular: - * @material: A #CoglMaterial object - * @specular: The components of the desired specular color - * - * Sets the material's specular color, in the standard OpenGL lighting - * model. The intensity of the specular color depends on the viewport - * position, and is brightest along the lines of reflection. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 1.0 - */ -void -cogl_material_set_specular (CoglMaterial *material, - const CoglColor *specular); - -/** - * cogl_material_get_specular: - * @material: A #CoglMaterial object - * @specular: The location to store the specular color - * - * Retrieves the materials current specular color. - * - * Since: 1.0 - */ -void -cogl_material_get_specular (CoglMaterial *material, - CoglColor *specular); - -/** - * cogl_material_set_shininess: - * @material: A #CoglMaterial object - * @shininess: The desired shininess; must be >= 0.0 - * - * Sets the shininess of the material, in the standard OpenGL lighting - * model, which determines the size of the specular highlights. A - * higher @shininess will produce smaller highlights which makes the - * object appear more shiny. - * - * The default value is 0.0 - * - * Since: 1.0 - */ -void -cogl_material_set_shininess (CoglMaterial *material, - float shininess); - -/** - * cogl_material_get_shininess: - * @material: A #CoglMaterial object - * - * Retrieves the materials current emission color. - * - * Return value: The materials current shininess value - * - * Since: 1.0 - */ -float -cogl_material_get_shininess (CoglMaterial *material); - -/** - * cogl_material_set_emission: - * @material: A #CoglMaterial object - * @emission: The components of the desired emissive color - * - * Sets the material's emissive color, in the standard OpenGL lighting - * model. It will look like the surface is a light source emitting this - * color. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 1.0 - */ -void -cogl_material_set_emission (CoglMaterial *material, - const CoglColor *emission); - -/** - * cogl_material_get_emission: - * @material: A #CoglMaterial object - * @emission: The location to store the emission color - * - * Retrieves the materials current emission color. - * - * Since: 1.0 - */ -void -cogl_material_get_emission (CoglMaterial *material, - CoglColor *emission); - -/** - * CoglMaterialAlphaFunc: - * @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through. - * @COGL_MATERIAL_ALPHA_FUNC_LESS: Let the fragment through if the incoming - * alpha value is less than the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_EQUAL: Let the fragment through if the incoming - * alpha value equals the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_LEQUAL: Let the fragment through if the incoming - * alpha value is less than or equal to the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_GREATER: Let the fragment through if the incoming - * alpha value is greater than the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL: Let the fragment through if the incoming - * alpha value does not equal the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_GEQUAL: Let the fragment through if the incoming - * alpha value is greater than or equal to the reference alpha value. - * @COGL_MATERIAL_ALPHA_FUNC_ALWAYS: Always let the fragment through. - * - * Alpha testing happens before blending primitives with the framebuffer and - * gives an opportunity to discard fragments based on a comparison with the - * incoming alpha value and a reference alpha value. The #CoglMaterialAlphaFunc - * determines how the comparison is done. - */ -typedef enum { - COGL_MATERIAL_ALPHA_FUNC_NEVER = 0x0200, - COGL_MATERIAL_ALPHA_FUNC_LESS = 0x0201, - COGL_MATERIAL_ALPHA_FUNC_EQUAL = 0x0202, - COGL_MATERIAL_ALPHA_FUNC_LEQUAL = 0x0203, - COGL_MATERIAL_ALPHA_FUNC_GREATER = 0x0204, - COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL = 0x0205, - COGL_MATERIAL_ALPHA_FUNC_GEQUAL = 0x0206, - COGL_MATERIAL_ALPHA_FUNC_ALWAYS = 0x0207 -} CoglMaterialAlphaFunc; - -/** - * cogl_material_set_alpha_test_function: - * @material: A #CoglMaterial object - * @alpha_func: A @CoglMaterialAlphaFunc constant - * @alpha_reference: A reference point that the chosen alpha function uses - * to compare incoming fragments to. - * - * Before a primitive is blended with the framebuffer, it goes through an - * alpha test stage which lets you discard fragments based on the current - * alpha value. This function lets you change the function used to evaluate - * the alpha channel, and thus determine which fragments are discarded - * and which continue on to the blending stage. - * - * The default is %COGL_MATERIAL_ALPHA_FUNC_ALWAYS - * - * Since: 1.0 - */ -void -cogl_material_set_alpha_test_function (CoglMaterial *material, - CoglMaterialAlphaFunc alpha_func, - float alpha_reference); - -/** - * cogl_material_set_blend: - * @material: A #CoglMaterial object - * @blend_string: A Cogl blend string - * describing the desired blend function. - * @error: return location for a #GError that may report lack of driver - * support if you give separate blend string statements for the alpha - * channel and RGB channels since some drivers, or backends such as - * GLES 1.1, don't support this feature. May be %NULL, in which case a - * warning will be printed out using GLib's logging facilities if an - * error is encountered. - * - * If not already familiar; please refer here - * for an overview of what blend strings are, and their syntax. - * - * Blending occurs after the alpha test function, and combines fragments with - * the framebuffer. - - * Currently the only blend function Cogl exposes is ADD(). So any valid - * blend statements will be of the form: - * - * |[ - * <channel-mask>=ADD(SRC_COLOR*(<factor>), DST_COLOR*(<factor>)) - * ]| - * - * The brackets around blend factors are currently not - * optional! - * - * This is the list of source-names usable as blend factors: - * - * SRC_COLOR: The color of the in comming fragment - * DST_COLOR: The color of the framebuffer - * CONSTANT: The constant set via cogl_material_set_blend_constant() - * - * - * The source names can be used according to the - * color-source and factor syntax, - * so for example "(1-SRC_COLOR[A])" would be a valid factor, as would - * "(CONSTANT[RGB])" - * - * These can also be used as factors: - * - * 0: (0, 0, 0, 0) - * 1: (1, 1, 1, 1) - * SRC_ALPHA_SATURATE_FACTOR: (f,f,f,1) where f = MIN(SRC_COLOR[A],1-DST_COLOR[A]) - * - * - * Remember; all color components are normalized to the range [0, 1] - * before computing the result of blending. - * - * - * Blend Strings/1 - * Blend a non-premultiplied source over a destination with - * premultiplied alpha: - * - * "RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))" - * "A = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * - * - * - * - * Blend Strings/2 - * Blend a premultiplied source over a destination with - * premultiplied alpha - * - * "RGBA = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * - * - * - * The default blend string is: - * |[ - * RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A])) - * ]| - * - * That gives normal alpha-blending when the calculated color for the material - * is in premultiplied form. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described blending is supported by the underlying driver/hardware. If - * there was an error, %FALSE is returned and @error is set accordingly (if - * present). - * - * Since: 1.0 - */ -gboolean -cogl_material_set_blend (CoglMaterial *material, - const char *blend_string, - GError **error); - -/** - * cogl_material_set_blend_constant: - * @material: A #CoglMaterial object - * @constant_color: The constant color you want - * - * When blending is setup to reference a CONSTANT blend factor then - * blending will depend on the constant set with this function. - * - * Since: 1.0 - */ -void -cogl_material_set_blend_constant (CoglMaterial *material, - const CoglColor *constant_color); - -/** - * cogl_material_set_point_size: - * @material: a material. - * @point_size: the new point size. - * - * Changes the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. Note that typically the GPU will - * only support a limited minimum and maximum range of point sizes. If - * the chosen point size is outside that range then the nearest value - * within that range will be used instead. The size of a point is in - * screen space so it will be the same regardless of any - * transformations. The default point size is 1.0. - * - * Since: 1.4 - */ -void -cogl_material_set_point_size (CoglMaterial *material, - float point_size); - -/** - * cogl_material_get_point_size: - * @material: a #CoglHandle to a material. - * - * Get the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. - * - * Return value: the point size of the material. - * - * Since: 1.4 - */ -float -cogl_material_get_point_size (CoglMaterial *material); - -/** - * cogl_material_get_user_program: - * @material: a #CoglMaterial object. - * - * Queries what user program has been associated with the given - * @material using cogl_material_set_user_program(). - * - * Return value: (transfer none): The current user program - * or %COGL_INVALID_HANDLE. - * - * Since: 1.4 - */ -CoglHandle -cogl_material_get_user_program (CoglMaterial *material); - -/** - * cogl_material_set_user_program: - * @material: a #CoglMaterial object. - * @program: A #CoglHandle to a linked CoglProgram - * - * Associates a linked CoglProgram with the given material so that the - * program can take full control of vertex and/or fragment processing. - * - * This is an example of how it can be used to associate an ARBfp - * program with a #CoglMaterial: - * |[ - * CoglHandle shader; - * CoglHandle program; - * CoglMaterial *material; - * - * shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - * cogl_shader_source (shader, - * "!!ARBfp1.0\n" - * "MOV result.color,fragment.color;\n" - * "END\n"); - * cogl_shader_compile (shader); - * - * program = cogl_create_program (); - * cogl_program_attach_shader (program, shader); - * cogl_program_link (program); - * - * material = cogl_material_new (); - * cogl_material_set_user_program (material, program); - * - * cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - * cogl_rectangle (0, 0, 100, 100); - * ]| - * - * It is possibly worth keeping in mind that this API is not part of - * the long term design for how we want to expose shaders to Cogl - * developers (We are planning on deprecating the cogl_program and - * cogl_shader APIs in favour of a "snippet" framework) but in the - * meantime we hope this will handle most practical GLSL and ARBfp - * requirements. - * - * Also remember you need to check for either the - * %COGL_FEATURE_SHADERS_GLSL or %COGL_FEATURE_SHADERS_ARBFP before - * using the cogl_program or cogl_shader API. - * - * Since: 1.4 - */ -void -cogl_material_set_user_program (CoglMaterial *material, - CoglHandle program); - -/** - * cogl_material_set_layer: - * @material: A #CoglMaterial object - * @layer_index: the index of the layer - * @texture: a #CoglHandle for the layer object - * - * In addition to the standard OpenGL lighting model a Cogl material may have - * one or more layers comprised of textures that can be blended together in - * order, with a number of different texture combine modes. This function - * defines a new texture layer. - * - * The index values of multiple layers do not have to be consecutive; it is - * only their relative order that is important. - * - * In the future, we may define other types of material layers, such - * as purely GLSL based layers. - * - * Since: 1.0 - */ -void -cogl_material_set_layer (CoglMaterial *material, - int layer_index, - CoglHandle texture); - -/** - * cogl_material_remove_layer: - * @material: A #CoglMaterial object - * @layer_index: Specifies the layer you want to remove - * - * This function removes a layer from your material - */ -void -cogl_material_remove_layer (CoglMaterial *material, - int layer_index); - - -/** - * cogl_material_set_layer_combine: - * @material: A #CoglMaterial object - * @layer_index: Specifies the layer you want define a combine function for - * @blend_string: A Cogl blend string - * describing the desired texture combine function. - * @error: A #GError that may report parse errors or lack of GPU/driver - * support. May be %NULL, in which case a warning will be printed out if an - * error is encountered. - * - * If not already familiar; you can refer - * here for an overview of what blend - * strings are and there syntax. - * - * These are all the functions available for texture combining: - * - * REPLACE(arg0) = arg0 - * MODULATE(arg0, arg1) = arg0 x arg1 - * ADD(arg0, arg1) = arg0 + arg1 - * ADD_SIGNED(arg0, arg1) = arg0 + arg1 - 0.5 - * INTERPOLATE(arg0, arg1, arg2) = arg0 x arg2 + arg1 x (1 - arg2) - * SUBTRACT(arg0, arg1) = arg0 - arg1 - * - * - * DOT3_RGB(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * - * - * - * - * DOT3_RGBA(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * - * - * - * - * Refer to the - * color-source syntax for - * describing the arguments. The valid source names for texture combining - * are: - * - * - * TEXTURE - * Use the color from the current texture layer - * - * - * TEXTURE_0, TEXTURE_1, etc - * Use the color from the specified texture layer - * - * - * CONSTANT - * Use the color from the constant given with - * cogl_material_set_layer_constant() - * - * - * PRIMARY - * Use the color of the material as set with - * cogl_material_set_color() - * - * - * PREVIOUS - * Either use the texture color from the previous layer, or - * if this is layer 0, use the color of the material as set with - * cogl_material_set_color() - * - * - * - * - * Layer Combine Examples - * This is effectively what the default blending is: - * - * RGBA = MODULATE (PREVIOUS, TEXTURE) - * - * This could be used to cross-fade between two images, using - * the alpha component of a constant as the interpolator. The constant - * color is given by calling cogl_material_set_layer_constant. - * - * RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A]) - * - * - * - * You can't give a multiplication factor for arguments as you can - * with blending. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described texture combining is supported by the underlying driver and - * or hardware. On failure, %FALSE is returned and @error is set - * - * Since: 1.0 - */ -gboolean -cogl_material_set_layer_combine (CoglMaterial *material, - int layer_index, - const char *blend_string, - GError **error); - -/** - * cogl_material_set_layer_combine_constant: - * @material: A #CoglMaterial object - * @layer_index: Specifies the layer you want to specify a constant used - * for texture combining - * @constant: The constant color you want - * - * When you are using the 'CONSTANT' color source in a layer combine - * description then you can use this function to define its value. - * - * Since: 1.0 - */ -void -cogl_material_set_layer_combine_constant (CoglMaterial *material, - int layer_index, - const CoglColor *constant); - -/** - * cogl_material_set_layer_matrix: - * @material: A #CoglMaterial object - * @layer_index: the index for the layer inside @material - * @matrix: the transformation matrix for the layer - * - * This function lets you set a matrix that can be used to e.g. translate - * and rotate a single layer of a material used to fill your geometry. - */ -void -cogl_material_set_layer_matrix (CoglMaterial *material, - int layer_index, - const CoglMatrix *matrix); - -/** - * cogl_material_get_layers: - * @material: A #CoglMaterial object - * - * This function lets you access a material's internal list of layers - * for iteration. - * - * You should avoid using this API if possible since it was only - * made public by mistake and will be deprecated when we have - * suitable alternative. - * - * It's important to understand that the list returned may not - * remain valid if you modify the material or any of the layers in any - * way and so you would have to re-get the list in that - * situation. - * - * Return value: (element-type CoglMaterialLayer) (transfer none): A - * list of #CoglMaterialLayer's that can be passed to the - * cogl_material_layer_* functions. The list is owned by Cogl and it - * should not be modified or freed - */ -G_CONST_RETURN GList * -cogl_material_get_layers (CoglMaterial *material); - -/** - * cogl_material_get_n_layers: - * @material: A #CoglMaterial object - * - * Retrieves the number of layers defined for the given @material - * - * Return value: the number of layers - * - * Since: 1.0 - */ -int -cogl_material_get_n_layers (CoglMaterial *material); - -/** - * CoglMaterialLayerType: - * @COGL_MATERIAL_LAYER_TYPE_TEXTURE: The layer represents a - * texture - * - * Available types of layers for a #CoglMaterial. This enumeration - * might be expanded in later versions. - * - * Since: 1.0 - */ -typedef enum { - COGL_MATERIAL_LAYER_TYPE_TEXTURE -} CoglMaterialLayerType; - - -/** - * cogl_material_layer_get_type: - * @layer: A #CoglMaterialLayer object - * - * Retrieves the type of the layer - * - * Currently there is only one type of layer defined: - * %COGL_MATERIAL_LAYER_TYPE_TEXTURE, but considering we may add purely GLSL - * based layers in the future, you should write code that checks the type - * first. - * - * Return value: the type of the layer - */ -CoglMaterialLayerType -cogl_material_layer_get_type (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_texture: - * @layer: A #CoglMaterialLayer object - * - * Extracts a texture handle for a specific layer. - * - * In the future Cogl may support purely GLSL based layers; for those - * layers this function which will likely return %COGL_INVALID_HANDLE if you - * try to get the texture handle from them. Considering this scenario, you - * should call cogl_material_layer_get_type() first in order check it is of - * type %COGL_MATERIAL_LAYER_TYPE_TEXTURE before calling this function. - * - * Return value: (transfer none): a #CoglHandle for the texture inside the layer - */ -CoglHandle -cogl_material_layer_get_texture (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_min_filter: - * @layer: a #CoglHandle for a material layer - * - * Queries the currently set downscaling filter for a material layer - * - * Return value: the current downscaling filter - */ -CoglMaterialFilter -cogl_material_layer_get_min_filter (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_mag_filter: - * @layer: A #CoglMaterialLayer object - * - * Queries the currently set downscaling filter for a material later - * - * Return value: the current downscaling filter - */ -CoglMaterialFilter -cogl_material_layer_get_mag_filter (CoglMaterialLayer *layer); - -/** - * cogl_material_set_layer_filters: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @min_filter: the filter used when scaling a texture down. - * @mag_filter: the filter used when magnifying a texture. - * - * Changes the decimation and interpolation filters used when a texture is - * drawn at other scales than 100%. - */ -void -cogl_material_set_layer_filters (CoglMaterial *material, - int layer_index, - CoglMaterialFilter min_filter, - CoglMaterialFilter mag_filter); - -/** - * cogl_material_set_layer_point_sprite_coords_enabled: - * @material: a #CoglHandle to a material. - * @layer_index: the layer number to change. - * @enable: whether to enable point sprite coord generation. - * @error: A return location for a GError, or NULL to ignore errors. - * - * When rendering points, if @enable is %TRUE then the texture - * coordinates for this layer will be replaced with coordinates that - * vary from 0.0 to 1.0 across the primitive. The top left of the - * point will have the coordinates 0.0,0.0 and the bottom right will - * have 1.0,1.0. If @enable is %FALSE then the coordinates will be - * fixed for the entire point. - * - * This function will only work if %COGL_FEATURE_POINT_SPRITE is - * available. If the feature is not available then the function will - * return %FALSE and set @error. - * - * Return value: %TRUE if the function succeeds, %FALSE otherwise. - * Since: 1.4 - */ -gboolean -cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index, - gboolean enable, - GError **error); - -/** - * cogl_material_get_layer_point_sprite_coords_enabled: - * @material: a #CoglHandle to a material. - * @layer_index: the layer number to check. - * - * Gets whether point sprite coordinate generation is enabled for this - * texture layer. - * - * Return value: whether the texture coordinates will be replaced with - * point sprite coordinates. - * - * Since: 1.4 - */ -gboolean -cogl_material_get_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index); - -/** - * cogl_material_get_layer_wrap_mode_s: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 's' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 's' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - */ -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_s (CoglMaterial *material, - int layer_index); - -/** - * cogl_material_set_layer_wrap_mode_s: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 's' coordinate of texture lookups on this layer. - * - * Since: 1.4 - */ -void -cogl_material_set_layer_wrap_mode_s (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_get_layer_wrap_mode_t: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 't' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 't' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - */ -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_t (CoglMaterial *material, - int layer_index); - - -/** - * cogl_material_set_layer_wrap_mode_t: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 't' coordinate of texture lookups on this layer. - * - * Since: 1.4 - */ -void -cogl_material_set_layer_wrap_mode_t (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_get_layer_wrap_mode_p: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 'p' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 'p' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - */ -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_p (CoglMaterial *material, - int layer_index); - -/** - * cogl_material_set_layer_wrap_mode_p: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 'p' coordinate of texture lookups on - * this layer. 'p' is the third coordinate. - * - * Since: 1.4 - */ -void -cogl_material_set_layer_wrap_mode_p (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_set_layer_wrap_mode: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for all three coordinates of texture lookups on - * this layer. This is equivalent to calling - * cogl_material_set_layer_wrap_mode_s(), - * cogl_material_set_layer_wrap_mode_t() and - * cogl_material_set_layer_wrap_mode_p() separately. - * - * Since: 1.4 - */ -void -cogl_material_set_layer_wrap_mode (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_layer_get_wrap_mode_s: - * @layer: A #CoglMaterialLayer object - * - * Gets the wrap mode for the 's' coordinate of texture lookups on this layer. - * - * Return value: the wrap mode value for the s coordinate. - * - * Since: 1.4 - */ -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_s (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_wrap_mode_t: - * @layer: A #CoglMaterialLayer object - * - * Gets the wrap mode for the 't' coordinate of texture lookups on this layer. - * - * Return value: the wrap mode value for the t coordinate. - * - * Since: 1.4 - */ -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_t (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_wrap_mode_p: - * @layer: A #CoglMaterialLayer object - * - * Gets the wrap mode for the 'p' coordinate of texture lookups on - * this layer. 'p' is the third coordinate. - * - * Return value: the wrap mode value for the p coordinate. - * - * Since: 1.4 - */ -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer); - -#ifdef COGL_ENABLE_EXPERIMENTAL_API - -/** - * cogl_material_set_depth_test_enabled: - * @material: A #CoglMaterial object - * @enable: The enable state you want - * - * Enables or disables depth testing according to the value of - * @enable. - * - * If depth testing is enable then the #CoglDepthTestFunction set - * using cogl_material_set_depth_test_function() us used to evaluate - * the depth value of incoming fragments against the corresponding - * value stored in the current depth buffer, and if the test passes - * then the fragments depth value is used to update the depth buffer. - * (unless you have disabled depth writing via - * cogl_material_set_depth_writing_enabled ()) - * - * By default depth testing is disabled. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_material_set_depth_test_enabled (CoglMaterial *material, - gboolean enable); - -/** - * cogl_material_get_depth_test_enabled: - * @material: A #CoglMaterial object - * - * Gets the current depth test enabled state as previously set by - * cogl_material_set_depth_test_enabled(). - * - * Returns: The material's current depth test enabled state. - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_material_get_depth_test_enabled (CoglMaterial *material); - -/** - * cogl_material_set_depth_writing_enabled: - * @material: A #CoglMaterial object - * @enable: The enable state you want - * - * Enables or disables depth buffer writing according to the value of - * @enable. Normally when depth testing is enabled and the comparison - * between a fragment's depth value and the corresponding depth buffer - * value passes then the fragment's depth is written to the depth - * buffer unless writing is disabled here. - * - * By default depth writing is enabled - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_material_set_depth_writing_enabled (CoglMaterial *material, - gboolean enable); - -/** - * cogl_material_get_depth_writing_enabled: - * @material: A #CoglMaterial object - * - * Gets the depth writing enable state as set by the corresponding - * cogl_material_set_depth_writing_enabled. - * - * Returns: The current depth writing enable state - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_material_get_depth_writing_enabled (CoglMaterial *material); - -/** - * cogl_material_set_depth_test_function: - * @material: A #CoglMaterial object - * @function: The #CoglDepthTestFunction to set - * - * Sets the #CoglDepthTestFunction used to compare the depth value of - * an incoming fragment against the corresponding value in the current - * depth buffer. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_material_set_depth_test_function (CoglMaterial *material, - CoglDepthTestFunction function); - -/** - * cogl_material_get_depth_test_function: - * @material: A #CoglMaterial object - * - * Gets the current depth test enable state as previously set via - * cogl_material_set_depth_test_enabled(). - * - * Returns: The current depth test enable state. - * Since: 1.4 - * Stability: Unstable - */ -CoglDepthTestFunction -cogl_material_get_depth_test_function (CoglMaterial *material); - -/** - * cogl_material_set_depth_range: - * @material: A #CoglMaterial object - * @near_val: The near component of the desired depth range which will be - * clamped to the range [0, 1] - * @far_val: The far component of the desired depth range which will be - * clamped to the range [0, 1] - * @error: location to store an error of type #CoglError - * - * Sets the range to map depth values in normalized device coordinates - * to before writing out to a depth buffer. - * - * After your geometry has be transformed, clipped and had perspective - * division applied placing it in normalized device - * coordinates all depth values between the near and far z clipping - * planes are in the range -1 to 1. Before writing any depth value to - * the depth buffer though the value is mapped into the range [0, 1]. - * - * With this function you can change the range which depth values are - * mapped too although the range must still lye within the range [0, - * 1]. - * - * If your driver does not support this feature (for example you are - * using GLES 1 drivers) then this will return %FALSE and set an error - * if @error isn't NULL. You can check ahead of time for the - * %COGL_FEATURE_DEPTH_RANGE feature with cogl_features_available() to - * know if this function will succeed. - * - * By default normalized device coordinate depth values are mapped to - * the full range of depth buffer values, [0, 1]. - * - * Returns: %TRUE if driver support is available else %FALSE. - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_material_set_depth_range (CoglMaterial *material, - float near_val, - float far_val, - GError **error); - -/** - * cogl_material_get_depth_range_mapping: - * @material: A #CoglMaterial object - * @near_val: A pointer to store the near component of the depth range - * @far_val: A pointer to store the far component of the depth range - * - * Gets the current range to which normalized depth values are mapped - * before writing to the depth buffer. This corresponds to the range - * set with cogl_material_set_depth_range(). - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_material_get_depth_range (CoglMaterial *material, - float *near_val, - float *far_val); - -/** - * CoglMaterialLayerCallback: - * @material: The #CoglMaterial whos layers are being iterated - * @layer_index: The current layer index - * @user_data: The private data passed to cogl_material_foreach_layer() - * - * The callback prototype used with cogl_material_foreach_layer() for - * iterating all the layers of a @material. - * - * Since: 1.4 - * Stability: Unstable - */ -typedef gboolean (*CoglMaterialLayerCallback) (CoglMaterial *material, - int layer_index, - void *user_data); - -/** - * cogl_material_foreach_layer: - * @material: A #CoglMaterial object - * @callback: A #CoglMaterialLayerCallback to be called for each layer - * index - * @user_data: Private data that will be passed to the callback - * - * Iterates all the layer indices of the given @material. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_material_foreach_layer (CoglMaterial *material, - CoglMaterialLayerCallback callback, - void *user_data); - -#endif /* COGL_ENABLE_EXPERIMENTAL_API */ - -G_END_DECLS - -#endif /* __COGL_MATERIAL_H__ */ diff --git a/clutter/cogl/cogl/cogl-matrix-mesa.c b/clutter/cogl/cogl/cogl-matrix-mesa.c deleted file mode 100644 index 0356a11..0000000 --- a/clutter/cogl/cogl/cogl-matrix-mesa.c +++ /dev/null @@ -1,1700 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ -/* - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/* - * file: cogl-matrix-mesa.c - * Matrix operations. - * - * note - * -# 4x4 transformation matrices are stored in memory in column major order. - * -# Points/vertices are to be thought of as column vectors. - * -# Transformation of a point p by a matrix M is: p' = M * p - */ - -/* - * Changes compared to the original code from Mesa: - * - * - instead of allocating matrix->m and matrix->inv using malloc, our - * public CoglMatrix typedef is large enough to directly contain the - * matrix, its inverse, a type and a set of flags. - * - instead of having a _math_matrix_analyse which updates the type, - * flags and inverse, we have _math_matrix_update_inverse which - * essentially does the same thing (internally making use of - * _math_matrix_update_type_and_flags()) but with additional guards in - * place to bail out when the inverse matrix is still valid. - * - when initializing a matrix with the identity matrix we don't - * immediately initialize the inverse matrix; rather we just set the - * dirty flag for the inverse (since it's likely the user won't request - * the inverse of the identity matrix) - */ - -#include "cogl-matrix-mesa.h" - -#include -#include - - -#define DEG2RAD (G_PI/180.0) - -/* Dot product of two 2-element vectors */ -#define DOT2(A,B) ( (A)[0]*(B)[0] + (A)[1]*(B)[1] ) - -/* Dot product of two 3-element vectors */ -#define DOT3(A,B) ( (A)[0]*(B)[0] + (A)[1]*(B)[1] + (A)[2]*(B)[2] ) - -#define CROSS3(N, U, V) \ -do { \ - (N)[0] = (U)[1]*(V)[2] - (U)[2]*(V)[1]; \ - (N)[1] = (U)[2]*(V)[0] - (U)[0]*(V)[2]; \ - (N)[2] = (U)[0]*(V)[1] - (U)[1]*(V)[0]; \ -} while (0) - -#define SUB_3V(DST, SRCA, SRCB) \ -do { \ - (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ - (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ - (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ -} while (0) - -#define LEN_SQUARED_3FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2]) - -/* - * \defgroup MatFlags MAT_FLAG_XXX-flags - * - * Bitmasks to indicate different kinds of 4x4 matrices in CoglMatrix::flags - */ -/*@{*/ -#define MAT_FLAG_IDENTITY 0 /*< is an identity matrix flag. - * (Not actually used - the identity - * matrix is identified by the absense - * of all other flags.) - */ -#define MAT_FLAG_GENERAL 0x1 /*< is a general matrix flag */ -#define MAT_FLAG_ROTATION 0x2 /*< is a rotation matrix flag */ -#define MAT_FLAG_TRANSLATION 0x4 /*< is a translation matrix flag */ -#define MAT_FLAG_UNIFORM_SCALE 0x8 /*< is an uniform scaling matrix flag */ -#define MAT_FLAG_GENERAL_SCALE 0x10 /*< is a general scaling matrix flag */ -#define MAT_FLAG_GENERAL_3D 0x20 /*< general 3D matrix flag */ -#define MAT_FLAG_PERSPECTIVE 0x40 /*< is a perspective proj matrix flag */ -#define MAT_FLAG_SINGULAR 0x80 /*< is a singular matrix flag */ -#define MAT_DIRTY_TYPE 0x100 /*< matrix type is dirty */ -#define MAT_DIRTY_FLAGS 0x200 /*< matrix flags are dirty */ -#define MAT_DIRTY_INVERSE 0x400 /*< matrix inverse is dirty */ - -/* angle preserving matrix flags mask */ -#define MAT_FLAGS_ANGLE_PRESERVING (MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION | \ - MAT_FLAG_UNIFORM_SCALE) - -/* geometry related matrix flags mask */ -#define MAT_FLAGS_GEOMETRY (MAT_FLAG_GENERAL | \ - MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION | \ - MAT_FLAG_UNIFORM_SCALE | \ - MAT_FLAG_GENERAL_SCALE | \ - MAT_FLAG_GENERAL_3D | \ - MAT_FLAG_PERSPECTIVE | \ - MAT_FLAG_SINGULAR) - -/* length preserving matrix flags mask */ -#define MAT_FLAGS_LENGTH_PRESERVING (MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION) - - -/* 3D (non-perspective) matrix flags mask */ -#define MAT_FLAGS_3D (MAT_FLAG_ROTATION | \ - MAT_FLAG_TRANSLATION | \ - MAT_FLAG_UNIFORM_SCALE | \ - MAT_FLAG_GENERAL_SCALE | \ - MAT_FLAG_GENERAL_3D) - -/* dirty matrix flags mask */ -#define MAT_DIRTY_ALL (MAT_DIRTY_TYPE | \ - MAT_DIRTY_FLAGS | \ - MAT_DIRTY_INVERSE) - -/*@}*/ - - -/* - * Test geometry related matrix flags. - * - * \param mat a pointer to a CoglMatrix structure. - * \param a flags mask. - * - * \returns non-zero if all geometry related matrix flags are contained within - * the mask, or zero otherwise. - */ -#define TEST_MAT_FLAGS(mat, a) \ - ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0) - - - -/* - * Names of the corresponding CoglMatrixType values. - */ -static const char *types[] = { - "COGL_MATRIX_TYPE_GENERAL", - "COGL_MATRIX_TYPE_IDENTITY", - "COGL_MATRIX_TYPE_3D_NO_ROT", - "COGL_MATRIX_TYPE_PERSPECTIVE", - "COGL_MATRIX_TYPE_2D", - "COGL_MATRIX_TYPE_2D_NO_ROT", - "COGL_MATRIX_TYPE_3D" -}; - - -/* - * Identity matrix. - */ -static float identity[16] = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 -}; - - - -/**********************************************************************/ -/* \name Matrix multiplication */ -/*@{*/ - -#define A(row,col) a[(col<<2)+row] -#define B(row,col) b[(col<<2)+row] -#define R(row,col) result[(col<<2)+row] - -/* - * Perform a full 4x4 matrix multiplication. - * - * \param a matrix. - * \param b matrix. - * \param product will receive the product of \p a and \p b. - * - * \warning Is assumed that \p product != \p b. \p product == \p a is allowed. - * - * \note KW: 4*16 = 64 multiplications - * - * \author This \c matmul was contributed by Thomas Malik - */ -static void -matrix_multiply4x4 (float *result, const float *a, const float *b) -{ - int i; - for (i = 0; i < 4; i++) - { - const float ai0 = A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); - R(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); - R(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); - R(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); - R(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); - } -} - -/* - * Multiply two matrices known to occupy only the top three rows, such - * as typical model matrices, and orthogonal matrices. - * - * \param a matrix. - * \param b matrix. - * \param product will receive the product of \p a and \p b. - */ -static void -matrix_multiply3x4 (float *result, const float *a, const float *b) -{ - int i; - for (i = 0; i < 3; i++) - { - const float ai0 = A(i,0), ai1 = A(i,1), ai2 = A(i,2), ai3 = A(i,3); - R(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0); - R(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1); - R(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2); - R(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3; - } - R(3,0) = 0; - R(3,1) = 0; - R(3,2) = 0; - R(3,3) = 1; -} - -#undef A -#undef B -#undef R - -/* - * Multiply a matrix by an array of floats with known properties. - * - * \param mat pointer to a CoglMatrix structure containing the left multiplication - * matrix, and that will receive the product result. - * \param m right multiplication matrix array. - * \param flags flags of the matrix \p m. - * - * Joins both flags and marks the type and inverse as dirty. Calls - * matrix_multiply3x4() if both matrices are 3D, or matrix_multiply4x4() - * otherwise. - */ -static void -matrix_multiply_array_with_flags (CoglMatrix *result, - const float *array, - unsigned int flags) -{ - result->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); - - if (TEST_MAT_FLAGS (result, MAT_FLAGS_3D)) - matrix_multiply3x4 ((float *)result, (float *)result, array); - else - matrix_multiply4x4 ((float *)result, (float *)result, array); -} - -/* - * Matrix multiplication. - * - * \param dest destination matrix. - * \param a left matrix. - * \param b right matrix. - * - * Joins both flags and marks the type and inverse as dirty. Calls - * matrix_multiply3x4() if both matrices are 3D, or matrix_multiply4x4() - * otherwise. - */ -void -_math_matrix_multiply (CoglMatrix *result, - const CoglMatrix *a, - const CoglMatrix *b) -{ - result->flags = (a->flags | - b->flags | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE); - - if (TEST_MAT_FLAGS(result, MAT_FLAGS_3D)) - matrix_multiply3x4 ((float *)result, (float *)a, (float *)b); - else - matrix_multiply4x4 ((float *)result, (float *)a, (float *)b); -} - -/* - * Matrix multiplication. - * - * \param dest left and destination matrix. - * \param m right matrix array. - * - * Marks the matrix flags with general flag, and type and inverse dirty flags. - * Calls matrix_multiply4x4() for the multiplication. - */ -void -_math_matrix_multiply_array (CoglMatrix *result, const float *array) -{ - result->flags |= (MAT_FLAG_GENERAL | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE | - MAT_DIRTY_FLAGS); - - matrix_multiply4x4 ((float *)result, (float *)result, (float *)array); -} - -/*@}*/ - - -/**********************************************************************/ -/* \name Matrix output */ -/*@{*/ - -/* - * Print a matrix array. - * - * \param m matrix array. - * - * Called by _math_matrix_print() to print a matrix or its inverse. - */ -static void -print_matrix_floats (const float m[16]) -{ - int i; - for (i = 0;i < 4; i++) - g_print ("\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] ); -} - -/* - * Dumps the contents of a CoglMatrix structure. - * - * \param m pointer to the CoglMatrix structure. - */ -void -_math_matrix_print (const CoglMatrix *matrix) -{ - g_print ("Matrix type: %s, flags: %x\n", - types[matrix->type], (int)matrix->flags); - print_matrix_floats ((float *)matrix); - g_print ("Inverse: \n"); - if (!(matrix->flags & MAT_DIRTY_INVERSE)) - { - float prod[16]; - print_matrix_floats (matrix->inv); - matrix_multiply4x4 (prod, (float *)matrix, matrix->inv); - g_print ("Mat * Inverse:\n"); - print_matrix_floats (prod); - } - else - g_print (" - not available\n"); -} - -/*@}*/ - - -/* - * References an element of 4x4 matrix. - * - * \param m matrix array. - * \param c column of the desired element. - * \param r row of the desired element. - * - * \return value of the desired element. - * - * Calculate the linear storage index of the element and references it. - */ -#define MAT(m,r,c) (m)[(c)*4+(r)] - - -/**********************************************************************/ -/* \name Matrix inversion */ -/*@{*/ - -/* - * Swaps the values of two floating pointer variables. - * - * Used by invert_matrix_general() to swap the row pointers. - */ -#define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; } - -/* - * Compute inverse of 4x4 transformation matrix. - * - * \param mat pointer to a CoglMatrix structure. The matrix inverse will be - * stored in the CoglMatrix::inv attribute. - * - * \return TRUE for success, FALSE for failure (\p singular matrix). - * - * \author - * Code contributed by Jacques Leroy jle@star.be - * - * Calculates the inverse matrix by performing the gaussian matrix reduction - * with partial pivoting followed by back/substitution with the loops manually - * unrolled. - */ -static gboolean -invert_matrix_general (CoglMatrix *matrix) -{ - const float *m = (float *)matrix; - float *out = matrix->inv; - float wtmp[4][8]; - float m0, m1, m2, m3, s; - float *r0, *r1, *r2, *r3; - - r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; - - r0[0] = MAT (m, 0, 0), r0[1] = MAT (m, 0, 1), - r0[2] = MAT (m, 0, 2), r0[3] = MAT (m, 0, 3), - r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, - - r1[0] = MAT (m, 1, 0), r1[1] = MAT (m, 1, 1), - r1[2] = MAT (m, 1, 2), r1[3] = MAT (m, 1, 3), - r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, - - r2[0] = MAT (m, 2, 0), r2[1] = MAT (m, 2, 1), - r2[2] = MAT (m, 2, 2), r2[3] = MAT (m, 2, 3), - r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, - - r3[0] = MAT (m, 3, 0), r3[1] = MAT (m, 3, 1), - r3[2] = MAT (m, 3, 2), r3[3] = MAT (m, 3, 3), - r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; - - /* choose pivot - or die */ - if (fabsf (r3[0]) > fabsf (r2[0])) - SWAP_ROWS (r3, r2); - if (fabsf (r2[0]) > fabsf (r1[0])) - SWAP_ROWS (r2, r1); - if (fabsf (r1[0]) > fabsf (r0[0])) - SWAP_ROWS (r1, r0); - if (0.0 == r0[0]) - return FALSE; - - /* eliminate first variable */ - m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; - s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; - s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; - s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; - s = r0[4]; - if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r0[5]; - if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r0[6]; - if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r0[7]; - if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabsf (r3[1]) > fabsf (r2[1])) - SWAP_ROWS (r3, r2); - if (fabsf (r2[1]) > fabsf (r1[1])) - SWAP_ROWS (r2, r1); - if (0.0 == r1[1]) - return FALSE; - - /* eliminate second variable */ - m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1]; - r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; - r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; - s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabsf (r3[2]) > fabsf (r2[2])) - SWAP_ROWS (r3, r2); - if (0.0 == r2[2]) - return FALSE; - - /* eliminate third variable */ - m3 = r3[2] / r2[2]; - r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], - r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], - r3[7] -= m3 * r2[7]; - - /* last check */ - if (0.0 == r3[3]) - return FALSE; - - s = 1.0f / r3[3]; /* now back substitute row 3 */ - r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; - - m2 = r2[3]; /* now back substitute row 2 */ - s = 1.0f / r2[2]; - r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), - r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); - m1 = r1[3]; - r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, - r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; - m0 = r0[3]; - r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, - r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; - - m1 = r1[2]; /* now back substitute row 1 */ - s = 1.0f / r1[1]; - r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), - r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); - m0 = r0[2]; - r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, - r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; - - m0 = r0[1]; /* now back substitute row 0 */ - s = 1.0f / r0[0]; - r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), - r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); - - MAT (out, 0, 0) = r0[4]; MAT (out, 0, 1) = r0[5], - MAT (out, 0, 2) = r0[6]; MAT (out, 0, 3) = r0[7], - MAT (out, 1, 0) = r1[4]; MAT (out, 1, 1) = r1[5], - MAT (out, 1, 2) = r1[6]; MAT (out, 1, 3) = r1[7], - MAT (out, 2, 0) = r2[4]; MAT (out, 2, 1) = r2[5], - MAT (out, 2, 2) = r2[6]; MAT (out, 2, 3) = r2[7], - MAT (out, 3, 0) = r3[4]; MAT (out, 3, 1) = r3[5], - MAT (out, 3, 2) = r3[6]; MAT (out, 3, 3) = r3[7]; - - return TRUE; -} -#undef SWAP_ROWS - -/* - * Compute inverse of a general 3d transformation matrix. - * - * \param mat pointer to a CoglMatrix structure. The matrix inverse will be - * stored in the CoglMatrix::inv attribute. - * - * \return TRUE for success, FALSE for failure (\p singular matrix). - * - * \author Adapted from graphics gems II. - * - * Calculates the inverse of the upper left by first calculating its - * determinant and multiplying it to the symmetric adjust matrix of each - * element. Finally deals with the translation part by transforming the - * original translation vector using by the calculated submatrix inverse. - */ -static gboolean -invert_matrix_3d_general (CoglMatrix *matrix) -{ - const float *in = (float *)matrix; - float *out = matrix->inv; - float pos, neg, t; - float det; - - /* Calculate the determinant of upper left 3x3 submatrix and - * determine if the matrix is singular. - */ - pos = neg = 0.0; - t = MAT (in,0,0) * MAT (in,1,1) * MAT (in,2,2); - if (t >= 0.0) pos += t; else neg += t; - - t = MAT (in,1,0) * MAT (in,2,1) * MAT (in,0,2); - if (t >= 0.0) pos += t; else neg += t; - - t = MAT (in,2,0) * MAT (in,0,1) * MAT (in,1,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT (in,2,0) * MAT (in,1,1) * MAT (in,0,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT (in,1,0) * MAT (in,0,1) * MAT (in,2,2); - if (t >= 0.0) pos += t; else neg += t; - - t = -MAT (in,0,0) * MAT (in,2,1) * MAT (in,1,2); - if (t >= 0.0) pos += t; else neg += t; - - det = pos + neg; - - if (det*det < 1e-25) - return FALSE; - - det = 1.0f / det; - MAT (out,0,0) = - ( (MAT (in, 1, 1)*MAT (in, 2, 2) - MAT (in, 2, 1)*MAT (in, 1, 2) )*det); - MAT (out,0,1) = - (- (MAT (in, 0, 1)*MAT (in, 2, 2) - MAT (in, 2, 1)*MAT (in, 0, 2) )*det); - MAT (out,0,2) = - ( (MAT (in, 0, 1)*MAT (in, 1, 2) - MAT (in, 1, 1)*MAT (in, 0, 2) )*det); - MAT (out,1,0) = - (- (MAT (in,1,0)*MAT (in,2,2) - MAT (in,2,0)*MAT (in,1,2) )*det); - MAT (out,1,1) = - ( (MAT (in,0,0)*MAT (in,2,2) - MAT (in,2,0)*MAT (in,0,2) )*det); - MAT (out,1,2) = - (- (MAT (in,0,0)*MAT (in,1,2) - MAT (in,1,0)*MAT (in,0,2) )*det); - MAT (out,2,0) = - ( (MAT (in,1,0)*MAT (in,2,1) - MAT (in,2,0)*MAT (in,1,1) )*det); - MAT (out,2,1) = - (- (MAT (in,0,0)*MAT (in,2,1) - MAT (in,2,0)*MAT (in,0,1) )*det); - MAT (out,2,2) = - ( (MAT (in,0,0)*MAT (in,1,1) - MAT (in,1,0)*MAT (in,0,1) )*det); - - /* Do the translation part */ - MAT (out,0,3) = - (MAT (in, 0, 3) * MAT (out, 0, 0) + - MAT (in, 1, 3) * MAT (out, 0, 1) + - MAT (in, 2, 3) * MAT (out, 0, 2) ); - MAT (out,1,3) = - (MAT (in, 0, 3) * MAT (out, 1, 0) + - MAT (in, 1, 3) * MAT (out, 1, 1) + - MAT (in, 2, 3) * MAT (out, 1, 2) ); - MAT (out,2,3) = - (MAT (in, 0, 3) * MAT (out, 2 ,0) + - MAT (in, 1, 3) * MAT (out, 2, 1) + - MAT (in, 2, 3) * MAT (out, 2, 2) ); - - return TRUE; -} - -/* - * Compute inverse of a 3d transformation matrix. - * - * \param mat pointer to a CoglMatrix structure. The matrix inverse will be - * stored in the CoglMatrix::inv attribute. - * - * \return TRUE for success, FALSE for failure (\p singular matrix). - * - * If the matrix is not an angle preserving matrix then calls - * invert_matrix_3d_general for the actual calculation. Otherwise calculates - * the inverse matrix analyzing and inverting each of the scaling, rotation and - * translation parts. - */ -static gboolean -invert_matrix_3d (CoglMatrix *matrix) -{ - const float *in = (float *)matrix; - float *out = matrix->inv; - - if (!TEST_MAT_FLAGS(matrix, MAT_FLAGS_ANGLE_PRESERVING)) - return invert_matrix_3d_general (matrix); - - if (matrix->flags & MAT_FLAG_UNIFORM_SCALE) - { - float scale = (MAT (in, 0, 0) * MAT (in, 0, 0) + - MAT (in, 0, 1) * MAT (in, 0, 1) + - MAT (in, 0, 2) * MAT (in, 0, 2)); - - if (scale == 0.0) - return FALSE; - - scale = 1.0f / scale; - - /* Transpose and scale the 3 by 3 upper-left submatrix. */ - MAT (out, 0, 0) = scale * MAT (in, 0, 0); - MAT (out, 1, 0) = scale * MAT (in, 0, 1); - MAT (out, 2, 0) = scale * MAT (in, 0, 2); - MAT (out, 0, 1) = scale * MAT (in, 1, 0); - MAT (out, 1, 1) = scale * MAT (in, 1, 1); - MAT (out, 2, 1) = scale * MAT (in, 1, 2); - MAT (out, 0, 2) = scale * MAT (in, 2, 0); - MAT (out, 1, 2) = scale * MAT (in, 2, 1); - MAT (out, 2, 2) = scale * MAT (in, 2, 2); - } - else if (matrix->flags & MAT_FLAG_ROTATION) - { - /* Transpose the 3 by 3 upper-left submatrix. */ - MAT (out, 0, 0) = MAT (in, 0, 0); - MAT (out, 1, 0) = MAT (in, 0, 1); - MAT (out, 2, 0) = MAT (in, 0, 2); - MAT (out, 0, 1) = MAT (in, 1, 0); - MAT (out, 1, 1) = MAT (in, 1, 1); - MAT (out, 2, 1) = MAT (in, 1, 2); - MAT (out, 0, 2) = MAT (in, 2, 0); - MAT (out, 1, 2) = MAT (in, 2, 1); - MAT (out, 2, 2) = MAT (in, 2, 2); - } - else - { - /* pure translation */ - memcpy (out, identity, 16 * sizeof (float)); - MAT (out, 0, 3) = - MAT (in, 0, 3); - MAT (out, 1, 3) = - MAT (in, 1, 3); - MAT (out, 2, 3) = - MAT (in, 2, 3); - return TRUE; - } - - if (matrix->flags & MAT_FLAG_TRANSLATION) - { - /* Do the translation part */ - MAT (out,0,3) = - (MAT (in, 0, 3) * MAT (out, 0, 0) + - MAT (in, 1, 3) * MAT (out, 0, 1) + - MAT (in, 2, 3) * MAT (out, 0, 2) ); - MAT (out,1,3) = - (MAT (in, 0, 3) * MAT (out, 1, 0) + - MAT (in, 1, 3) * MAT (out, 1, 1) + - MAT (in, 2, 3) * MAT (out, 1, 2) ); - MAT (out,2,3) = - (MAT (in, 0, 3) * MAT (out, 2, 0) + - MAT (in, 1, 3) * MAT (out, 2, 1) + - MAT (in, 2, 3) * MAT (out, 2, 2) ); - } - else - MAT (out, 0, 3) = MAT (out, 1, 3) = MAT (out, 2, 3) = 0.0; - - return TRUE; -} - -/* - * Compute inverse of an identity transformation matrix. - * - * \param mat pointer to a CoglMatrix structure. The matrix inverse will be - * stored in the CoglMatrix::inv attribute. - * - * \return always TRUE. - * - * Simply copies identity into CoglMatrix::inv. - */ -static gboolean -invert_matrix_identity (CoglMatrix *matrix) -{ - memcpy (matrix->inv, identity, 16 * sizeof (float)); - return TRUE; -} - -/* - * Compute inverse of a no-rotation 3d transformation matrix. - * - * \param mat pointer to a CoglMatrix structure. The matrix inverse will be - * stored in the CoglMatrix::inv attribute. - * - * \return TRUE for success, FALSE for failure (\p singular matrix). - * - * Calculates the - */ -static gboolean -invert_matrix_3d_no_rotation (CoglMatrix *matrix) -{ - const float *in = (float *)matrix; - float *out = matrix->inv; - - if (MAT (in,0,0) == 0 || MAT (in,1,1) == 0 || MAT (in,2,2) == 0) - return FALSE; - - memcpy (out, identity, 16 * sizeof (float)); - MAT (out,0,0) = 1.0f / MAT (in,0,0); - MAT (out,1,1) = 1.0f / MAT (in,1,1); - MAT (out,2,2) = 1.0f / MAT (in,2,2); - - if (matrix->flags & MAT_FLAG_TRANSLATION) - { - MAT (out,0,3) = - (MAT (in,0,3) * MAT (out,0,0)); - MAT (out,1,3) = - (MAT (in,1,3) * MAT (out,1,1)); - MAT (out,2,3) = - (MAT (in,2,3) * MAT (out,2,2)); - } - - return TRUE; -} - -/* - * Compute inverse of a no-rotation 2d transformation matrix. - * - * \param mat pointer to a CoglMatrix structure. The matrix inverse will be - * stored in the CoglMatrix::inv attribute. - * - * \return TRUE for success, FALSE for failure (\p singular matrix). - * - * Calculates the inverse matrix by applying the inverse scaling and - * translation to the identity matrix. - */ -static gboolean -invert_matrix_2d_no_rotation (CoglMatrix *matrix) -{ - const float *in = (float *)matrix; - float *out = matrix->inv; - - if (MAT (in, 0, 0) == 0 || MAT (in, 1, 1) == 0) - return FALSE; - - memcpy (out, identity, 16 * sizeof (float)); - MAT (out, 0, 0) = 1.0f / MAT (in, 0, 0); - MAT (out, 1, 1) = 1.0f / MAT (in, 1, 1); - - if (matrix->flags & MAT_FLAG_TRANSLATION) - { - MAT (out, 0, 3) = - (MAT (in, 0, 3) * MAT (out, 0, 0)); - MAT (out, 1, 3) = - (MAT (in, 1, 3) * MAT (out, 1, 1)); - } - - return TRUE; -} - -#if 0 -/* broken */ -static gboolean -invert_matrix_perspective (CoglMatrix *matrix) -{ - const float *in = matrix; - float *out = matrix->inv; - - if (MAT (in,2,3) == 0) - return FALSE; - - memcpy( out, identity, 16 * sizeof(float) ); - - MAT (out, 0, 0) = 1.0f / MAT (in, 0, 0); - MAT (out, 1, 1) = 1.0f / MAT (in, 1, 1); - - MAT (out, 0, 3) = MAT (in, 0, 2); - MAT (out, 1, 3) = MAT (in, 1, 2); - - MAT (out,2,2) = 0; - MAT (out,2,3) = -1; - - MAT (out,3,2) = 1.0f / MAT (in,2,3); - MAT (out,3,3) = MAT (in,2,2) * MAT (out,3,2); - - return TRUE; -} -#endif - -/* - * Matrix inversion function pointer type. - */ -typedef gboolean (*inv_mat_func)(CoglMatrix *matrix); - -/* - * Table of the matrix inversion functions according to the matrix type. - */ -static inv_mat_func inv_mat_tab[7] = { - invert_matrix_general, - invert_matrix_identity, - invert_matrix_3d_no_rotation, -#if 0 - /* Don't use this function for now - it fails when the projection matrix - * is premultiplied by a translation (ala Chromium's tilesort SPU). - */ - invert_matrix_perspective, -#else - invert_matrix_general, -#endif - invert_matrix_3d, /* lazy! */ - invert_matrix_2d_no_rotation, - invert_matrix_3d -}; - -/* - * Compute inverse of a transformation matrix. - * - * \param mat pointer to a CoglMatrix structure. The matrix inverse will be - * stored in the CoglMatrix::inv attribute. - * - * \return TRUE for success, FALSE for failure (\p singular matrix). - * - * Calls the matrix inversion function in inv_mat_tab corresponding to the - * given matrix type. In case of failure, updates the MAT_FLAG_SINGULAR flag, - * and copies the identity matrix into CoglMatrix::inv. - */ -gboolean -_math_matrix_update_inverse (CoglMatrix *matrix) -{ - if (matrix->flags & MAT_DIRTY_FLAGS || - matrix->flags & MAT_DIRTY_INVERSE) - { - _math_matrix_update_type_and_flags (matrix); - - if (inv_mat_tab[matrix->type](matrix)) - matrix->flags &= ~MAT_FLAG_SINGULAR; - else - { - matrix->flags |= MAT_FLAG_SINGULAR; - memcpy (matrix->inv, identity, 16 * sizeof (float)); - } - - matrix->flags &= ~MAT_DIRTY_INVERSE; - } - - if (matrix->flags & MAT_FLAG_SINGULAR) - return FALSE; - else - return TRUE; -} - -/*@}*/ - - -/**********************************************************************/ -/* \name Matrix generation */ -/*@{*/ - -/* - * Generate a 4x4 transformation matrix from glRotate parameters, and - * post-multiply the input matrix by it. - * - * \author - * This function was contributed by Erich Boleyn (erich@uruk.org). - * Optimizations contributed by Rudolf Opalla (rudi@khm.de). - */ -void -_math_matrix_rotate (CoglMatrix *matrix, - float angle, - float x, - float y, - float z) -{ - float xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c; - float m[16]; - gboolean optimized; - - s = sinf (angle * DEG2RAD); - c = cosf (angle * DEG2RAD); - - memcpy (m, identity, 16 * sizeof (float)); - optimized = FALSE; - -#define M(row,col) m[col*4+row] - - if (x == 0.0f) - { - if (y == 0.0f) - { - if (z != 0.0f) - { - optimized = TRUE; - /* rotate only around z-axis */ - M (0,0) = c; - M (1,1) = c; - if (z < 0.0f) - { - M (0,1) = s; - M (1,0) = -s; - } - else - { - M (0,1) = -s; - M (1,0) = s; - } - } - } - else if (z == 0.0f) - { - optimized = TRUE; - /* rotate only around y-axis */ - M (0,0) = c; - M (2,2) = c; - if (y < 0.0f) - { - M (0,2) = -s; - M (2,0) = s; - } - else - { - M (0,2) = s; - M (2,0) = -s; - } - } - } - else if (y == 0.0f) - { - if (z == 0.0f) - { - optimized = TRUE; - /* rotate only around x-axis */ - M (1,1) = c; - M (2,2) = c; - if (x < 0.0f) - { - M (1,2) = s; - M (2,1) = -s; - } - else - { - M (1,2) = -s; - M (2,1) = s; - } - } - } - - if (!optimized) - { - const float mag = sqrtf (x * x + y * y + z * z); - - if (mag <= 1.0e-4) - { - /* no rotation, leave mat as-is */ - return; - } - - x /= mag; - y /= mag; - z /= mag; - - - /* - * Arbitrary axis rotation matrix. - * - * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied - * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation - * (which is about the X-axis), and the two composite transforms - * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary - * from the arbitrary axis to the X-axis then back. They are - * all elementary rotations. - * - * Rz' is a rotation about the Z-axis, to bring the axis vector - * into the x-z plane. Then Ry' is applied, rotating about the - * Y-axis to bring the axis vector parallel with the X-axis. The - * rotation about the X-axis is then performed. Ry and Rz are - * simply the respective inverse transforms to bring the arbitrary - * axis back to it's original orientation. The first transforms - * Rz' and Ry' are considered inverses, since the data from the - * arbitrary axis gives you info on how to get to it, not how - * to get away from it, and an inverse must be applied. - * - * The basic calculation used is to recognize that the arbitrary - * axis vector (x, y, z), since it is of unit length, actually - * represents the sines and cosines of the angles to rotate the - * X-axis to the same orientation, with theta being the angle about - * Z and phi the angle about Y (in the order described above) - * as follows: - * - * cos ( theta ) = x / sqrt ( 1 - z^2 ) - * sin ( theta ) = y / sqrt ( 1 - z^2 ) - * - * cos ( phi ) = sqrt ( 1 - z^2 ) - * sin ( phi ) = z - * - * Note that cos ( phi ) can further be inserted to the above - * formulas: - * - * cos ( theta ) = x / cos ( phi ) - * sin ( theta ) = y / sin ( phi ) - * - * ...etc. Because of those relations and the standard trigonometric - * relations, it is pssible to reduce the transforms down to what - * is used below. It may be that any primary axis chosen will give the - * same results (modulo a sign convention) using thie method. - * - * Particularly nice is to notice that all divisions that might - * have caused trouble when parallel to certain planes or - * axis go away with care paid to reducing the expressions. - * After checking, it does perform correctly under all cases, since - * in all the cases of division where the denominator would have - * been zero, the numerator would have been zero as well, giving - * the expected result. - */ - - xx = x * x; - yy = y * y; - zz = z * z; - xy = x * y; - yz = y * z; - zx = z * x; - xs = x * s; - ys = y * s; - zs = z * s; - one_c = 1.0f - c; - - /* We already hold the identity-matrix so we can skip some statements */ - M (0,0) = (one_c * xx) + c; - M (0,1) = (one_c * xy) - zs; - M (0,2) = (one_c * zx) + ys; - /* M (0,3) = 0.0f; */ - - M (1,0) = (one_c * xy) + zs; - M (1,1) = (one_c * yy) + c; - M (1,2) = (one_c * yz) - xs; - /* M (1,3) = 0.0f; */ - - M (2,0) = (one_c * zx) - ys; - M (2,1) = (one_c * yz) + xs; - M (2,2) = (one_c * zz) + c; - /* M (2,3) = 0.0f; */ - - /* - M (3,0) = 0.0f; - M (3,1) = 0.0f; - M (3,2) = 0.0f; - M (3,3) = 1.0f; - */ - } -#undef M - - matrix_multiply_array_with_flags (matrix, m, MAT_FLAG_ROTATION); -} - -/* - * Apply a perspective projection matrix. - * - * \param mat matrix to apply the projection. - * \param left left clipping plane coordinate. - * \param right right clipping plane coordinate. - * \param bottom bottom clipping plane coordinate. - * \param top top clipping plane coordinate. - * \param nearval distance to the near clipping plane. - * \param farval distance to the far clipping plane. - * - * Creates the projection matrix and multiplies it with \p mat, marking the - * MAT_FLAG_PERSPECTIVE flag. - */ -void -_math_matrix_frustum (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float nearval, - float farval) -{ - float x, y, a, b, c, d; - float m[16]; - - x = (2.0f * nearval) / (right - left); - y = (2.0f * nearval) / (top - bottom); - a = (right + left) / (right - left); - b = (top + bottom) / (top - bottom); - c = -(farval + nearval) / ( farval - nearval); - d = -(2.0f * farval * nearval) / (farval - nearval); /* error? */ - -#define M(row,col) m[col*4+row] - M (0,0) = x; M (0,1) = 0.0f; M (0,2) = a; M (0,3) = 0.0f; - M (1,0) = 0.0f; M (1,1) = y; M (1,2) = b; M (1,3) = 0.0f; - M (2,0) = 0.0f; M (2,1) = 0.0f; M (2,2) = c; M (2,3) = d; - M (3,0) = 0.0f; M (3,1) = 0.0f; M (3,2) = -1.0f; M (3,3) = 0.0f; -#undef M - - matrix_multiply_array_with_flags (matrix, m, MAT_FLAG_PERSPECTIVE); -} - -/* - * Apply an orthographic projection matrix. - * - * \param mat matrix to apply the projection. - * \param left left clipping plane coordinate. - * \param right right clipping plane coordinate. - * \param bottom bottom clipping plane coordinate. - * \param top top clipping plane coordinate. - * \param nearval distance to the near clipping plane. - * \param farval distance to the far clipping plane. - * - * Creates the projection matrix and multiplies it with \p mat, marking the - * MAT_FLAG_GENERAL_SCALE and MAT_FLAG_TRANSLATION flags. - */ -void -_math_matrix_ortho (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float nearval, - float farval) -{ - float m[16]; - -#define M(row,col) m[col*4+row] - M (0,0) = 2.0f / (right-left); - M (0,1) = 0.0f; - M (0,2) = 0.0f; - M (0,3) = -(right+left) / (right-left); - - M (1,0) = 0.0f; - M (1,1) = 2.0f / (top-bottom); - M (1,2) = 0.0f; - M (1,3) = -(top+bottom) / (top-bottom); - - M (2,0) = 0.0f; - M (2,1) = 0.0f; - M (2,2) = -2.0f / (farval-nearval); - M (2,3) = -(farval+nearval) / (farval-nearval); - - M (3,0) = 0.0f; - M (3,1) = 0.0f; - M (3,2) = 0.0f; - M (3,3) = 1.0f; -#undef M - - matrix_multiply_array_with_flags (matrix, m, - (MAT_FLAG_GENERAL_SCALE | - MAT_FLAG_TRANSLATION)); -} - -/* - * Multiply a matrix with a general scaling matrix. - * - * \param mat matrix. - * \param x x axis scale factor. - * \param y y axis scale factor. - * \param z z axis scale factor. - * - * Multiplies in-place the elements of \p mat by the scale factors. Checks if - * the scales factors are roughly the same, marking the MAT_FLAG_UNIFORM_SCALE - * flag, or MAT_FLAG_GENERAL_SCALE. Marks the MAT_DIRTY_TYPE and - * MAT_DIRTY_INVERSE dirty flags. - */ -void -_math_matrix_scale (CoglMatrix *matrix, float x, float y, float z) -{ - float *m = (float *)matrix; - m[0] *= x; m[4] *= y; m[8] *= z; - m[1] *= x; m[5] *= y; m[9] *= z; - m[2] *= x; m[6] *= y; m[10] *= z; - m[3] *= x; m[7] *= y; m[11] *= z; - - if (fabsf (x - y) < 1e-8 && fabsf (x - z) < 1e-8) - matrix->flags |= MAT_FLAG_UNIFORM_SCALE; - else - matrix->flags |= MAT_FLAG_GENERAL_SCALE; - - matrix->flags |= (MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); -} - -/* - * Multiply a matrix with a translation matrix. - * - * \param mat matrix. - * \param x translation vector x coordinate. - * \param y translation vector y coordinate. - * \param z translation vector z coordinate. - * - * Adds the translation coordinates to the elements of \p mat in-place. Marks - * the MAT_FLAG_TRANSLATION flag, and the MAT_DIRTY_TYPE and MAT_DIRTY_INVERSE - * dirty flags. - */ -void -_math_matrix_translate (CoglMatrix *matrix, float x, float y, float z) -{ - float *m = (float *)matrix; - m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; - m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; - m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; - m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; - - matrix->flags |= (MAT_FLAG_TRANSLATION | - MAT_DIRTY_TYPE | - MAT_DIRTY_INVERSE); -} - - -/* - * Set matrix to do viewport and depthrange mapping. - * Transforms Normalized Device Coords to window/Z values. - */ -void -_math_matrix_viewport (CoglMatrix *matrix, - float x, float y, - float width, float height, - float zNear, float zFar, float depthMax) -{ - float *m = (float *)matrix; - m[MAT_SX] = width / 2.0f; - m[MAT_TX] = m[MAT_SX] + x; - m[MAT_SY] = height / 2.0f; - m[MAT_TY] = m[MAT_SY] + y; - m[MAT_SZ] = depthMax * ((zFar - zNear) / 2.0f); - m[MAT_TZ] = depthMax * ((zFar - zNear) / 2.0f + zNear); - matrix->flags = MAT_FLAG_GENERAL_SCALE | MAT_FLAG_TRANSLATION; - matrix->type = COGL_MATRIX_TYPE_3D_NO_ROT; -} - - -/* - * Set a matrix to the identity matrix. - * - * \param mat matrix. - * - * Copies ::identity into \p CoglMatrix::m, and into CoglMatrix::inv if - * not NULL. Sets the matrix type to identity, resets the flags. It - * doesn't initialize the inverse matrix, it just marks it dirty. - */ -void -_math_matrix_init_identity (CoglMatrix *matrix) -{ - memcpy (matrix, identity, 16 * sizeof (float)); - - matrix->type = COGL_MATRIX_TYPE_IDENTITY; - matrix->flags = MAT_DIRTY_INVERSE; -} - -/*@}*/ - - -/**********************************************************************/ -/* \name Matrix analysis */ -/*@{*/ - -#define ZERO(x) (1<flags &= ~MAT_FLAGS_GEOMETRY; - - /* Check for translation - no-one really cares - */ - if ((mask & MASK_NO_TRX) != MASK_NO_TRX) - matrix->flags |= MAT_FLAG_TRANSLATION; - - /* Do the real work - */ - if (mask == (unsigned int) MASK_IDENTITY) - matrix->type = COGL_MATRIX_TYPE_IDENTITY; - else if ((mask & MASK_2D_NO_ROT) == (unsigned int) MASK_2D_NO_ROT) - { - matrix->type = COGL_MATRIX_TYPE_2D_NO_ROT; - - if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE) - matrix->flags |= MAT_FLAG_GENERAL_SCALE; - } - else if ((mask & MASK_2D) == (unsigned int) MASK_2D) - { - float mm = DOT2 (m, m); - float m4m4 = DOT2 (m+4,m+4); - float mm4 = DOT2 (m,m+4); - - matrix->type = COGL_MATRIX_TYPE_2D; - - /* Check for scale */ - if (SQ (mm-1) > SQ (1e-6) || - SQ (m4m4-1) > SQ (1e-6)) - matrix->flags |= MAT_FLAG_GENERAL_SCALE; - - /* Check for rotation */ - if (SQ (mm4) > SQ (1e-6)) - matrix->flags |= MAT_FLAG_GENERAL_3D; - else - matrix->flags |= MAT_FLAG_ROTATION; - - } - else if ((mask & MASK_3D_NO_ROT) == (unsigned int) MASK_3D_NO_ROT) - { - matrix->type = COGL_MATRIX_TYPE_3D_NO_ROT; - - /* Check for scale */ - if (SQ (m[0]-m[5]) < SQ (1e-6) && - SQ (m[0]-m[10]) < SQ (1e-6)) - { - if (SQ (m[0]-1.0) > SQ (1e-6)) - matrix->flags |= MAT_FLAG_UNIFORM_SCALE; - } - else - matrix->flags |= MAT_FLAG_GENERAL_SCALE; - } - else if ((mask & MASK_3D) == (unsigned int) MASK_3D) - { - float c1 = DOT3 (m,m); - float c2 = DOT3 (m+4,m+4); - float c3 = DOT3 (m+8,m+8); - float d1 = DOT3 (m, m+4); - float cp[3]; - - matrix->type = COGL_MATRIX_TYPE_3D; - - /* Check for scale */ - if (SQ (c1-c2) < SQ (1e-6) && SQ (c1-c3) < SQ (1e-6)) - { - if (SQ (c1-1.0) > SQ (1e-6)) - matrix->flags |= MAT_FLAG_UNIFORM_SCALE; - /* else no scale at all */ - } - else - matrix->flags |= MAT_FLAG_GENERAL_SCALE; - - /* Check for rotation */ - if (SQ (d1) < SQ (1e-6)) - { - CROSS3 ( cp, m, m+4); - SUB_3V ( cp, cp, (m+8)); - if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) - matrix->flags |= MAT_FLAG_ROTATION; - else - matrix->flags |= MAT_FLAG_GENERAL_3D; - } - else - matrix->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */ - } - else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0f) - { - matrix->type = COGL_MATRIX_TYPE_PERSPECTIVE; - matrix->flags |= MAT_FLAG_GENERAL; - } - else - { - matrix->type = COGL_MATRIX_TYPE_GENERAL; - matrix->flags |= MAT_FLAG_GENERAL; - } -} - -/* - * Analyze a matrix given that its flags are accurate. - * - * This is the more common operation, hopefully. - */ -static void -analyse_from_flags (CoglMatrix *matrix) -{ - const float *m = (float *)matrix; - - if (TEST_MAT_FLAGS(matrix, 0)) - matrix->type = COGL_MATRIX_TYPE_IDENTITY; - else if (TEST_MAT_FLAGS(matrix, (MAT_FLAG_TRANSLATION | - MAT_FLAG_UNIFORM_SCALE | - MAT_FLAG_GENERAL_SCALE))) - { - if ( m[10] == 1.0f && m[14] == 0.0f ) - matrix->type = COGL_MATRIX_TYPE_2D_NO_ROT; - else - matrix->type = COGL_MATRIX_TYPE_3D_NO_ROT; - } - else if (TEST_MAT_FLAGS (matrix, MAT_FLAGS_3D)) - { - if ( m[ 8]==0.0f - && m[ 9]==0.0f - && m[2]==0.0f && m[6]==0.0f && m[10]==1.0f && m[14]==0.0f) - { - matrix->type = COGL_MATRIX_TYPE_2D; - } - else - matrix->type = COGL_MATRIX_TYPE_3D; - } - else if ( m[4]==0.0f && m[12]==0.0f - && m[1]==0.0f && m[13]==0.0f - && m[2]==0.0f && m[6]==0.0f - && m[3]==0.0f && m[7]==0.0f && m[11]==-1.0f && m[15]==0.0f) - { - matrix->type = COGL_MATRIX_TYPE_PERSPECTIVE; - } - else - matrix->type = COGL_MATRIX_TYPE_GENERAL; -} - -/* - * Analyze and update the type and flags of a matrix. - * - * \param mat matrix. - * - * If the matrix type is dirty then calls either analyse_from_scratch() or - * analyse_from_flags() to determine its type, according to whether the flags - * are dirty or not, respectively. If the matrix has an inverse and it's dirty - * then calls matrix_invert(). Finally clears the dirty flags. - */ -void -_math_matrix_update_type_and_flags (CoglMatrix *matrix) -{ - if (matrix->flags & MAT_DIRTY_TYPE) - { - if (matrix->flags & MAT_DIRTY_FLAGS) - analyse_from_scratch (matrix); - else - analyse_from_flags (matrix); - } - - matrix->flags &= ~(MAT_DIRTY_FLAGS | MAT_DIRTY_TYPE); -} - -/*@}*/ - - -/* - * Test if the given matrix preserves vector lengths. - */ -gboolean -_math_matrix_is_length_preserving (const CoglMatrix *m) -{ - return TEST_MAT_FLAGS (m, MAT_FLAGS_LENGTH_PRESERVING); -} - - -/* - * Test if the given matrix does any rotation. - * (or perhaps if the upper-left 3x3 is non-identity) - */ -gboolean -_math_matrix_has_rotation (const CoglMatrix *matrix) -{ - if (matrix->flags & (MAT_FLAG_GENERAL | - MAT_FLAG_ROTATION | - MAT_FLAG_GENERAL_3D | - MAT_FLAG_PERSPECTIVE)) - return TRUE; - else - return FALSE; -} - - -gboolean -_math_matrix_is_general_scale (const CoglMatrix *matrix) -{ - return (matrix->flags & MAT_FLAG_GENERAL_SCALE) ? TRUE : FALSE; -} - - -gboolean -_math_matrix_is_dirty (const CoglMatrix *matrix) -{ - return (matrix->flags & MAT_DIRTY_ALL) ? TRUE : FALSE; -} - - -/**********************************************************************/ -/* \name Matrix setup */ -/*@{*/ - -/* - * Loads a matrix array into CoglMatrix. - * - * \param m matrix array. - * \param mat matrix. - * - * Copies \p m into CoglMatrix::m and marks the MAT_FLAG_GENERAL and - * MAT_DIRTY_ALL - * flags. - */ -void -_math_matrix_init_from_array (CoglMatrix *matrix, const float *array) -{ - memcpy (matrix, array, 16 * sizeof (float)); - matrix->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL); -} - -/*@}*/ - - -/**********************************************************************/ -/* \name Matrix transpose */ -/*@{*/ - -/* - * Transpose a float matrix. - * - * \param to destination array. - * \param from source array. - */ -void -_math_transposef (float to[16], const float from[16]) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - -/* - * Transpose a double matrix. - * - * \param to destination array. - * \param from source array. - */ -void -_math_transposed (double to[16], const double from[16]) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - -/* - * Transpose a double matrix and convert to float. - * - * \param to destination array. - * \param from source array. - */ -void -_math_transposefd (float to[16], const double from[16]) -{ - to[0] = (float)from[0]; - to[1] = (float)from[4]; - to[2] = (float)from[8]; - to[3] = (float)from[12]; - to[4] = (float)from[1]; - to[5] = (float)from[5]; - to[6] = (float)from[9]; - to[7] = (float)from[13]; - to[8] = (float)from[2]; - to[9] = (float)from[6]; - to[10] = (float)from[10]; - to[11] = (float)from[14]; - to[12] = (float)from[3]; - to[13] = (float)from[7]; - to[14] = (float)from[11]; - to[15] = (float)from[15]; -} - -/*@}*/ - - -/* - * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix. This - * function is used for transforming clipping plane equations and spotlight - * directions. - * Mathematically, u = v * m. - * Input: v - input vector - * m - transformation matrix - * Output: u - transformed vector - */ -void -_mesa_transform_vector (float u[4], const float v[4], const float m[16]) -{ - const float v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; -#define M(row,col) m[row + col*4] - u[0] = v0 * M (0,0) + v1 * M (1,0) + v2 * M (2,0) + v3 * M (3,0); - u[1] = v0 * M (0,1) + v1 * M (1,1) + v2 * M (2,1) + v3 * M (3,1); - u[2] = v0 * M (0,2) + v1 * M (1,2) + v2 * M (2,2) + v3 * M (3,2); - u[3] = v0 * M (0,3) + v1 * M (1,3) + v2 * M (2,3) + v3 * M (3,3); -#undef M -} - diff --git a/clutter/cogl/cogl/cogl-matrix-mesa.h b/clutter/cogl/cogl/cogl-matrix-mesa.h deleted file mode 100644 index 72ac865..0000000 --- a/clutter/cogl/cogl/cogl-matrix-mesa.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ -/* - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/* - * \file math/m_matrix.h - * Defines basic structures for matrix-handling. - */ - -#ifndef _M_MATRIX_H -#define _M_MATRIX_H - -#include - -#include - -/* - * \name Symbolic names to some of the entries in the matrix - * - * These are handy for the viewport mapping, which is expressed as a matrix. - */ -/*@{*/ -#define MAT_SX 0 -#define MAT_SY 5 -#define MAT_SZ 10 -#define MAT_TX 12 -#define MAT_TY 13 -#define MAT_TZ 14 -/*@}*/ - - -/* - * Different kinds of 4x4 transformation matrices. - * We use these to select specific optimized vertex transformation routines. - */ -enum CoglMatrixType { - COGL_MATRIX_TYPE_GENERAL, /**< general 4x4 matrix */ - COGL_MATRIX_TYPE_IDENTITY, /**< identity matrix */ - COGL_MATRIX_TYPE_3D_NO_ROT, /**< orthogonal projection and others... */ - COGL_MATRIX_TYPE_PERSPECTIVE, /**< perspective projection matrix */ - COGL_MATRIX_TYPE_2D, /**< 2-D transformation */ - COGL_MATRIX_TYPE_2D_NO_ROT, /**< 2-D scale & translate only */ - COGL_MATRIX_TYPE_3D /**< 3-D transformation */ -} ; - - -#if 0 -/* - * Matrix type to represent 4x4 transformation matrices. - */ -typedef struct { - float *m; /**< 16 matrix elements (16-byte aligned) */ - float *inv; /**< optional 16-element inverse (16-byte aligned) */ - unsigned int flags; /**< possible values determined by (of \link - * MatFlags MAT_FLAG_* flags\endlink) - */ - enum CoglMatrixType type; -} CoglMatrix; -#endif - - -void -_math_matrix_multiply (CoglMatrix *result, - const CoglMatrix *a, - const CoglMatrix *b); - -void -_math_matrix_multiply_array (CoglMatrix *result, const float *b); - -void -_math_matrix_init_from_array (CoglMatrix *matrix, const float *array); - -void -_math_matrix_translate (CoglMatrix *matrix, float x, float y, float z); - -void -_math_matrix_rotate (CoglMatrix *matrix, float angle, - float x, float y, float z); - -void -_math_matrix_scale (CoglMatrix *matrix, float x, float y, float z); - -void -_math_matrix_ortho (CoglMatrix *matrix, - float left, float right, - float bottom, float top, - float nearval, float farval); - -void -_math_matrix_frustum (CoglMatrix *matrix, - float left, float right, - float bottom, float top, - float nearval, float farval); - -void -_math_matrix_viewport (CoglMatrix *matrix, - float x, float y, float width, float height, - float z_near, float z_far, float depth_max); - -void -_math_matrix_init_identity (CoglMatrix *matrix); - -gboolean -_math_matrix_update_inverse (CoglMatrix *matrix); - -void -_math_matrix_update_type_and_flags (CoglMatrix *matrix); - -void -_math_matrix_print (const CoglMatrix *matrix); - -gboolean -_math_matrix_is_length_preserving (const CoglMatrix *matrix); - -gboolean -_math_matrix_has_rotation (const CoglMatrix *matrix); - -gboolean -_math_matrix_is_general_scale (const CoglMatrix *matrix); - -gboolean -_math_matrix_is_dirty (const CoglMatrix *matrix); - - -/* - * \name Related functions that don't actually operate on CoglMatrix structs - */ -/*@{*/ - -void -_math_transposef ( float to[16], const float from[16]); - -void -_math_transposed (double to[16], const double from[16]); - -void -_math_transposefd (float to[16], const double from[16]); - - -/* - * Transform a point (column vector) by a matrix: Q = M * P - */ -#define TRANSFORM_POINT( Q, M, P ) \ - Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; \ - Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; \ - Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; \ - Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; - - -#define TRANSFORM_POINT3( Q, M, P ) \ - Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; \ - Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; \ - Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; \ - Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; - - -/* - * Transform a normal (row vector) by a matrix: [NX NY NZ] = N * MAT - */ -#define TRANSFORM_NORMAL( TO, N, MAT ) \ -do { \ - TO[0] = N[0] * MAT[0] + N[1] * MAT[1] + N[2] * MAT[2]; \ - TO[1] = N[0] * MAT[4] + N[1] * MAT[5] + N[2] * MAT[6]; \ - TO[2] = N[0] * MAT[8] + N[1] * MAT[9] + N[2] * MAT[10]; \ -} while (0) - - -/* - * Transform a direction by a matrix. - */ -#define TRANSFORM_DIRECTION( TO, DIR, MAT ) \ -do { \ - TO[0] = DIR[0] * MAT[0] + DIR[1] * MAT[4] + DIR[2] * MAT[8]; \ - TO[1] = DIR[0] * MAT[1] + DIR[1] * MAT[5] + DIR[2] * MAT[9]; \ - TO[2] = DIR[0] * MAT[2] + DIR[1] * MAT[6] + DIR[2] * MAT[10];\ -} while (0) - - -void -_mesa_transform_vector (float u[4], const float v[4], const float m[16]); - - -/*@}*/ - - -#endif diff --git a/clutter/cogl/cogl/cogl-matrix-private.h b/clutter/cogl/cogl/cogl-matrix-private.h deleted file mode 100644 index 7414e5b..0000000 --- a/clutter/cogl/cogl/cogl-matrix-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_MATRIX_PRIVATE_H -#define __COGL_MATRIX_PRIVATE_H - -#include - -G_BEGIN_DECLS - -#define _COGL_MATRIX_DEBUG_PRINT(MATRIX) \ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_MATRICES))) \ - { \ - g_print ("%s:\n", G_STRFUNC); \ - _cogl_matrix_print (MATRIX); \ - } - -void -_cogl_matrix_print (CoglMatrix *matrix); - -G_END_DECLS - -#endif /* __COGL_MATRIX_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-matrix-stack.c b/clutter/cogl/cogl/cogl-matrix-stack.c deleted file mode 100644 index d844c7b..0000000 --- a/clutter/cogl/cogl/cogl-matrix-stack.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Havoc Pennington for litl - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-context-private.h" -#include "cogl-internal.h" -#include "cogl-matrix-stack.h" -#include "cogl-framebuffer-private.h" -#include "cogl-object-private.h" - -typedef struct { - CoglMatrix matrix; - gboolean is_identity; - /* count of pushes with no changes; when a change is - * requested, we create a new state and decrement this - */ - int push_count; -} CoglMatrixState; - -/** - * CoglMatrixStack: - * - * Stores a cogl-side matrix stack, which we use as a cache - * so we can get the matrix efficiently when using indirect - * rendering. - */ -struct _CoglMatrixStack -{ - CoglObject _parent; - - GArray *stack; - - /* which state does GL have, NULL if unknown */ - CoglMatrixState *flushed_state; - gboolean flushed_identity; - - unsigned int age; -}; - -static void _cogl_matrix_stack_free (CoglMatrixStack *stack); - -COGL_OBJECT_INTERNAL_DEFINE (MatrixStack, matrix_stack); - -/* XXX: this doesn't initialize the matrix! */ -static void -_cogl_matrix_state_init (CoglMatrixState *state) -{ - state->push_count = 0; - state->is_identity = FALSE; -} - -static CoglMatrixState * -_cogl_matrix_stack_top (CoglMatrixStack *stack) -{ - return &g_array_index (stack->stack, CoglMatrixState, stack->stack->len - 1); -} - -/* XXX: - * Operations like scale, translate, rotate etc need to have an - * initialized state->matrix to work with, so they will pass - * initialize = TRUE. - * - * _cogl_matrix_stack_load_identity and _cogl_matrix_stack_set on the - * other hand don't so they will pass initialize = FALSE - * - * NB: Identity matrices are represented by setting - * state->is_identity=TRUE in which case state->matrix will be - * uninitialized. - */ -static CoglMatrixState * -_cogl_matrix_stack_top_mutable (CoglMatrixStack *stack, - gboolean initialize) -{ - CoglMatrixState *state; - CoglMatrixState *new_top; - - state = _cogl_matrix_stack_top (stack); - - if (state->push_count == 0) - { - if (state->is_identity && initialize) - cogl_matrix_init_identity (&state->matrix); - return state; - } - - state->push_count -= 1; - - g_array_set_size (stack->stack, stack->stack->len + 1); - new_top = &g_array_index (stack->stack, CoglMatrixState, - stack->stack->len - 1); - _cogl_matrix_state_init (new_top); - - if (initialize) - { - if (state->is_identity) - cogl_matrix_init_identity (&new_top->matrix); - else - new_top->matrix = state->matrix; - - if (stack->flushed_state == state) - stack->flushed_state = new_top; - } - - return new_top; -} - -CoglMatrixStack* -_cogl_matrix_stack_new (void) -{ - CoglMatrixStack *stack; - CoglMatrixState *state; - - stack = g_slice_new0 (CoglMatrixStack); - - stack->stack = g_array_sized_new (FALSE, FALSE, - sizeof (CoglMatrixState), 10); - g_array_set_size (stack->stack, 1); - state = &g_array_index (stack->stack, CoglMatrixState, 0); - _cogl_matrix_state_init (state); - state->is_identity = TRUE; - - stack->age = 0; - - return _cogl_matrix_stack_object_new (stack); -} - -static void -_cogl_matrix_stack_free (CoglMatrixStack *stack) -{ - g_array_free (stack->stack, TRUE); - g_slice_free (CoglMatrixStack, stack); -} - -void -_cogl_matrix_stack_push (CoglMatrixStack *stack) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top (stack); - - /* we lazily create a new stack top if someone changes the matrix - * while push_count > 0 - */ - state->push_count += 1; -} - -void -_cogl_matrix_stack_pop (CoglMatrixStack *stack) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top (stack); - - if (state->push_count > 0) - { - state->push_count -= 1; - } - else - { - if (stack->stack->len == 1) - { - g_warning ("Too many matrix pops"); - return; - } - - if (stack->flushed_state == state) - { - stack->flushed_state = NULL; - } - - stack->age++; - g_array_set_size (stack->stack, stack->stack->len - 1); - } -} - -void -_cogl_matrix_stack_load_identity (CoglMatrixStack *stack) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, FALSE); - - /* NB: Identity matrices are represented by setting - * state->is_identity = TRUE and leaving state->matrix - * uninitialized. - * - * This is done to optimize the heavy usage of - * _cogl_matrix_stack_load_identity by the Cogl Journal. - */ - if (!state->is_identity) - { - state->is_identity = TRUE; - - /* mark dirty */ - stack->flushed_state = NULL; - stack->age++; - } -} - -void -_cogl_matrix_stack_scale (CoglMatrixStack *stack, - float x, - float y, - float z) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - cogl_matrix_scale (&state->matrix, x, y, z); - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -void -_cogl_matrix_stack_translate (CoglMatrixStack *stack, - float x, - float y, - float z) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - cogl_matrix_translate (&state->matrix, x, y, z); - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -void -_cogl_matrix_stack_rotate (CoglMatrixStack *stack, - float angle, - float x, - float y, - float z) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - cogl_matrix_rotate (&state->matrix, angle, x, y, z); - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -void -_cogl_matrix_stack_multiply (CoglMatrixStack *stack, - const CoglMatrix *matrix) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - cogl_matrix_multiply (&state->matrix, &state->matrix, matrix); - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -void -_cogl_matrix_stack_frustum (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - cogl_matrix_frustum (&state->matrix, - left, right, bottom, top, - z_near, z_far); - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -void -_cogl_matrix_stack_perspective (CoglMatrixStack *stack, - float fov_y, - float aspect, - float z_near, - float z_far) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - cogl_matrix_perspective (&state->matrix, - fov_y, aspect, z_near, z_far); - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -void -_cogl_matrix_stack_ortho (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - cogl_matrix_ortho (&state->matrix, - left, right, bottom, top, z_near, z_far); - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -gboolean -_cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, - CoglMatrix *inverse) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, TRUE); - - return cogl_matrix_get_inverse (&state->matrix, inverse); -} - -void -_cogl_matrix_stack_get (CoglMatrixStack *stack, - CoglMatrix *matrix) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top (stack); - - /* NB: identity matrices are lazily initialized because we can often avoid - * initializing them at all if nothing is pushed on top of them since we - * load them using glLoadIdentity() - * - * The Cogl journal typically loads an identiy matrix because it performs - * software transformations, which is why we have optimized this case. - */ - if (state->is_identity) - cogl_matrix_init_identity (matrix); - else - *matrix = state->matrix; -} - -void -_cogl_matrix_stack_set (CoglMatrixStack *stack, - const CoglMatrix *matrix) -{ - CoglMatrixState *state; - - state = _cogl_matrix_stack_top_mutable (stack, FALSE); - state->matrix = *matrix; - /* mark dirty */ - stack->flushed_state = NULL; - state->is_identity = FALSE; - stack->age++; -} - -#ifndef HAVE_COGL_GLES2 - -static void -flush_to_fixed_api_gl (gboolean is_identity, - const CoglMatrix *matrix, - void *user_data) -{ - CoglMatrixStack *stack = user_data; - - if (is_identity) - { - if (!stack->flushed_identity) - GE (glLoadIdentity ()); - stack->flushed_identity = TRUE; - } - else - { - GE (glLoadMatrixf (cogl_matrix_get_array (matrix)) ); - stack->flushed_identity = FALSE; - } -} - -#endif /* HAVE_COGL_GLES2 */ - -void -_cogl_matrix_stack_prepare_for_flush (CoglMatrixStack *stack, - CoglMatrixMode mode, - CoglMatrixStackFlushFunc callback, - void *user_data) -{ - CoglMatrixState *state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - state = _cogl_matrix_stack_top (stack); - - /* Because Cogl defines texture coordinates to have a top left origin and - * because offscreen framebuffers may be used for rendering to textures we - * always render upside down to offscreen buffers. - */ - if (mode == COGL_MATRIX_PROJECTION && - cogl_is_offscreen (cogl_get_draw_framebuffer ())) - { - CoglMatrix flipped_projection; - CoglMatrix *projection = - state->is_identity ? &ctx->identity_matrix : &state->matrix; - - cogl_matrix_multiply (&flipped_projection, - &ctx->y_flip_matrix, projection); - callback (FALSE, &flipped_projection, user_data); - } - else - callback (state->is_identity, - state->is_identity ? &ctx->identity_matrix : &state->matrix, - user_data); -} - -void -_cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack, - CoglMatrixMode mode) -{ - CoglMatrixState *state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - state = _cogl_matrix_stack_top (stack); - -#ifdef HAVE_COGL_GLES2 - - /* Under GLES2 we need to flush the matrices differently because - they are stored in uniforms attached to the program instead of - the global GL context state. At this point we can't be sure that - the right program will be generated so instead we'll just store a - reference to the matrix stack that is intended to be flushed and - update the uniform once the program is ready. */ - - switch (mode) - { - case COGL_MATRIX_MODELVIEW: - cogl_object_ref (stack); - if (ctx->flushed_modelview_stack) - cogl_object_unref (ctx->flushed_modelview_stack); - ctx->flushed_modelview_stack = stack; - break; - - case COGL_MATRIX_PROJECTION: - cogl_object_ref (stack); - if (ctx->flushed_projection_stack) - cogl_object_unref (ctx->flushed_projection_stack); - ctx->flushed_projection_stack = stack; - break; - - case COGL_MATRIX_TEXTURE: - /* This shouldn't happen because the texture matrices are - handled by the GLSL pipeline backend */ - g_assert_not_reached (); - break; - } - -#else /* HAVE_COGL_GLES2 */ - - if (stack->flushed_state == state) - return; - - if (ctx->flushed_matrix_mode != mode) - { - GLenum gl_mode = 0; - - switch (mode) - { - case COGL_MATRIX_MODELVIEW: - gl_mode = GL_MODELVIEW; - break; - - case COGL_MATRIX_PROJECTION: - gl_mode = GL_PROJECTION; - break; - - case COGL_MATRIX_TEXTURE: - gl_mode = GL_TEXTURE; - break; - } - - GE (glMatrixMode (gl_mode)); - ctx->flushed_matrix_mode = mode; - } - - _cogl_matrix_stack_prepare_for_flush (stack, - mode, - flush_to_fixed_api_gl, - stack); - -#endif /* HAVE_COGL_GLES2 */ - - stack->flushed_state = state; -} - -void -_cogl_matrix_stack_dirty (CoglMatrixStack *stack) -{ - stack->flushed_state = NULL; - stack->flushed_identity = FALSE; -} - -unsigned int -_cogl_matrix_stack_get_age (CoglMatrixStack *stack) -{ - return stack->age; -} - -gboolean -_cogl_matrix_stack_has_identity_flag (CoglMatrixStack *stack) -{ - return _cogl_matrix_stack_top (stack)->is_identity; -} diff --git a/clutter/cogl/cogl/cogl-matrix-stack.h b/clutter/cogl/cogl/cogl-matrix-stack.h deleted file mode 100644 index 3368f1b..0000000 --- a/clutter/cogl/cogl/cogl-matrix-stack.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Havoc Pennington for litl - * Robert Bragg - */ - -#ifndef __COGL_MATRIX_STACK_H -#define __COGL_MATRIX_STACK_H - -#include "cogl-matrix.h" - -typedef struct _CoglMatrixStack CoglMatrixStack; - -typedef enum { - COGL_MATRIX_MODELVIEW, - COGL_MATRIX_PROJECTION, - COGL_MATRIX_TEXTURE -} CoglMatrixMode; - -typedef void (* CoglMatrixStackFlushFunc) (gboolean is_identity, - const CoglMatrix *matrix, - void *user_data); - -CoglMatrixStack * -_cogl_matrix_stack_new (void); - -void -_cogl_matrix_stack_push (CoglMatrixStack *stack); - -void -_cogl_matrix_stack_pop (CoglMatrixStack *stack); - -void -_cogl_matrix_stack_load_identity (CoglMatrixStack *stack); - -void -_cogl_matrix_stack_scale (CoglMatrixStack *stack, - float x, - float y, - float z); -void -_cogl_matrix_stack_translate (CoglMatrixStack *stack, - float x, - float y, - float z); -void -_cogl_matrix_stack_rotate (CoglMatrixStack *stack, - float angle, - float x, - float y, - float z); -void -_cogl_matrix_stack_multiply (CoglMatrixStack *stack, - const CoglMatrix *matrix); -void -_cogl_matrix_stack_frustum (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); -void -_cogl_matrix_stack_perspective (CoglMatrixStack *stack, - float fov_y, - float aspect, - float z_near, - float z_far); -void -_cogl_matrix_stack_ortho (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); -gboolean -_cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, - CoglMatrix *inverse); -void -_cogl_matrix_stack_get (CoglMatrixStack *stack, - CoglMatrix *matrix); -void -_cogl_matrix_stack_set (CoglMatrixStack *stack, - const CoglMatrix *matrix); -void -_cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack, - CoglMatrixMode mode); -void -_cogl_matrix_stack_dirty (CoglMatrixStack *stack); - -unsigned int -_cogl_matrix_stack_get_age (CoglMatrixStack *stack); - -/* If this returns TRUE then the top of the matrix is definitely the - identity matrix. If it returns FALSE it may or may not be the - identity matrix but no expensive comparison is performed to verify - it. */ -gboolean -_cogl_matrix_stack_has_identity_flag (CoglMatrixStack *stack); - -void -_cogl_matrix_stack_prepare_for_flush (CoglMatrixStack *stack, - CoglMatrixMode mode, - CoglMatrixStackFlushFunc callback, - void *user_data); - -#endif /* __COGL_MATRIX_STACK_H */ diff --git a/clutter/cogl/cogl/cogl-matrix.c b/clutter/cogl/cogl/cogl-matrix.c deleted file mode 100644 index 625b89f..0000000 --- a/clutter/cogl/cogl/cogl-matrix.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define USE_MESA_MATRIX_API - -#include -#include "cogl-debug.h" -#include -#include -#ifdef USE_MESA_MATRIX_API -#include -#endif - -#include -#include -#include - -#ifdef _COGL_SUPPORTS_GTYPE_INTEGRATION -#include -COGL_GTYPE_DEFINE_BOXED ("Matrix", matrix, - cogl_matrix_copy, - cogl_matrix_free); -#endif - -void -_cogl_matrix_print (CoglMatrix *matrix) -{ - float *m = (float *)matrix; - int y; - - for (y = 0; y < 4; y++) - g_print ("\t%6.4f %6.4f %6.4f %6.4f\n", m[y], m[4+y], m[8+y], m[12+y]); -} - -void -cogl_matrix_init_identity (CoglMatrix *matrix) -{ -#ifndef USE_MESA_MATRIX_API - matrix->xx = 1; matrix->xy = 0; matrix->xz = 0; matrix->xw = 0; - matrix->yx = 0; matrix->yy = 1; matrix->yz = 0; matrix->yw = 0; - matrix->zx = 0; matrix->zy = 0; matrix->zz = 1; matrix->zw = 0; - matrix->wx = 0; matrix->wy = 0; matrix->wz = 0; matrix->ww = 1; -#else - _math_matrix_init_identity (matrix); -#endif - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_matrix_multiply (CoglMatrix *result, - const CoglMatrix *a, - const CoglMatrix *b) -{ -#ifndef USE_MESA_MATRIX_API - CoglMatrix r; - - /* row 0 */ - r.xx = a->xx * b->xx + a->xy * b->yx + a->xz * b->zx + a->xw * b->wx; - r.xy = a->xx * b->xy + a->xy * b->yy + a->xz * b->zy + a->xw * b->wy; - r.xz = a->xx * b->xz + a->xy * b->yz + a->xz * b->zz + a->xw * b->wz; - r.xw = a->xx * b->xw + a->xy * b->yw + a->xz * b->zw + a->xw * b->ww; - - /* row 1 */ - r.yx = a->yx * b->xx + a->yy * b->yx + a->yz * b->zx + a->yw * b->wx; - r.yy = a->yx * b->xy + a->yy * b->yy + a->yz * b->zy + a->yw * b->wy; - r.yz = a->yx * b->xz + a->yy * b->yz + a->yz * b->zz + a->yw * b->wz; - r.yw = a->yx * b->xw + a->yy * b->yw + a->yz * b->zw + a->yw * b->ww; - - /* row 2 */ - r.zx = a->zx * b->xx + a->zy * b->yx + a->zz * b->zx + a->zw * b->wx; - r.zy = a->zx * b->xy + a->zy * b->yy + a->zz * b->zy + a->zw * b->wy; - r.zz = a->zx * b->xz + a->zy * b->yz + a->zz * b->zz + a->zw * b->wz; - r.zw = a->zx * b->xw + a->zy * b->yw + a->zz * b->zw + a->zw * b->ww; - - /* row 3 */ - r.wx = a->wx * b->xx + a->wy * b->yx + a->wz * b->zx + a->ww * b->wx; - r.wy = a->wx * b->xy + a->wy * b->yy + a->wz * b->zy + a->ww * b->wy; - r.wz = a->wx * b->xz + a->wy * b->yz + a->wz * b->zz + a->ww * b->wz; - r.ww = a->wx * b->xw + a->wy * b->yw + a->wz * b->zw + a->ww * b->ww; - - /* The idea was that having this unrolled; it might be easier for the - * compiler to vectorize, but that's probably not true. Mesa does it - * using a single for (i=0; i<4; i++) approach, maybe that's better... - */ - - *result = r; -#else - _math_matrix_multiply (result, a, b); -#endif - _COGL_MATRIX_DEBUG_PRINT (result); -} - -void -cogl_matrix_rotate (CoglMatrix *matrix, - float angle, - float x, - float y, - float z) -{ -#ifndef USE_MESA_MATRIX_API - CoglMatrix rotation; - CoglMatrix result; - float c, s; - - angle *= G_PI / 180.0f; - c = cosf (angle); - s = sinf (angle); - - rotation.xx = x * x * (1.0f - c) + c; - rotation.yx = y * x * (1.0f - c) + z * s; - rotation.zx = x * z * (1.0f - c) - y * s; - rotation.wx = 0.0f; - - rotation.xy = x * y * (1.0f - c) - z * s; - rotation.yy = y * y * (1.0f - c) + c; - rotation.zy = y * z * (1.0f - c) + x * s; - rotation.wy = 0.0f; - - rotation.xz = x * z * (1.0f - c) + y * s; - rotation.yz = y * z * (1.0f - c) - x * s; - rotation.zz = z * z * (1.0f - c) + c; - rotation.wz = 0.0f; - - rotation.xw = 0.0f; - rotation.yw = 0.0f; - rotation.zw = 0.0f; - rotation.ww = 1.0f; - - cogl_matrix_multiply (&result, matrix, &rotation); - *matrix = result; -#else - _math_matrix_rotate (matrix, angle, x, y, z); -#endif - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_matrix_translate (CoglMatrix *matrix, - float x, - float y, - float z) -{ -#ifndef USE_MESA_MATRIX_API - matrix->xw = matrix->xx * x + matrix->xy * y + matrix->xz * z + matrix->xw; - matrix->yw = matrix->yx * x + matrix->yy * y + matrix->yz * z + matrix->yw; - matrix->zw = matrix->zx * x + matrix->zy * y + matrix->zz * z + matrix->zw; - matrix->ww = matrix->wx * x + matrix->wy * y + matrix->wz * z + matrix->ww; -#else - _math_matrix_translate (matrix, x, y, z); -#endif - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_matrix_scale (CoglMatrix *matrix, - float sx, - float sy, - float sz) -{ -#ifndef USE_MESA_MATRIX_API - matrix->xx *= sx; matrix->xy *= sy; matrix->xz *= sz; - matrix->yx *= sx; matrix->yy *= sy; matrix->yz *= sz; - matrix->zx *= sx; matrix->zy *= sy; matrix->zz *= sz; - matrix->wx *= sx; matrix->wy *= sy; matrix->wz *= sz; -#else - _math_matrix_scale (matrix, sx, sy, sz); -#endif - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_matrix_frustum (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ -#ifndef USE_MESA_MATRIX_API - float x, y, a, b, c, d; - CoglMatrix frustum; - - x = (2.0f * z_near) / (right - left); - y = (2.0f * z_near) / (top - bottom); - a = (right + left) / (right - left); - b = (top + bottom) / (top - bottom); - c = -(z_far + z_near) / ( z_far - z_near); - d = -(2.0f * z_far* z_near) / (z_far - z_near); - - frustum.xx = x; - frustum.yx = 0.0f; - frustum.zx = 0.0f; - frustum.wx = 0.0f; - - frustum.xy = 0.0f; - frustum.yy = y; - frustum.zy = 0.0f; - frustum.wy = 0.0f; - - frustum.xz = a; - frustum.yz = b; - frustum.zz = c; - frustum.wz = -1.0f; - - frustum.xw = 0.0f; - frustum.yw = 0.0f; - frustum.zw = d; - frustum.ww = 0.0f; - - cogl_matrix_multiply (matrix, matrix, &frustum); -#else - _math_matrix_frustum (matrix, left, right, bottom, top, z_near, z_far); -#endif - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_matrix_perspective (CoglMatrix *matrix, - float fov_y, - float aspect, - float z_near, - float z_far) -{ - float ymax = z_near * tan (fov_y * G_PI / 360.0); - - cogl_matrix_frustum (matrix, - -ymax * aspect, /* left */ - ymax * aspect, /* right */ - -ymax, /* bottom */ - ymax, /* top */ - z_near, - z_far); - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_matrix_ortho (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float near_val, - float far_val) -{ -#ifndef USE_MESA_MATRIX_API - CoglMatrix ortho; - - /* column 0 */ - ortho.xx = 2.0 / (right - left); - ortho.yx = 0.0; - ortho.zx = 0.0; - ortho.wx = 0.0; - - /* column 1 */ - ortho.xy = 0.0; - ortho.yy = 2.0 / (top - bottom); - ortho.zy = 0.0; - ortho.wy = 0.0; - - /* column 2 */ - ortho.xz = 0.0; - ortho.yz = 0.0; - ortho.zz = -2.0 / (far_val - near_val); - ortho.wz = 0.0; - - /* column 3 */ - ortho.xw = -(right + left) / (right - left); - ortho.yw = -(top + bottom) / (top - bottom); - ortho.zw = -(far_val + near_val) / (far_val - near_val); - ortho.ww = 1.0; - - cogl_matrix_multiply (matrix, matrix, &ortho); -#else - _math_matrix_ortho (matrix, left, right, bottom, top, near_val, far_val); -#endif - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_matrix_view_2d_in_frustum (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float z_near, - float z_2d, - float width_2d, - float height_2d) -{ - float left_2d_plane = left / z_near * z_2d; - float right_2d_plane = right / z_near * z_2d; - float bottom_2d_plane = bottom / z_near * z_2d; - float top_2d_plane = top / z_near * z_2d; - - float width_2d_start = right_2d_plane - left_2d_plane; - float height_2d_start = top_2d_plane - bottom_2d_plane; - - /* Factors to scale from framebuffer geometry to frustum - * cross-section geometry. */ - float width_scale = width_2d_start / width_2d; - float height_scale = height_2d_start / height_2d; - - cogl_matrix_translate (matrix, - left_2d_plane, top_2d_plane, -z_2d); - - cogl_matrix_scale (matrix, width_scale, -height_scale, width_scale); -} - -/* Assuming a symmetric perspective matrix is being used for your - * projective transform this convenience function lets you compose a - * view transform such that geometry on the z=0 plane will map to - * screen coordinates with a top left origin of (0,0) and with the - * given width and height. - */ -void -cogl_matrix_view_2d_in_perspective (CoglMatrix *matrix, - float fov_y, - float aspect, - float z_near, - float z_2d, - float width_2d, - float height_2d) -{ - float top = z_near * tan (fov_y * G_PI / 360.0); - cogl_matrix_view_2d_in_frustum (matrix, - -top * aspect, - top * aspect, - -top, - top, - z_near, - z_2d, - width_2d, - height_2d); -} - -void -cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array) -{ -#ifndef USE_MESA_MATRIX_API - memcpy (matrix, array, sizeof (float) * 16); -#else - _math_matrix_init_from_array (matrix, array); -#endif - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -gboolean -cogl_matrix_equal (gconstpointer v1, gconstpointer v2) -{ - const CoglMatrix *a = v1; - const CoglMatrix *b = v2; - - g_return_val_if_fail (v1 != NULL, FALSE); - g_return_val_if_fail (v2 != NULL, FALSE); - - /* We want to avoid having a fuzzy _equal() function (e.g. that uses - * an arbitrary epsilon value) since this function noteably conforms - * to the prototype suitable for use with g_hash_table_new() and a - * fuzzy hash function isn't really appropriate for comparing hash - * table keys since it's possible that you could end up fetching - * different values if you end up with multiple similar keys in use - * at the same time. If you consider that fuzzyness allows cases - * such as A == B == C but A != C then you could also end up loosing - * values in a hash table. - * - * We do at least use the == operator to compare values though so - * that -0 is considered equal to 0. - */ - - /* XXX: We don't compare the flags, inverse matrix or padding */ - if (a->xx == b->xx && - a->xy == b->xy && - a->xz == b->xz && - a->xw == b->xw && - a->yx == b->yx && - a->yy == b->yy && - a->yz == b->yz && - a->yw == b->yw && - a->zx == b->zx && - a->zy == b->zy && - a->zz == b->zz && - a->zw == b->zw && - a->wx == b->wx && - a->wy == b->wy && - a->wz == b->wz && - a->ww == b->ww) - return TRUE; - else - return FALSE; -} - -CoglMatrix * -cogl_matrix_copy (const CoglMatrix *matrix) -{ - if (G_LIKELY (matrix)) - return g_slice_dup (CoglMatrix, matrix); - - return NULL; -} - -void -cogl_matrix_free (CoglMatrix *matrix) -{ - g_slice_free (CoglMatrix, matrix); -} - -const float * -cogl_matrix_get_array (const CoglMatrix *matrix) -{ - return (float *)matrix; -} - -gboolean -cogl_matrix_get_inverse (const CoglMatrix *matrix, CoglMatrix *inverse) -{ -#ifndef USE_MESA_MATRIX_API -#warning "cogl_matrix_get_inverse not supported without Mesa matrix API" - cogl_matrix_init_identity (inverse); - return FALSE; -#else - if (_math_matrix_update_inverse ((CoglMatrix *)matrix)) - { - cogl_matrix_init_from_array (inverse, matrix->inv); - return TRUE; - } - else - { - cogl_matrix_init_identity (inverse); - return FALSE; - } -#endif -} - -void -cogl_matrix_transform_point (const CoglMatrix *matrix, - float *x, - float *y, - float *z, - float *w) -{ - float _x = *x, _y = *y, _z = *z, _w = *w; - - *x = matrix->xx * _x + matrix->xy * _y + matrix->xz * _z + matrix->xw * _w; - *y = matrix->yx * _x + matrix->yy * _y + matrix->yz * _z + matrix->yw * _w; - *z = matrix->zx * _x + matrix->zy * _y + matrix->zz * _z + matrix->zw * _w; - *w = matrix->wx * _x + matrix->wy * _y + matrix->wz * _z + matrix->ww * _w; -} - -typedef struct _Point2f -{ - float x; - float y; -} Point2f; - -typedef struct _Point3f -{ - float x; - float y; - float z; -} Point3f; - -typedef struct _Point4f -{ - float x; - float y; - float z; - float w; -} Point4f; - -static void -_cogl_matrix_transform_points_f2 (const CoglMatrix *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - int i; - - for (i = 0; i < n_points; i++) - { - Point2f p = *(Point2f *)((guint8 *)points_in + i * stride_in); - Point3f *o = (Point3f *)((guint8 *)points_out + i * stride_out); - - o->x = matrix->xx * p.x + matrix->xy * p.y + matrix->xw; - o->y = matrix->yx * p.x + matrix->yy * p.y + matrix->yw; - o->z = matrix->zx * p.x + matrix->zy * p.y + matrix->zw; - } -} - -static void -_cogl_matrix_project_points_f2 (const CoglMatrix *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - int i; - - for (i = 0; i < n_points; i++) - { - Point2f p = *(Point2f *)((guint8 *)points_in + i * stride_in); - Point4f *o = (Point4f *)((guint8 *)points_out + i * stride_out); - - o->x = matrix->xx * p.x + matrix->xy * p.y + matrix->xw; - o->y = matrix->yx * p.x + matrix->yy * p.y + matrix->yw; - o->z = matrix->zx * p.x + matrix->zy * p.y + matrix->zw; - o->w = matrix->wx * p.x + matrix->wy * p.y + matrix->ww; - } -} - -static void -_cogl_matrix_transform_points_f3 (const CoglMatrix *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - int i; - - for (i = 0; i < n_points; i++) - { - Point3f p = *(Point3f *)((guint8 *)points_in + i * stride_in); - Point3f *o = (Point3f *)((guint8 *)points_out + i * stride_out); - - o->x = matrix->xx * p.x + matrix->xy * p.y + - matrix->xz * p.z + matrix->xw; - o->y = matrix->yx * p.x + matrix->yy * p.y + - matrix->yz * p.z + matrix->yw; - o->z = matrix->zx * p.x + matrix->zy * p.y + - matrix->zz * p.z + matrix->zw; - } -} - -static void -_cogl_matrix_project_points_f3 (const CoglMatrix *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - int i; - - for (i = 0; i < n_points; i++) - { - Point3f p = *(Point3f *)((guint8 *)points_in + i * stride_in); - Point4f *o = (Point4f *)((guint8 *)points_out + i * stride_out); - - o->x = matrix->xx * p.x + matrix->xy * p.y + - matrix->xz * p.z + matrix->xw; - o->y = matrix->yx * p.x + matrix->yy * p.y + - matrix->yz * p.z + matrix->yw; - o->z = matrix->zx * p.x + matrix->zy * p.y + - matrix->zz * p.z + matrix->zw; - o->w = matrix->wx * p.x + matrix->wy * p.y + - matrix->wz * p.z + matrix->ww; - } -} - -static void -_cogl_matrix_project_points_f4 (const CoglMatrix *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - int i; - - for (i = 0; i < n_points; i++) - { - Point4f p = *(Point4f *)((guint8 *)points_in + i * stride_in); - Point4f *o = (Point4f *)((guint8 *)points_out + i * stride_out); - - o->x = matrix->xx * p.x + matrix->xy * p.y + - matrix->xz * p.z + matrix->xw * p.w; - o->y = matrix->yx * p.x + matrix->yy * p.y + - matrix->yz * p.z + matrix->yw * p.w; - o->z = matrix->zx * p.x + matrix->zy * p.y + - matrix->zz * p.z + matrix->zw * p.w; - o->w = matrix->wx * p.x + matrix->wy * p.y + - matrix->wz * p.z + matrix->ww * p.w; - } -} - -void -cogl_matrix_transform_points (const CoglMatrix *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - /* The results of transforming always have three components... */ - g_return_if_fail (stride_out >= sizeof (Point3f)); - - if (n_components == 2) - _cogl_matrix_transform_points_f2 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - else - { - g_return_if_fail (n_components == 3); - - _cogl_matrix_transform_points_f3 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } -} - -void -cogl_matrix_project_points (const CoglMatrix *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - if (n_components == 2) - _cogl_matrix_project_points_f2 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - else if (n_components == 3) - _cogl_matrix_project_points_f3 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - else - { - g_return_if_fail (n_components == 4); - - _cogl_matrix_project_points_f4 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } -} diff --git a/clutter/cogl/cogl/cogl-matrix.h b/clutter/cogl/cogl/cogl-matrix.h deleted file mode 100644 index 1db1d8f..0000000 --- a/clutter/cogl/cogl/cogl-matrix.h +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_MATRIX_H -#define __COGL_MATRIX_H - -#include -#include "cogl-types.h" - -G_BEGIN_DECLS - -/** - * SECTION:cogl-matrix - * @short_description: Fuctions for initializing and manipulating 4x4 matrices - * - * Matrices are used in Cogl to describe affine model-view transforms, texture - * transforms, and projective transforms. This exposes a utility API that can - * be used for direct manipulation of these matrices. - */ - -typedef struct _CoglMatrix CoglMatrix; - -/** - * CoglMatrix: - * - * A CoglMatrix holds a 4x4 transform matrix. This is a single precision, - * column-major matrix which means it is compatible with what OpenGL expects. - * - * A CoglMatrix can represent transforms such as, rotations, scaling, - * translation, sheering, and linear projections. You can combine these - * transforms by multiplying multiple matrices in the order you want them - * applied. - * - * The transformation of a vertex (x, y, z, w) by a CoglMatrix is given by: - * - * |[ - * x_new = xx * x + xy * y + xz * z + xw * w - * y_new = yx * x + yy * y + yz * z + yw * w - * z_new = zx * x + zy * y + zz * z + zw * w - * w_new = wx * x + wy * y + wz * z + ww * w - * ]| - * - * Where w is normally 1 - * - * You must consider the members of the CoglMatrix structure read only, - * and all matrix modifications must be done via the cogl_matrix API. This - * allows Cogl to annotate the matrices internally. Violation of this will give - * undefined results. If you need to initialize a matrix with a constant other - * than the identity matrix you can use cogl_matrix_init_from_array(). - */ -struct _CoglMatrix -{ - /* column 0 */ - float xx; - float yx; - float zx; - float wx; - - /* column 1 */ - float xy; - float yy; - float zy; - float wy; - - /* column 2 */ - float xz; - float yz; - float zz; - float wz; - - /* column 3 */ - float xw; - float yw; - float zw; - float ww; - - /*< private >*/ - - /* Note: we may want to extend this later with private flags - * and a cache of the inverse transform matrix. */ - float COGL_PRIVATE (inv)[16]; - unsigned long COGL_PRIVATE (type); - unsigned long COGL_PRIVATE (flags); - unsigned long COGL_PRIVATE (_padding3); -}; - -/** - * cogl_matrix_init_identity: - * @matrix: A 4x4 transformation matrix - * - * Resets matrix to the identity matrix: - * - * |[ - * .xx=1; .xy=0; .xz=0; .xw=0; - * .yx=0; .yy=1; .yz=0; .yw=0; - * .zx=0; .zy=0; .zz=1; .zw=0; - * .wx=0; .wy=0; .wz=0; .ww=1; - * ]| - */ -void -cogl_matrix_init_identity (CoglMatrix *matrix); - -/** - * cogl_matrix_multiply: - * @result: The address of a 4x4 matrix to store the result in - * @a: A 4x4 transformation matrix - * @b: A 4x4 transformation matrix - * - * Multiplies the two supplied matrices together and stores - * the resulting matrix inside @result. - * - * It is possible to multiply the @a matrix in-place, so - * @result can be equal to @a but can't be equal to @b. - */ -void -cogl_matrix_multiply (CoglMatrix *result, - const CoglMatrix *a, - const CoglMatrix *b); - -/** - * cogl_matrix_rotate: - * @matrix: A 4x4 transformation matrix - * @angle: The angle you want to rotate in degrees - * @x: X component of your rotation vector - * @y: Y component of your rotation vector - * @z: Z component of your rotation vector - * - * Multiplies @matrix with a rotation matrix that applies a rotation - * of @angle degrees around the specified 3D vector. - */ -void -cogl_matrix_rotate (CoglMatrix *matrix, - float angle, - float x, - float y, - float z); - -/** - * cogl_matrix_translate: - * @matrix: A 4x4 transformation matrix - * @x: The X translation you want to apply - * @y: The Y translation you want to apply - * @z: The Z translation you want to apply - * - * Multiplies @matrix with a transform matrix that translates along - * the X, Y and Z axis. - */ -void -cogl_matrix_translate (CoglMatrix *matrix, - float x, - float y, - float z); - -/** - * cogl_matrix_scale: - * @matrix: A 4x4 transformation matrix - * @sx: The X scale factor - * @sy: The Y scale factor - * @sz: The Z scale factor - * - * Multiplies @matrix with a transform matrix that scales along the X, - * Y and Z axis. - */ -void -cogl_matrix_scale (CoglMatrix *matrix, - float sx, - float sy, - float sz); - -/** - * cogl_matrix_frustum: - * @matrix: A 4x4 transformation matrix - * @left: coord of left vertical clipping plane - * @right: coord of right vertical clipping plane - * @bottom: coord of bottom horizontal clipping plane - * @top: coord of top horizontal clipping plane - * @z_near: positive distance to near depth clipping plane - * @z_far: positive distance to far depth clipping plane - * - * Multiplies @matrix by the given frustum perspective matrix. - */ -void -cogl_matrix_frustum (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -/** - * cogl_matrix_perspective: - * @matrix: A 4x4 transformation matrix - * @fov_y: A field of view angle for the Y axis - * @aspect: The ratio of width to height determining the field of view angle - * for the x axis. - * @z_near: The distance to the near clip plane. Never pass 0 and always pass - * a positive number. - * @z_far: The distance to the far clip plane. (Should always be positive) - * - * Multiplies @matrix by the described perspective matrix - * - * You should be careful not to have to great a @z_far / @z_near ratio - * since that will reduce the effectiveness of depth testing since there wont - * be enough precision to identify the depth of objects near to each - * other. - */ -void -cogl_matrix_perspective (CoglMatrix *matrix, - float fov_y, - float aspect, - float z_near, - float z_far); - -/** - * cogl_matrix_ortho: - * @matrix: A 4x4 transformation matrix - * @left: The coordinate for the left clipping plane - * @right: The coordinate for the right clipping plane - * @bottom: The coordinate for the bottom clipping plane - * @top: The coordinate for the top clipping plane - * @z_near: The coordinate for the near clipping plane (may be negative if - * the plane is behind the viewer) - * @z_far: The coordinate for the far clipping plane (may be negative if - * the plane is behind the viewer) - * - * Multiplies @matrix by a parallel projection matrix. - */ -void -cogl_matrix_ortho (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -#ifdef COGL_ENABLE_EXPERIMENTAL_API -#define cogl_matrix_view_2d_in_frustum cogl_matrix_view_2d_in_frustum_EXP -#define cogl_matrix_view_2d_in_perspective \ - cogl_matrix_view_2d_in_perspective_EXP - -/** - * cogl_matrix_view_2d_in_frustum: - * @matrix: A 4x4 transformation matrix - * @left: coord of left vertical clipping plane - * @right: coord of right vertical clipping plane - * @bottom: coord of bottom horizontal clipping plane - * @top: coord of top horizontal clipping plane - * @z_near: The distance to the near clip plane. Never pass 0 and always pass - * a positive number. - * @z_2d: The distance to the 2D plane. (Should always be positive and - * be between @z_near and the z_far value that was passed to - * cogl_matrix_frustum()) - * @width_2d: The width of the 2D coordinate system - * @height_2d: The height of the 2D coordinate system - * - * Multiplies @matrix by a view transform that maps the 2D coordinates - * (0,0) top left and (@width_2d,@height_2d) bottom right the full viewport - * size. Geometry at a depth of 0 will now lie on this 2D plane. - * - * Note: this doesn't multiply the matrix by any projection matrix, - * but it assumes you have a perspective projection as defined by - * passing the corresponding arguments to cogl_matrix_frustum(). - - * Toolkits such as Clutter that mix 2D and 3D drawing can use this to - * create a 2D coordinate system within a 3D perspective projected - * view frustum. - */ -void -cogl_matrix_view_2d_in_frustum (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float z_near, - float z_2d, - float width_2d, - float height_2d); - -/** - * cogl_matrix_view_2d_in_perspective: - * @fov_y: A field of view angle for the Y axis - * @aspect: The ratio of width to height determining the field of view angle - * for the x axis. - * @z_near: The distance to the near clip plane. Never pass 0 and always pass - * a positive number. - * @z_2d: The distance to the 2D plane. (Should always be positive and - * be between @z_near and the z_far value that was passed to - * cogl_matrix_frustum()) - * @width_2d: The width of the 2D coordinate system - * @height_2d: The height of the 2D coordinate system - * - * Multiplies @matrix by a view transform that maps the 2D coordinates - * (0,0) top left and (@width_2d,@height_2d) bottom right the full viewport - * size. Geometry at a depth of 0 will now lie on this 2D plane. - * - * Note: this doesn't multiply the matrix by any projection matrix, - * but it assumes you have a perspective projection as defined by - * passing the corresponding arguments to cogl_matrix_perspective(). - * - * Toolkits such as Clutter that mix 2D and 3D drawing can use this to - * create a 2D coordinate system within a 3D perspective projected - * view frustum. - - */ -void -cogl_matrix_view_2d_in_perspective (CoglMatrix *matrix, - float fov_y, - float aspect, - float z_near, - float z_2d, - float width_2d, - float height_2d); - -#endif - -/** - * cogl_matrix_init_from_array: - * @matrix: A 4x4 transformation matrix - * @array: A linear array of 16 floats (column-major order) - * - * Initializes @matrix with the contents of @array - */ -void -cogl_matrix_init_from_array (CoglMatrix *matrix, - const float *array); - -/** - * cogl_matrix_get_array: - * @matrix: A 4x4 transformation matrix - * - * Casts @matrix to a float array which can be directly passed to OpenGL. - * - * Return value: a pointer to the float array - */ -G_CONST_RETURN float * -cogl_matrix_get_array (const CoglMatrix *matrix); - -/** - * cogl_matrix_equal: - * @v1: A 4x4 transformation matrix - * @v2: A 4x4 transformation matrix - * - * Compares two matrices to see if they represent the same - * transformation. Although internally the matrices may have different - * annotations associated with them and may potentially have a cached - * inverse matrix these are not considered in the comparison. - * - * Since: 1.4 - */ -gboolean -cogl_matrix_equal (gconstpointer v1, gconstpointer v2); - -/** - * cogl_matrix_copy: - * @matrix: A 4x4 transformation matrix you want to copy - * - * Allocates a new #CoglMatrix on the heap and initializes it with - * the same values as @matrix. - * - * Returns: A newly allocated #CoglMatrix which should be freed using - * cogl_matrix_free() - * - * Since: 1.6 - */ -CoglMatrix * -cogl_matrix_copy (const CoglMatrix *matrix); - -/** - * cogl_matrix_free: - * @matrix: A 4x4 transformation matrix you want to free - * - * Frees a #CoglMatrix that was previously allocated via a call to - * cogl_matrix_copy(). - * - * Since: 1.6 - */ -void -cogl_matrix_free (CoglMatrix *matrix); - -/** - * cogl_matrix_get_inverse: - * @matrix: A 4x4 transformation matrix - * @inverse: (out): The destination for a 4x4 inverse transformation matrix - * - * Gets the inverse transform of a given matrix and uses it to initialize - * a new #CoglMatrix. - * - * Although the first parameter is annotated as const to indicate - * that the transform it represents isn't modified this function may - * technically save a copy of the inverse transform within the given - * #CoglMatrix so that subsequent requests for the inverse transform may - * avoid costly inversion calculations. - * - * Return value: %TRUE if the inverse was successfully calculated or %FALSE - * for degenerate transformations that can't be inverted (in this case the - * @inverse matrix will simply be initialized with the identity matrix) - * - * Since: 1.2 - */ -gboolean -cogl_matrix_get_inverse (const CoglMatrix *matrix, - CoglMatrix *inverse); - -/* FIXME: to be consistent with cogl_matrix_{transform,project}_points - * this could be renamed to cogl_matrix_project_point for Cogl 2.0... - */ - -/** - * cogl_matrix_transform_point: - * @matrix: A 4x4 transformation matrix - * @x: (inout): The X component of your points position - * @y: (inout): The Y component of your points position - * @z: (inout): The Z component of your points position - * @w: (inout): The W component of your points position - * - * Transforms a point whos position is given and returned as four float - * components. - */ -void -cogl_matrix_transform_point (const CoglMatrix *matrix, - float *x, - float *y, - float *z, - float *w); - -#ifdef COGL_ENABLE_EXPERIMENTAL_API -#define cogl_matrix_transform_points cogl_matrix_transform_points_EXP -#define cogl_matrix_project_points cogl_matrix_project_points_EXP - -/** - * cogl_matrix_transform_points: - * @matrix: A transformation matrix - * @n_components: The number of position components for each input point. - * (either 2 or 3) - * @stride_in: The stride in bytes between input points. - * @points_in: A pointer to the first component of the first input point. - * @stride_out: The stride in bytes between output points. - * @points_out: A pointer to the first component of the first output point. - * @n_points: The number of points to transform. - * - * Transforms an array of input points and writes the result to - * another array of output points. The input points can either have 2 - * or 3 components each. The output points always have 3 components. - * The output array can simply point to the input array to do the - * transform in-place. - * - * If you need to transform 4 component points see - * cogl_matrix_project_points(). - * - * Here's an example with differing input/output strides: - * |[ - * typedef struct { - * float x,y; - * guint8 r,g,b,a; - * float s,t,p; - * } MyInVertex; - * typedef struct { - * guint8 r,g,b,a; - * float x,y,z; - * } MyOutVertex; - * MyInVertex vertices[N_VERTICES]; - * MyOutVertex results[N_VERTICES]; - * CoglMatrix matrix; - * - * my_load_vertices (vertices); - * my_get_matrix (&matrix); - * - * cogl_matrix_transform_points (&matrix, - * 2, - * sizeof (MyInVertex), - * &vertices[0].x, - * sizeof (MyOutVertex), - * &results[0].x, - * N_VERTICES); - * ]| - * - * Stability: Unstable - */ -void -cogl_matrix_transform_points (const CoglMatrix *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points); - -/** - * cogl_matrix_project_points: - * @matrix: A projection matrix - * @n_components: The number of position components for each input point. - * (either 2, 3 or 4) - * @stride_in: The stride in bytes between input points. - * @points_in: A pointer to the first component of the first input point. - * @stride_out: The stride in bytes between output points. - * @points_out: A pointer to the first component of the first output point. - * @n_points: The number of points to transform. - * - * Projects an array of input points and writes the result to another - * array of output points. The input points can either have 2, 3 or 4 - * components each. The output points always have 4 components (known - * as homogenous coordinates). The output array can simply point to - * the input array to do the transform in-place. - * - * Here's an example with differing input/output strides: - * |[ - * typedef struct { - * float x,y; - * guint8 r,g,b,a; - * float s,t,p; - * } MyInVertex; - * typedef struct { - * guint8 r,g,b,a; - * float x,y,z; - * } MyOutVertex; - * MyInVertex vertices[N_VERTICES]; - * MyOutVertex results[N_VERTICES]; - * CoglMatrix matrix; - * - * my_load_vertices (vertices); - * my_get_matrix (&matrix); - * - * cogl_matrix_project_points (&matrix, - * 2, - * sizeof (MyInVertex), - * &vertices[0].x, - * sizeof (MyOutVertex), - * &results[0].x, - * N_VERTICES); - * ]| - * - * Stability: Unstable - */ -void -cogl_matrix_project_points (const CoglMatrix *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points); - -#endif /* COGL_ENABLE_EXPERIMENTAL_API */ - -#ifdef _COGL_SUPPORTS_GTYPE_INTEGRATION - -#define COGL_GTYPE_TYPE_MATRIX (cogl_gtype_matrix_get_type ()) - -/** - * cogl_gtype_matrix_get_type: - * - * Returns the GType for the registered "CoglMatrix" boxed type. This - * can be used for example to define GObject properties that accept a - * #CoglMatrix value. - */ -GType -cogl_gtype_matrix_get_type (void); - -#endif /* _COGL_SUPPORTS_GTYPE_INTEGRATION */ - -G_END_DECLS - -#endif /* __COGL_MATRIX_H */ - diff --git a/clutter/cogl/cogl/cogl-object-private.h b/clutter/cogl/cogl/cogl-object-private.h deleted file mode 100644 index e8b4ed0..0000000 --- a/clutter/cogl/cogl/cogl-object-private.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_OBJECT_PRIVATE_H -#define __COGL_OBJECT_PRIVATE_H - -#include - -#include "cogl-types.h" -#include "cogl-object.h" -#include "cogl-debug.h" - -/* For compatability until all components have been converted */ -typedef struct _CoglObjectClass CoglHandleClass; -typedef struct _CoglObject CoglHandleObject; - -/* XXX: sadly we didn't fully consider when we copied the cairo API - * for _set_user_data that the callback doesn't get a pointer to the - * instance which is desired in most cases. This means you tend to end - * up creating micro allocations for the private data just so you can - * pair up the data of interest with the original instance for - * identification when it is later destroyed. - * - * Internally we use a small hack to avoid needing these micro - * allocations by actually passing the instance as a second argument - * to the callback */ -typedef void (*CoglUserDataDestroyInternalCallback) (void *user_data, - void *instance); - -typedef struct _CoglObjectClass -{ - GQuark type; - void *virt_free; -} CoglObjectClass; - -#define COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES 2 - -typedef struct -{ - CoglUserDataKey *key; - void *user_data; - CoglUserDataDestroyInternalCallback destroy; -} CoglUserDataEntry; - -/* All Cogl objects inherit from this base object by adding a member: - * - * CoglObject _parent; - * - * at the top of its main structure. This structure is initialized - * when you call _cogl_#type_name#_object_new (new_object); - */ -struct _CoglObject -{ - unsigned int ref_count; - - CoglUserDataEntry user_data_entry[ - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES]; - GArray *user_data_array; - int n_user_data_entries; - - CoglObjectClass *klass; -}; - -/* Helper macro to encapsulate the common code for COGL reference - counted objects */ - -#ifdef COGL_OBJECT_DEBUG - -#define _COGL_OBJECT_DEBUG_NEW(type_name, obj) \ - COGL_NOTE (HANDLE, "COGL " G_STRINGIFY (type_name) " NEW %p %i", \ - (obj), (obj)->ref_count) - -#define _COGL_OBJECT_DEBUG_REF(type_name, object) G_STMT_START { \ - CoglObject *__obj = (CoglObject *)object; \ - COGL_NOTE (HANDLE, "COGL %s REF %p %i", \ - g_quark_to_string ((__obj)->klass->type), \ - (__obj), (__obj)->ref_count); } G_STMT_END - -#define _COGL_OBJECT_DEBUG_UNREF(type_name, object) G_STMT_START { \ - CoglObject *__obj = (CoglObject *)object; \ - COGL_NOTE (HANDLE, "COGL %s UNREF %p %i", \ - g_quark_to_string ((__obj)->klass->type), \ - (__obj), (__obj)->ref_count - 1); } G_STMT_END - -#define COGL_OBJECT_DEBUG_FREE(obj) \ - COGL_NOTE (HANDLE, "COGL %s FREE %p", \ - g_quark_to_string ((obj)->klass->type), (obj)) - -#else /* !COGL_OBJECT_DEBUG */ - -#define _COGL_OBJECT_DEBUG_NEW(type_name, obj) -#define _COGL_OBJECT_DEBUG_REF(type_name, obj) -#define _COGL_OBJECT_DEBUG_UNREF(type_name, obj) -#define COGL_OBJECT_DEBUG_FREE(obj) - -#endif /* COGL_OBJECT_DEBUG */ - -/* For temporary compatability */ -#define _COGL_HANDLE_DEBUG_NEW _COGL_OBJECT_DEBUG_NEW -#define _COGL_HANDLE_DEBUG_REF _COGL_OBJECT_DEBUG_REF -#define _COGL_HANDLE_DEBUG_UNREF _COGL_OBJECT_DEBUG_UNREF -#define COGL_HANDLE_DEBUG_FREE COGL_OBJECT_DEBUG_FREE - -#define COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -static CoglObjectClass _cogl_##type_name##_class; \ - \ -GQuark \ -_cogl_object_##type_name##_get_type (void) \ -{ \ - static GQuark type = 0; \ - if (!type) \ - { \ - type = g_quark_from_static_string ("Cogl"#TypeName); \ - { code; } \ - } \ - return type; \ -} \ - \ -GQuark \ -_cogl_handle_##type_name##_get_type (void) \ -{ \ - return _cogl_object_##type_name##_get_type (); \ -} \ - \ -static Cogl##TypeName * \ -_cogl_##type_name##_object_new (Cogl##TypeName *new_obj) \ -{ \ - CoglObject *obj = (CoglObject *)&new_obj->_parent; \ - obj->ref_count = 1; \ - obj->n_user_data_entries = 0; \ - obj->user_data_array = NULL; \ - \ - obj->klass = &_cogl_##type_name##_class; \ - if (!obj->klass->type) \ - { \ - obj->klass->type = _cogl_object_##type_name##_get_type ();\ - obj->klass->virt_free = _cogl_##type_name##_free; \ - } \ - \ - _COGL_OBJECT_DEBUG_NEW (TypeName, obj); \ - return new_obj; \ -} \ - \ -Cogl##TypeName * \ -_cogl_##type_name##_pointer_from_handle (CoglHandle handle) \ -{ \ - return handle; \ -} - -#define COGL_OBJECT_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -gboolean \ -cogl_is_##type_name (void *object) \ -{ \ - CoglObject *obj = object; \ - \ - if (object == NULL) \ - return FALSE; \ - \ - return (obj->klass->type == \ - _cogl_object_##type_name##_get_type ()); \ -} - -#define COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -gboolean \ -_cogl_is_##type_name (void *object) \ -{ \ - CoglObject *obj = object; \ - \ - if (object == NULL) \ - return FALSE; \ - \ - return (obj->klass->type == \ - _cogl_object_##type_name##_get_type ()); \ -} - -#define COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING(type_name) \ - \ -void * G_GNUC_DEPRECATED \ -cogl_##type_name##_ref (void *object) \ -{ \ - if (!cogl_is_##type_name (object)) \ - return NULL; \ - \ - _COGL_OBJECT_DEBUG_REF (TypeName, object); \ - \ - cogl_handle_ref (object); \ - \ - return object; \ -} \ - \ -void G_GNUC_DEPRECATED \ -cogl_##type_name##_unref (void *object) \ -{ \ - if (!cogl_is_##type_name (object)) \ - { \ - g_warning (G_STRINGIFY (cogl_##type_name##_unref) \ - ": Ignoring unref of Cogl handle " \ - "due to type mismatch"); \ - return; \ - } \ - \ - _COGL_OBJECT_DEBUG_UNREF (TypeName, object); \ - \ - cogl_handle_unref (object); \ -} - -#define COGL_OBJECT_DEFINE(TypeName, type_name) \ - COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, (void) 0) - -#define COGL_OBJECT_INTERNAL_DEFINE(TypeName, type_name) \ - COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0) - -/* For temporary compatability */ -#define COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, code) \ - \ -static Cogl##TypeName * \ -_cogl_##type_name##_handle_new (CoglHandle handle) \ -{ \ - return _cogl_##type_name##_object_new (handle); \ -} - -#define COGL_HANDLE_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, code) \ - \ -static Cogl##TypeName * \ -_cogl_##type_name##_handle_new (CoglHandle handle) \ -{ \ - return _cogl_##type_name##_object_new (handle); \ -} - -#define COGL_HANDLE_INTERNAL_DEFINE(TypeName, type_name) \ - COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0) - -#define COGL_HANDLE_DEFINE(TypeName, type_name) \ - COGL_HANDLE_DEFINE_WITH_CODE (TypeName, type_name, (void) 0) - -void -_cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyInternalCallback destroy); - -#endif /* __COGL_OBJECT_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-object.c b/clutter/cogl/cogl/cogl-object.c deleted file mode 100644 index 90109eb..0000000 --- a/clutter/cogl/cogl/cogl-object.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "cogl-types.h" -#include "cogl-object-private.h" - -void * -cogl_object_ref (void *object) -{ - CoglObject *obj = object; - - g_return_val_if_fail (object != NULL, NULL); - - obj->ref_count++; - return object; -} - -CoglHandle -cogl_handle_ref (CoglHandle handle) -{ - return cogl_object_ref (handle); -} - -void -cogl_object_unref (void *object) -{ - CoglObject *obj = object; - - g_return_if_fail (object != NULL); - g_return_if_fail (obj->ref_count > 0); - - if (--obj->ref_count < 1) - { - void (*free_func)(void *obj); - - if (obj->n_user_data_entries) - { - int i; - int count = MIN (obj->n_user_data_entries, - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES); - - for (i = 0; i < count; i++) - { - CoglUserDataEntry *entry = &obj->user_data_entry[i]; - if (entry->destroy) - entry->destroy (entry->user_data, obj); - } - - if (obj->user_data_array != NULL) - { - for (i = 0; i < obj->user_data_array->len; i++) - { - CoglUserDataEntry *entry = - &g_array_index (obj->user_data_array, - CoglUserDataEntry, i); - - if (entry->destroy) - entry->destroy (entry->user_data, obj); - } - g_array_free (obj->user_data_array, TRUE); - } - } - - COGL_OBJECT_DEBUG_FREE (obj); - free_func = obj->klass->virt_free; - free_func (obj); - } -} - -void -cogl_handle_unref (CoglHandle handle) -{ - cogl_object_unref (handle); -} - -GType -cogl_handle_get_type (void) -{ - static GType our_type = 0; - - /* XXX: We are keeping the "CoglHandle" name for now incase it would - * break bindings to change to "CoglObject" */ - if (G_UNLIKELY (our_type == 0)) - our_type = g_boxed_type_register_static (g_intern_static_string ("CoglHandle"), - (GBoxedCopyFunc) cogl_object_ref, - (GBoxedFreeFunc) cogl_object_unref); - - return our_type; -} - -/* XXX: Unlike for cogl_object_get_user_data this code will return - * an empty entry if available and no entry for the given key can be - * found. */ -static CoglUserDataEntry * -_cogl_object_find_entry (CoglObject *object, CoglUserDataKey *key) -{ - CoglUserDataEntry *entry = NULL; - int count; - int i; - - count = MIN (object->n_user_data_entries, - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES); - - for (i = 0; i < count; i++) - { - CoglUserDataEntry *current = &object->user_data_entry[i]; - if (current->key == key) - return current; - if (current->user_data == NULL) - entry = current; - } - - if (G_UNLIKELY (object->user_data_array != NULL)) - { - for (i = 0; i < object->user_data_array->len; i++) - { - CoglUserDataEntry *current = - &g_array_index (object->user_data_array, CoglUserDataEntry, i); - - if (current->key == key) - return current; - if (current->user_data == NULL) - entry = current; - } - } - - return entry; -} - -void -_cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyInternalCallback destroy) -{ - CoglUserDataEntry new_entry; - CoglUserDataEntry *entry; - - if (user_data) - { - new_entry.key = key; - new_entry.user_data = user_data; - new_entry.destroy = destroy; - } - else - memset (&new_entry, 0, sizeof (new_entry)); - - entry = _cogl_object_find_entry (object, key); - if (entry) - { - if (G_LIKELY (entry->destroy)) - entry->destroy (entry->user_data, object); - } - else - { - if (G_LIKELY (object->n_user_data_entries < - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES)) - entry = &object->user_data_entry[object->n_user_data_entries++]; - else - { - if (G_UNLIKELY (object->user_data_array == NULL)) - { - object->user_data_array = - g_array_new (FALSE, FALSE, sizeof (CoglUserDataEntry)); - } - - g_array_set_size (object->user_data_array, - object->user_data_array->len + 1); - entry = - &g_array_index (object->user_data_array, CoglUserDataEntry, - object->user_data_array->len - 1); - - object->n_user_data_entries++; - } - } - - *entry = new_entry; -} - -void -cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyCallback destroy) -{ - _cogl_object_set_user_data (object, key, user_data, - (CoglUserDataDestroyInternalCallback)destroy); -} - -void * -cogl_object_get_user_data (CoglObject *object, CoglUserDataKey *key) -{ - int count; - int i; - - count = MIN (object->n_user_data_entries, - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES); - - for (i = 0; i < count; i++) - { - CoglUserDataEntry *entry = &object->user_data_entry[i]; - if (entry->key == key) - return entry->user_data; - } - - if (object->user_data_array != NULL) - { - for (i = 0; i < object->user_data_array->len; i++) - { - CoglUserDataEntry *entry = - &g_array_index (object->user_data_array, CoglUserDataEntry, i); - - if (entry->key == key) - return entry->user_data; - } - } - - return NULL; -} - diff --git a/clutter/cogl/cogl/cogl-object.h b/clutter/cogl/cogl/cogl-object.h deleted file mode 100644 index 71dd8bd..0000000 --- a/clutter/cogl/cogl/cogl-object.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -#ifndef __COGL_OBJECT_H -#define __COGL_OBJECT_H - -typedef struct _CoglObject CoglObject; - -#define COGL_OBJECT(X) ((CoglObject *)X) - -/** - * CoglUserDataKey: - * @unused: ignored. - * - * A #CoglUserDataKey is used to declare a key for attaching data to a - * #CoglObject using cogl_object_set_user_data. The typedef only exists as a - * formality to make code self documenting since only the unique address of a - * #CoglUserDataKey is used. - * - * Typically you would declare a static #CoglUserDataKey and set private data - * on an object something like this: - * - * |[ - * static CoglUserDataKey path_private_key; - * - * static void - * destroy_path_private_cb (void *data) - * { - * g_free (data); - * } - * - * static void - * my_path_set_data (CoglPath *path, void *data) - * { - * cogl_object_set_user_data (COGL_OBJECT (path), - * &private_key, - * data, - * destroy_path_private_cb); - * } - * ]| - * - * Since: 1.4 - */ -typedef struct -{ - int unused; -} CoglUserDataKey; - -/** - * CoglUserDataDestroyCallback: - * @user_data: The data whos association with a #CoglObject has been - * destoyed. - * - * When associating private data with a #CoglObject a callback can be - * given which will be called either if the object is destroyed or if - * cogl_object_set_user_data() is called with NULL user_data for the - * same key. - * - * Since: 1.4 - */ -typedef void (*CoglUserDataDestroyCallback) (void *user_data); - -/** - * cogl_object_set_user_data: (skip) - * @object: The object to associate private data with - * @key: The address of a #CoglUserDataKey which provides a unique value - * with which to index the private data. - * @user_data: The data to associate with the given object, - * or %NULL to remove a previous association. - * @destroy: A #CoglUserDataDestroyCallback to call if the object is - * destroyed or if the association is removed by later setting - * %NULL data for the same key. - * - * Associates some private @user_data with a given #CoglObject. To - * later remove the association call cogl_object_set_user_data() with - * the same @key but NULL for the @user_data. - * - * Since: 1.4 - */ -void -cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyCallback destroy); - -/** - * cogl_object_get_user_data: (skip) - * @object: The object with associated private data to query - * @key: The address of a #CoglUserDataKey which provides a unique value - * with which to index the private data. - * - * Finds the user data previously associated with @object using - * the given @key. If no user data has been associated with @object - * for the given @key this function returns NULL. - * - * Returns: (transfer none): The user data previously associated - * with @object using the given @key; or %NULL if no associated - * data is found. - * - * Since: 1.4 - */ -void * -cogl_object_get_user_data (CoglObject *object, - CoglUserDataKey *key); -#endif /* __COGL_OBJECT_H */ - diff --git a/clutter/cogl/cogl/cogl-offscreen.h b/clutter/cogl/cogl/cogl-offscreen.h deleted file mode 100644 index c70eb99..0000000 --- a/clutter/cogl/cogl/cogl-offscreen.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_OFFSCREEN_H__ -#define __COGL_OFFSCREEN_H__ - -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-offscreen - * @short_description: Fuctions for creating and manipulating offscreen - * framebuffers. - * - * Cogl allows creating and operating on offscreen framebuffers. - */ - -/* Offscreen api */ - -/** - * cogl_offscreen_new_to_texture: - * @handle: A CoglHandle for a Cogl texture - * - * This creates an offscreen buffer object using the given texture as the - * primary color buffer. It doesn't just initialize the contents of the - * offscreen buffer with the texture; they are tightly bound so that - * drawing to the offscreen buffer effectivly updates the contents of the - * given texture. You don't need to destroy the offscreen buffer before - * you can use the texture again. - * - * Note: This does not work with sliced Cogl textures. - * - * Return value: (transfer full): a #CoglHandle for the new offscreen - * buffer or %COGL_INVALID_HANDLE if it wasn't possible to create the - * buffer. - */ -CoglHandle cogl_offscreen_new_to_texture (CoglHandle handle); - -/** - * cogl_is_offscreen: - * @handle: A CoglHandle for an offscreen buffer - * - * Determines whether the given #CoglHandle references an offscreen buffer - * object. - * - * Returns: %TRUE if the handle references an offscreen buffer, - * %FALSE otherwise - */ -gboolean cogl_is_offscreen (CoglHandle handle); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_offscreen_ref: - * @handle: A CoglHandle for an offscreen buffer - * - * Increments the reference count on the offscreen buffer. - * - * Return value: (transfer none): For convenience it returns the given CoglHandle - * - * Deprecated: 1.2: cogl_handle_ref() should be used in new code. - */ -CoglHandle cogl_offscreen_ref (CoglHandle handle) G_GNUC_DEPRECATED; - -/** - * cogl_offscreen_unref: - * @handle: A CoglHandle for an offscreen buffer - * - * Decreases the reference count for the offscreen buffer and frees it when - * the count reaches 0. - * - * Deprecated: 1.2: cogl_handle_unref() should be used in new code. - */ -void cogl_offscreen_unref (CoglHandle handle) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -G_END_DECLS - -#endif /* __COGL_OFFSCREEN_H__ */ diff --git a/clutter/cogl/cogl/cogl-onscreen-template-private.h b/clutter/cogl/cogl/cogl-onscreen-template-private.h deleted file mode 100644 index 0f8d253..0000000 --- a/clutter/cogl/cogl/cogl-onscreen-template-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - */ - -#ifndef __COGL_ONSCREEN_TEMPLATE_PRIVATE_H -#define __COGL_ONSCREEN_TEMPLATE_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-swap-chain.h" - -struct _CoglOnscreenTemplate -{ - CoglObject _parent; - - CoglSwapChain *swap_chain; -}; - -#endif /* __COGL_ONSCREEN_TEMPLATE_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-onscreen-template.c b/clutter/cogl/cogl/cogl-onscreen-template.c deleted file mode 100644 index ff400e4..0000000 --- a/clutter/cogl/cogl/cogl-onscreen-template.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-object.h" - -#include "cogl-onscreen-template-private.h" - -static void _cogl_onscreen_template_free (CoglOnscreenTemplate *onscreen_template); - -COGL_OBJECT_DEFINE (OnscreenTemplate, onscreen_template); - -GQuark -cogl_onscreen_template_error_quark (void) -{ - return g_quark_from_static_string ("cogl-onscreen-template-error-quark"); -} - -static void -_cogl_onscreen_template_free (CoglOnscreenTemplate *onscreen_template) -{ - g_slice_free (CoglOnscreenTemplate, onscreen_template); -} - -CoglOnscreenTemplate * -cogl_onscreen_template_new (CoglSwapChain *swap_chain) -{ - CoglOnscreenTemplate *onscreen_template = g_slice_new0 (CoglOnscreenTemplate); - - onscreen_template->swap_chain = swap_chain; - if (swap_chain) - cogl_object_ref (swap_chain); - - return _cogl_onscreen_template_object_new (onscreen_template); -} diff --git a/clutter/cogl/cogl/cogl-onscreen-template.h b/clutter/cogl/cogl/cogl-onscreen-template.h deleted file mode 100644 index 4769f9f..0000000 --- a/clutter/cogl/cogl/cogl-onscreen-template.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_ONSCREEN_TEMPLATE_H__ -#define __COGL_ONSCREEN_TEMPLATE_H__ - -#include - -G_BEGIN_DECLS - -typedef struct _CoglOnscreenTemplate CoglOnscreenTemplate; - -#define COGL_ONSCREEN_TEMPLATE(OBJECT) ((CoglOnscreenTemplate *)OBJECT) - -#define cogl_onscreen_template_new cogl_onscreen_template_new_EXP -CoglOnscreenTemplate * -cogl_onscreen_template_new (CoglSwapChain *swap_chain); - -G_END_DECLS - -#endif /* __COGL_ONSCREEN_TEMPLATE_H__ */ diff --git a/clutter/cogl/cogl/cogl-path-private.h b/clutter/cogl/cogl/cogl-path-private.h deleted file mode 100644 index dbd23f4..0000000 --- a/clutter/cogl/cogl/cogl-path-private.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_PATH_PRIVATE_H -#define __COGL_PATH_PRIVATE_H - -#include "cogl-object.h" - -typedef struct _floatVec2 -{ - float x; - float y; -} floatVec2; - -typedef struct _CoglPathNode -{ - float x; - float y; - unsigned int path_size; -} CoglPathNode; - -typedef struct _CoglBezQuad -{ - floatVec2 p1; - floatVec2 p2; - floatVec2 p3; -} CoglBezQuad; - -typedef struct _CoglBezCubic -{ - floatVec2 p1; - floatVec2 p2; - floatVec2 p3; - floatVec2 p4; -} CoglBezCubic; - -typedef struct _CoglPathData CoglPathData; - -struct _CoglPath -{ - CoglObject _parent; - - CoglPathData *data; -}; - -#define COGL_PATH_N_ATTRIBUTES 2 - -struct _CoglPathData -{ - unsigned int ref_count; - - CoglPathFillRule fill_rule; - - GArray *path_nodes; - - floatVec2 path_start; - floatVec2 path_pen; - unsigned int last_path; - floatVec2 path_nodes_min; - floatVec2 path_nodes_max; - - CoglVertexArray *fill_vbo; - CoglIndices *fill_vbo_indices; - unsigned int fill_vbo_n_indices; - CoglAttribute *fill_vbo_attributes[COGL_PATH_N_ATTRIBUTES + 1]; - - CoglVertexArray *stroke_vbo; - CoglAttribute **stroke_vbo_attributes; - unsigned int stroke_vbo_n_attributes; - - /* This is used as an optimisation for when the path contains a - single contour specified using cogl2_path_rectangle. Cogl is more - optimised to handle rectangles than paths so we can detect this - case and divert to the journal or a rectangle clip. If it is TRUE - then the entire path can be described by calling - _cogl_path_get_bounds */ - gboolean is_rectangle; -}; - -void -_cogl_add_path_to_stencil_buffer (CoglPath *path, - gboolean merge, - gboolean need_clear); - -void -_cogl_path_get_bounds (CoglPath *path, - float *min_x, - float *min_y, - float *max_x, - float *max_y); - -gboolean -_cogl_path_is_rectangle (CoglPath *path); - -#endif /* __COGL_PATH_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-path.c b/clutter/cogl/cogl/cogl-path.c deleted file mode 100644 index 116bd50..0000000 --- a/clutter/cogl/cogl/cogl-path.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl2-path.h" - -#include -#include - -#undef cogl_path_set_fill_rule -void -cogl_path_set_fill_rule (CoglPathFillRule fill_rule) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_set_fill_rule (ctx->current_path, fill_rule); -} - -#undef cogl_path_get_fill_rule -CoglPathFillRule -cogl_path_get_fill_rule (void) -{ - _COGL_GET_CONTEXT (ctx, COGL_PATH_FILL_RULE_EVEN_ODD); - - return cogl2_path_get_fill_rule (ctx->current_path); -} - -#undef cogl_path_fill -void -cogl_path_fill (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_fill (ctx->current_path); - - cogl_object_unref (ctx->current_path); - ctx->current_path = cogl2_path_new (); -} - -#undef cogl_path_fill_preserve -void -cogl_path_fill_preserve (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_fill (ctx->current_path); -} - -#undef cogl_path_stroke -void -cogl_path_stroke (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_stroke (ctx->current_path); - - cogl_object_unref (ctx->current_path); - ctx->current_path = cogl2_path_new (); -} - -#undef cogl_path_stroke_preserve -void -cogl_path_stroke_preserve (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_stroke (ctx->current_path); -} - -#undef cogl_path_move_to -void -cogl_path_move_to (float x, - float y) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_move_to (ctx->current_path, x, y); -} - -#undef cogl_path_rel_move_to -void -cogl_path_rel_move_to (float x, - float y) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_rel_move_to (ctx->current_path, x, y); -} - -#undef cogl_path_line_to -void -cogl_path_line_to (float x, - float y) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_line_to (ctx->current_path, x, y); -} - -#undef cogl_path_rel_line_to -void -cogl_path_rel_line_to (float x, - float y) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_rel_line_to (ctx->current_path, x, y); -} - -#undef cogl_path_close -void -cogl_path_close (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_close (ctx->current_path); -} - -#undef cogl_path_new -void -cogl_path_new (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_object_unref (ctx->current_path); - ctx->current_path = cogl2_path_new (); -} - -#undef cogl_path_line -void -cogl_path_line (float x_1, - float y_1, - float x_2, - float y_2) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_line (ctx->current_path, x_1, y_1, x_2, y_2); -} - -#undef cogl_path_polyline -void -cogl_path_polyline (const float *coords, - int num_points) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_polyline (ctx->current_path, coords, num_points); -} - -#undef cogl_path_polygon -void -cogl_path_polygon (const float *coords, - int num_points) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_polygon (ctx->current_path, coords, num_points); -} - -#undef cogl_path_rectangle -void -cogl_path_rectangle (float x_1, - float y_1, - float x_2, - float y_2) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_rectangle (ctx->current_path, x_1, y_1, x_2, y_2); -} - -#undef cogl_path_arc -void -cogl_path_arc (float center_x, - float center_y, - float radius_x, - float radius_y, - float angle_1, - float angle_2) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_arc (ctx->current_path, - center_x, - center_y, - radius_x, - radius_y, - angle_1, - angle_2); -} - -#undef cogl_path_ellipse -void -cogl_path_ellipse (float center_x, - float center_y, - float radius_x, - float radius_y) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_ellipse (ctx->current_path, - center_x, - center_y, - radius_x, - radius_y); -} - -#undef cogl_path_round_rectangle -void -cogl_path_round_rectangle (float x_1, - float y_1, - float x_2, - float y_2, - float radius, - float arc_step) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_round_rectangle (ctx->current_path, - x_1, y_1, x_2, y_2, radius, arc_step); -} - -#undef cogl_path_curve_to -void -cogl_path_curve_to (float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_curve_to (ctx->current_path, - x_1, y_2, x_2, y_2, x_3, y_3); -} - -#undef cogl_path_rel_curve_to -void -cogl_path_rel_curve_to (float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl2_path_rel_curve_to (ctx->current_path, - x_1, y_1, x_2, y_2, x_3, y_3); -} - -CoglPath * -cogl_get_path (void) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - return ctx->current_path; -} - -void -cogl_set_path (CoglPath *path) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_path (path)); - - /* Reference the new object first in case it is the same as the old - object */ - cogl_object_ref (path); - cogl_object_unref (ctx->current_path); - ctx->current_path = path; -} - diff --git a/clutter/cogl/cogl/cogl-path.h b/clutter/cogl/cogl/cogl-path.h deleted file mode 100644 index 30df7ef..0000000 --- a/clutter/cogl/cogl/cogl-path.h +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_PATH_H__ -#define __COGL_PATH_H__ - -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-paths - * @short_description: Functions for constructing and drawing 2D paths. - * - * There are two levels on which drawing with cogl-paths can be used. - * The highest level functions construct various simple primitive - * shapes to be either filled or stroked. Using a lower-level set of - * functions more complex and arbitrary paths can be constructed by - * concatenating straight line, bezier curve and arc segments. - * - * When constructing arbitrary paths, the current pen location is - * initialized using the move_to command. The subsequent path segments - * implicitly use the last pen location as their first vertex and move - * the pen location to the last vertex they produce at the end. Also - * there are special versions of functions that allow specifying the - * vertices of the path segments relative to the last pen location - * rather then in the absolute coordinates. - */ - -typedef struct _CoglPath CoglPath; - -#define COGL_PATH(obj) ((CoglPath *)(obj)) - -/** - * CoglPathFillRule: - * @COGL_PATH_FILL_RULE_NON_ZERO: Each time the line crosses an edge of - * the path from left to right one is added to a counter and each time - * it crosses from right to left the counter is decremented. If the - * counter is non-zero then the point will be filled. See . - * @COGL_PATH_FILL_RULE_EVEN_ODD: If the line crosses an edge of the - * path an odd number of times then the point will filled, otherwise - * it won't. See . - * - * #CoglPathFillRule is used to determine how a path is filled. There - * are two options - 'non-zero' and 'even-odd'. To work out whether any - * point will be filled imagine drawing an infinetely long line in any - * direction from that point. The number of times and the direction - * that the edges of the path crosses this line determines whether the - * line is filled as described below. Any open sub paths are treated - * as if there was an extra line joining the first point and the last - * point. - * - * The default fill rule is %COGL_PATH_FILL_RULE_EVEN_ODD. The fill - * rule is attached to the current path so preserving a path with - * cogl_get_path() also preserves the fill rule. Calling - * cogl_path_new() resets the current fill rule to the default. - * - *
- * Example of filling various paths using the non-zero rule - * - *
- * - *
- * Example of filling various paths using the even-odd rule - * - *
- * - * Since: 1.4 - */ -typedef enum { - COGL_PATH_FILL_RULE_NON_ZERO, - COGL_PATH_FILL_RULE_EVEN_ODD -} CoglPathFillRule; - -/** - * cogl_is_path: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing path object. - * - * Return value: %TRUE if the handle references a #CoglPath, - * %FALSE otherwise - */ -gboolean -cogl_is_path (CoglHandle handle); - -/** - * cogl_path_set_fill_rule: - * @fill_rule: The new fill rule. - * - * Sets the fill rule of the current path to @fill_rule. This will - * affect how the path is filled when cogl_path_fill() is later - * called. Note that the fill rule state is attached to the path so - * calling cogl_get_path() will preserve the fill rule and calling - * cogl_path_new() will reset the fill rule back to the default. - * - * Since: 1.4 - */ -void -cogl_path_set_fill_rule (CoglPathFillRule fill_rule); - -/** - * cogl_path_get_fill_rule: - * - * Retrieves the fill rule set using cogl_path_set_fill_rule(). - * - * Return value: the fill rule that is used for the current path. - * - * Since: 1.4 - */ -CoglPathFillRule -cogl_path_get_fill_rule (void); - -/** - * cogl_path_fill: - * - * Fills the interior of the constructed shape using the current - * drawing color. The current path is then cleared. To use the path - * again, call cogl_path_fill_preserve() instead. - * - * The interior of the shape is determined using the fill rule of the - * path. See %CoglPathFillRule for details. - **/ -void -cogl_path_fill (void); - -/** - * cogl_path_fill_preserve: - * - * Fills the interior of the constructed shape using the current - * drawing color and preserves the path to be used again. See - * cogl_path_fill() for a description what is considered the interior - * of the shape. - * - * Since: 1.0 - **/ -void -cogl_path_fill_preserve (void); - -/** - * cogl_path_stroke: - * - * Strokes the constructed shape using the current drawing color and a - * width of 1 pixel (regardless of the current transformation - * matrix). To current path is then cleared. To use the path again, - * call cogl_path_stroke_preserve() instead. - **/ -void -cogl_path_stroke (void); - -/** - * cogl_path_stroke_preserve: - * - * Strokes the constructed shape using the current drawing color and - * preserves the path to be used again. - * - * Since: 1.0 - **/ -void -cogl_path_stroke_preserve (void); - -/** - * cogl_path_new: - * - * Clears the current path and starts a new one. Creating a new path - * also resets the fill rule to the default which is - * %COGL_PATH_FILL_RULE_EVEN_ODD. - * - * Since: 1.0 - */ -void -cogl_path_new (void); - -/** - * cogl_path_move_to: - * @x: X coordinate of the pen location to move to. - * @y: Y coordinate of the pen location to move to. - * - * Moves the pen to the given location. If there is an existing path - * this will start a new disjoint subpath. - **/ -void -cogl_path_move_to (float x, - float y); - - -/** - * cogl_path_rel_move_to: - * @x: X offset from the current pen location to move the pen to. - * @y: Y offset from the current pen location to move the pen to. - * - * Moves the pen to the given offset relative to the current pen - * location. If there is an existing path this will start a new - * disjoint subpath. - **/ -void -cogl_path_rel_move_to (float x, - float y); - -/** - * cogl_path_line_to: - * @x: X coordinate of the end line vertex - * @y: Y coordinate of the end line vertex - * - * Adds a straight line segment to the current path that ends at the - * given coordinates. - **/ -void -cogl_path_line_to (float x, - float y); - -/** - * cogl_path_rel_line_to: - * @x: X offset from the current pen location of the end line vertex - * @y: Y offset from the current pen location of the end line vertex - * - * Adds a straight line segment to the current path that ends at the - * given coordinates relative to the current pen location. - **/ -void -cogl_path_rel_line_to (float x, - float y); - - -/** - * cogl_path_arc: - * @center_x: X coordinate of the elliptical arc center - * @center_y: Y coordinate of the elliptical arc center - * @radius_x: X radius of the elliptical arc - * @radius_y: Y radius of the elliptical arc - * @angle_1: Angle in degrees at which the arc begin - * @angle_2: Angle in degrees at which the arc ends - * - * Adds an elliptical arc segment to the current path. A straight line - * segment will link the current pen location with the first vertex - * of the arc. If you perform a move_to to the arcs start just before - * drawing it you create a free standing arc. - * - * The angles are measured in degrees where 0° is in the direction of - * the positive X axis and 90° is in the direction of the positive Y - * axis. The angle of the arc begins at @angle_1 and heads towards - * @angle_2 (so if @angle_2 is less than @angle_1 it will decrease, - * otherwise it will increase). - **/ -void -cogl_path_arc (float center_x, - float center_y, - float radius_x, - float radius_y, - float angle_1, - float angle_2); - -/** - * cogl_path_curve_to: - * @x_1: X coordinate of the second bezier control point - * @y_1: Y coordinate of the second bezier control point - * @x_2: X coordinate of the third bezier control point - * @y_2: Y coordinate of the third bezier control point - * @x_3: X coordinate of the fourth bezier control point - * @y_3: Y coordinate of the fourth bezier control point - * - * Adds a cubic bezier curve segment to the current path with the given - * second, third and fourth control points and using current pen location - * as the first control point. - **/ -void -cogl_path_curve_to (float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3); - -/** - * cogl_path_rel_curve_to: - * @x_1: X coordinate of the second bezier control point - * @y_1: Y coordinate of the second bezier control point - * @x_2: X coordinate of the third bezier control point - * @y_2: Y coordinate of the third bezier control point - * @x_3: X coordinate of the fourth bezier control point - * @y_3: Y coordinate of the fourth bezier control point - * - * Adds a cubic bezier curve segment to the current path with the given - * second, third and fourth control points and using current pen location - * as the first control point. The given coordinates are relative to the - * current pen location. - */ -void -cogl_path_rel_curve_to (float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3); - -/** - * cogl_path_close: - * - * Closes the path being constructed by adding a straight line segment - * to it that ends at the first vertex of the path. - **/ -void -cogl_path_close (void); - -/** - * cogl_path_line: - * @x_1: X coordinate of the start line vertex - * @y_1: Y coordinate of the start line vertex - * @x_2: X coordinate of the end line vertex - * @y_2: Y coordinate of the end line vertex - * - * Constructs a straight line shape starting and ending at the given - * coordinates. If there is an existing path this will start a new - * disjoint sub-path. - **/ -void -cogl_path_line (float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_path_polyline: - * @coords: (in) (array) (transfer none): A pointer to the first element of an - * array of fixed-point values that specify the vertex coordinates. - * @num_points: The total number of vertices. - * - * Constructs a series of straight line segments, starting from the - * first given vertex coordinate. If there is an existing path this - * will start a new disjoint sub-path. Each subsequent segment starts - * where the previous one ended and ends at the next given vertex - * coordinate. - * - * The coords array must contain 2 * num_points values. The first value - * represents the X coordinate of the first vertex, the second value - * represents the Y coordinate of the first vertex, continuing in the same - * fashion for the rest of the vertices. (num_points - 1) segments will - * be constructed. - **/ -void -cogl_path_polyline (const float *coords, - int num_points); - - -/** - * cogl_path_polygon: - * @coords: (in) (array) (transfer none): A pointer to the first element of - * an array of fixed-point values that specify the vertex coordinates. - * @num_points: The total number of vertices. - * - * Constructs a polygonal shape of the given number of vertices. If - * there is an existing path this will start a new disjoint sub-path. - * - * The coords array must contain 2 * num_points values. The first value - * represents the X coordinate of the first vertex, the second value - * represents the Y coordinate of the first vertex, continuing in the same - * fashion for the rest of the vertices. - **/ -void -cogl_path_polygon (const float *coords, - int num_points); - - -/** - * cogl_path_rectangle: - * @x_1: X coordinate of the top-left corner. - * @y_1: Y coordinate of the top-left corner. - * @x_2: X coordinate of the bottom-right corner. - * @y_2: Y coordinate of the bottom-right corner. - * - * Constructs a rectangular shape at the given coordinates. If there - * is an existing path this will start a new disjoint sub-path. - **/ -void -cogl_path_rectangle (float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_path_ellipse: - * @center_x: X coordinate of the ellipse center - * @center_y: Y coordinate of the ellipse center - * @radius_x: X radius of the ellipse - * @radius_y: Y radius of the ellipse - * - * Constructs an ellipse shape. If there is an existing path this will - * start a new disjoint sub-path. - **/ -void -cogl_path_ellipse (float center_x, - float center_y, - float radius_x, - float radius_y); - -/** - * cogl_path_round_rectangle: - * @x_1: X coordinate of the top-left corner. - * @y_1: Y coordinate of the top-left corner. - * @x_2: X coordinate of the bottom-right corner. - * @y_2: Y coordinate of the bottom-right corner. - * @radius: Radius of the corner arcs. - * @arc_step: Angle increment resolution for subdivision of - * the corner arcs. - * - * Constructs a rectangular shape with rounded corners. If there is an - * existing path this will start a new disjoint sub-path. - **/ -void -cogl_path_round_rectangle (float x_1, - float y_1, - float x_2, - float y_2, - float radius, - float arc_step); - -/** - * cogl_get_path: (skip) - * - * Gets a pointer to the current path. The path can later be used - * again by calling cogl_path_set(). Note that the path isn't copied - * so if you later call any functions to add to the path it will - * affect the returned object too. No reference is taken on the path - * so if you want to retain it you should take your own reference with - * cogl_object_ref(). - * - * Return value: a pointer to the current path. - * - * Since: 1.4 - */ -CoglPath * -cogl_get_path (void); - -/** - * cogl_set_path: (skip) - * @path: A #CoglPath object - * - * Replaces the current path with @path. A reference is taken on the - * object so if you no longer need the path you should unref with - * cogl_object_unref(). - * - * Since: 1.4 - */ -void -cogl_set_path (CoglPath *path); - -/** - * cogl_path_copy: (skip) - * @path: A #CoglPath object - * - * Returns a new copy of the path in @path. The new path has a - * reference count of 1 so you should unref it with - * cogl_object_unref() if you no longer need it. - * - * Internally the path will share the data until one of the paths is - * modified so copying paths should be relatively cheap. - * - * Return value: (transfer full): a copy of the path in @path. - */ -CoglPath * -cogl_path_copy (CoglPath *path); - -G_END_DECLS - -#endif /* __COGL_PATH_H__ */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-fragend-arbfp-private.h b/clutter/cogl/cogl/cogl-pipeline-fragend-arbfp-private.h deleted file mode 100644 index 168bbe9..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-fragend-arbfp-private.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PIPELINE_FRAGEND_ARBFP_PRIVATE_H -#define __COGL_PIPELINE_FRAGEND_ARBFP_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineFragend _cogl_pipeline_arbfp_fragend; - -unsigned int -_cogl_pipeline_fragend_arbfp_hash (const void *pipeline); - -gboolean -_cogl_pipeline_fragend_arbfp_equal (const void *pipeline0, - const void *pipeline1); - -#endif /* __COGL_PIPELINE_ARBFP_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-fragend-arbfp.c b/clutter/cogl/cogl/cogl-pipeline-fragend-arbfp.c deleted file mode 100644 index 4e14ba1..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-fragend-arbfp.c +++ /dev/null @@ -1,1109 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-debug.h" -#include "cogl-pipeline-private.h" - -#ifdef COGL_PIPELINE_FRAGEND_ARBFP - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" - -#include "cogl-texture-private.h" -#include "cogl-blend-string.h" -#include "cogl-journal-private.h" -#include "cogl-color-private.h" -#include "cogl-profile.h" -#include "cogl-program-private.h" - -#include -#include -#include - -/* - * GL/GLES compatability defines for pipeline thingies: - */ - -#ifdef HAVE_COGL_GL -#define glProgramString ctx->drv.pf_glProgramString -#define glBindProgram ctx->drv.pf_glBindProgram -#define glDeletePrograms ctx->drv.pf_glDeletePrograms -#define glGenPrograms ctx->drv.pf_glGenPrograms -#define glProgramLocalParameter4fv ctx->drv.pf_glProgramLocalParameter4fv -#define glUseProgram ctx->drv.pf_glUseProgram -#endif - -/* This might not be defined on GLES */ -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif - -typedef struct _UnitState -{ - int constant_id; /* The program.local[] index */ - unsigned int dirty_combine_constant:1; - - unsigned int sampled:1; -} UnitState; - -typedef struct _ArbfpProgramState -{ - int ref_count; - - /* XXX: only valid during codegen */ - CoglPipeline *arbfp_authority; - - CoglHandle user_program; - /* XXX: only valid during codegen */ - GString *source; - GLuint gl_program; - UnitState *unit_state; - int next_constant_id; - - /* Age of the program the last time the uniforms were flushed. This - is used to detect when we need to flush all of the uniforms */ - unsigned int user_program_age; - - /* We need to track the last pipeline that an ARBfp program was used - * with so know if we need to update any program.local parameters. */ - CoglPipeline *last_used_for_pipeline; -} ArbfpProgramState; - -typedef struct _CoglPipelineFragendARBfpPrivate -{ - ArbfpProgramState *arbfp_program_state; -} CoglPipelineFragendARBfpPrivate; - -const CoglPipelineFragend _cogl_pipeline_arbfp_fragend; - - -static ArbfpProgramState * -arbfp_program_state_new (int n_layers) -{ - ArbfpProgramState *state = g_slice_new0 (ArbfpProgramState); - state->ref_count = 1; - state->unit_state = g_new0 (UnitState, n_layers); - return state; -} - -static ArbfpProgramState * -arbfp_program_state_ref (ArbfpProgramState *state) -{ - state->ref_count++; - return state; -} - -void -arbfp_program_state_unref (ArbfpProgramState *state) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (state->ref_count > 0); - - state->ref_count--; - if (state->ref_count == 0) - { - if (state->gl_program) - { - GE (glDeletePrograms (1, &state->gl_program)); - state->gl_program = 0; - } - - g_free (state->unit_state); - - g_slice_free (ArbfpProgramState, state); - } -} - -static CoglPipelineFragendARBfpPrivate * -get_arbfp_priv (CoglPipeline *pipeline) -{ - if (!(pipeline->fragend_priv_set_mask & COGL_PIPELINE_FRAGEND_ARBFP_MASK)) - return NULL; - - return pipeline->fragend_privs[COGL_PIPELINE_FRAGEND_ARBFP]; -} - -static void -set_arbfp_priv (CoglPipeline *pipeline, CoglPipelineFragendARBfpPrivate *priv) -{ - if (priv) - { - pipeline->fragend_privs[COGL_PIPELINE_FRAGEND_ARBFP] = priv; - pipeline->fragend_priv_set_mask |= COGL_PIPELINE_FRAGEND_ARBFP_MASK; - } - else - pipeline->fragend_priv_set_mask &= ~COGL_PIPELINE_FRAGEND_ARBFP_MASK; -} - -static ArbfpProgramState * -get_arbfp_program_state (CoglPipeline *pipeline) -{ - CoglPipelineFragendARBfpPrivate *priv = get_arbfp_priv (pipeline); - if (!priv) - return NULL; - return priv->arbfp_program_state; -} - -static gboolean -_cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference, - int n_tex_coord_attribs) -{ - CoglPipelineFragendARBfpPrivate *priv; - CoglPipeline *authority; - CoglPipelineFragendARBfpPrivate *authority_priv; - ArbfpProgramState *arbfp_program_state; - CoglHandle user_program; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* First validate that we can handle the current state using ARBfp - */ - - if (!cogl_features_available (COGL_FEATURE_SHADERS_ARBFP)) - return FALSE; - - /* TODO: support fog */ - if (ctx->legacy_fog_state.enabled) - return FALSE; - - user_program = cogl_pipeline_get_user_program (pipeline); - if (user_program != COGL_INVALID_HANDLE) - { - /* If the program doesn't have a fragment shader then some other - vertend will handle the vertex shader state and we still need - to generate a fragment program */ - if (!_cogl_program_has_fragment_shader (user_program)) - user_program = COGL_INVALID_HANDLE; - /* If the user program does have a fragment shader then we can - only handle it if it's in ARBfp */ - else if (_cogl_program_get_language (user_program) != - COGL_SHADER_LANGUAGE_ARBFP) - return FALSE; - } - - /* Now lookup our ARBfp backend private state (allocating if - * necessary) */ - priv = get_arbfp_priv (pipeline); - if (!priv) - { - priv = g_slice_new0 (CoglPipelineFragendARBfpPrivate); - set_arbfp_priv (pipeline, priv); - } - - /* If we have a valid arbfp_program_state pointer then we are all - * set and don't need to generate a new program. */ - if (priv->arbfp_program_state) - return TRUE; - - /* If we don't have an associated arbfp program yet then find the - * arbfp-authority (the oldest ancestor whose state will result in - * the same program being generated as for this pipeline). - * - * We always make sure to associate new programs with the - * arbfp-authority to maximize the chance that other pipelines can - * share it. - */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN & - ~COGL_PIPELINE_STATE_LAYERS, - COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN); - authority_priv = get_arbfp_priv (authority); - if (authority_priv && - authority_priv->arbfp_program_state) - { - /* If we are going to share our program state with an arbfp-authority - * then steal a reference to the program state associated with that - * arbfp-authority... */ - priv->arbfp_program_state = - arbfp_program_state_ref (authority_priv->arbfp_program_state); - return TRUE; - } - - if (!authority_priv) - { - authority_priv = g_slice_new0 (CoglPipelineFragendARBfpPrivate); - set_arbfp_priv (authority, authority_priv); - } - - /* If we haven't yet found an existing program then before we resort to - * generating a new arbfp program we see if we can find a suitable - * program in the arbfp_cache. */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - arbfp_program_state = g_hash_table_lookup (ctx->arbfp_cache, authority); - if (arbfp_program_state) - { - priv->arbfp_program_state = - arbfp_program_state_ref (arbfp_program_state); - - /* Since we have already resolved the arbfp-authority at this point - * we might as well also associate any program we find from the cache - * with the authority too... */ - if (authority_priv != priv) - authority_priv->arbfp_program_state = - arbfp_program_state_ref (arbfp_program_state); - return TRUE; - } - } - - /* If we still haven't found an existing program then start - * generating code for a new program... - */ - - arbfp_program_state = arbfp_program_state_new (n_layers); - - priv->arbfp_program_state = arbfp_program_state_ref (arbfp_program_state); - - /* Since we have already resolved the arbfp-authority at this point we might - * as well also associate any program we generate with the authority too... - */ - if (authority_priv != priv) - authority_priv->arbfp_program_state = - arbfp_program_state_ref (arbfp_program_state); - - arbfp_program_state->user_program = user_program; - if (user_program == COGL_INVALID_HANDLE) - { - int i; - - /* We reuse a single grow-only GString for code-gen */ - g_string_set_size (ctx->codegen_source_buffer, 0); - arbfp_program_state->source = ctx->codegen_source_buffer; - g_string_append (arbfp_program_state->source, - "!!ARBfp1.0\n" - "TEMP output;\n" - "TEMP tmp0, tmp1, tmp2, tmp3, tmp4;\n" - "PARAM half = {.5, .5, .5, .5};\n" - "PARAM one = {1, 1, 1, 1};\n" - "PARAM two = {2, 2, 2, 2};\n" - "PARAM minus_one = {-1, -1, -1, -1};\n"); - - /* At the end of code-gen we'll add the program to a cache and - * we'll use the authority pipeline as the basis for key into - * that cache... */ - arbfp_program_state->arbfp_authority = authority; - - for (i = 0; i < n_layers; i++) - { - arbfp_program_state->unit_state[i].sampled = FALSE; - arbfp_program_state->unit_state[i].dirty_combine_constant = FALSE; - } - arbfp_program_state->next_constant_id = 0; - } - - return TRUE; -} - -unsigned int -_cogl_pipeline_fragend_arbfp_hash (const void *data) -{ - unsigned long fragment_state = - COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN; - unsigned long layer_fragment_state = - COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN; - - return _cogl_pipeline_hash ((CoglPipeline *)data, - fragment_state, layer_fragment_state, - 0); -} - -gboolean -_cogl_pipeline_fragend_arbfp_equal (const void *a, const void *b) -{ - unsigned long fragment_state = - COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN; - unsigned long layer_fragment_state = - COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN; - - return _cogl_pipeline_equal ((CoglPipeline *)a, (CoglPipeline *)b, - fragment_state, layer_fragment_state, - 0); -} - -static const char * -gl_target_to_arbfp_string (GLenum gl_target) -{ -#ifndef HAVE_COGL_GLES2 - if (gl_target == GL_TEXTURE_1D) - return "1D"; - else -#endif - if (gl_target == GL_TEXTURE_2D) - return "2D"; -#ifdef GL_ARB_texture_rectangle - else if (gl_target == GL_TEXTURE_RECTANGLE_ARB) - return "RECT"; -#endif - else if (gl_target == GL_TEXTURE_3D) - return "3D"; - else - return "2D"; -} - -static void -setup_texture_source (ArbfpProgramState *arbfp_program_state, - int unit_index, - GLenum gl_target) -{ - if (!arbfp_program_state->unit_state[unit_index].sampled) - { - g_string_append_printf (arbfp_program_state->source, - "TEMP texel%d;\n" - "TEX texel%d,fragment.texcoord[%d]," - "texture[%d],%s;\n", - unit_index, - unit_index, - unit_index, - unit_index, - gl_target_to_arbfp_string (gl_target)); - arbfp_program_state->unit_state[unit_index].sampled = TRUE; - } -} - -typedef enum _CoglPipelineFragendARBfpArgType -{ - COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE, - COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT, - COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE -} CoglPipelineFragendARBfpArgType; - -typedef struct _CoglPipelineFragendARBfpArg -{ - const char *name; - - CoglPipelineFragendARBfpArgType type; - - /* for type = TEXTURE */ - int texture_unit; - GLenum texture_target; - - /* for type = CONSTANT */ - int constant_id; - - const char *swizzle; - -} CoglPipelineFragendARBfpArg; - -static void -append_arg (GString *source, const CoglPipelineFragendARBfpArg *arg) -{ - switch (arg->type) - { - case COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE: - g_string_append_printf (source, "texel%d%s", - arg->texture_unit, arg->swizzle); - break; - case COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT: - g_string_append_printf (source, "program.local[%d]%s", - arg->constant_id, arg->swizzle); - break; - case COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE: - g_string_append_printf (source, "%s%s", - arg->name, arg->swizzle); - break; - } -} - -/* Note: we are trying to avoid duplicating strings during codegen - * which is why we have the slightly awkward - * CoglPipelineFragendARBfpArg mechanism. */ -static void -setup_arg (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - CoglBlendStringChannelMask mask, - int arg_index, - GLint src, - GLint op, - CoglPipelineFragendARBfpArg *arg) -{ - ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline); - static const char *tmp_name[3] = { "tmp0", "tmp1", "tmp2" }; - GLenum gl_target; - CoglHandle texture; - - switch (src) - { - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; - arg->name = "texel%d"; - arg->texture_unit = _cogl_pipeline_layer_get_unit_index (layer); - texture = _cogl_pipeline_layer_get_texture (layer); - cogl_texture_get_gl_texture (texture, NULL, &gl_target); - setup_texture_source (arbfp_program_state, arg->texture_unit, gl_target); - break; - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - UnitState *unit_state = &arbfp_program_state->unit_state[unit_index]; - - unit_state->constant_id = arbfp_program_state->next_constant_id++; - unit_state->dirty_combine_constant = TRUE; - - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT; - arg->name = "program.local[%d]"; - arg->constant_id = unit_state->constant_id; - break; - } - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - arg->name = "fragment.color.primary"; - break; - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - if (_cogl_pipeline_layer_get_unit_index (layer) == 0) - arg->name = "fragment.color.primary"; - else - arg->name = "output"; - break; - default: /* GL_TEXTURE0..N */ - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; - arg->name = "texture[%d]"; - arg->texture_unit = src - GL_TEXTURE0; - texture = _cogl_pipeline_layer_get_texture (layer); - cogl_texture_get_gl_texture (texture, NULL, &gl_target); - setup_texture_source (arbfp_program_state, arg->texture_unit, gl_target); - } - - arg->swizzle = ""; - - switch (op) - { - case COGL_PIPELINE_COMBINE_OP_SRC_COLOR: - break; - case COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR: - g_string_append_printf (arbfp_program_state->source, - "SUB tmp%d, one, ", - arg_index); - append_arg (arbfp_program_state->source, arg); - g_string_append_printf (arbfp_program_state->source, ";\n"); - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - arg->name = tmp_name[arg_index]; - arg->swizzle = ""; - break; - case COGL_PIPELINE_COMBINE_OP_SRC_ALPHA: - /* avoid a swizzle if we know RGB are going to be masked - * in the end anyway */ - if (mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - arg->swizzle = ".a"; - break; - case COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA: - g_string_append_printf (arbfp_program_state->source, - "SUB tmp%d, one, ", - arg_index); - append_arg (arbfp_program_state->source, arg); - /* avoid a swizzle if we know RGB are going to be masked - * in the end anyway */ - if (mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - g_string_append_printf (arbfp_program_state->source, ".a;\n"); - else - g_string_append_printf (arbfp_program_state->source, ";\n"); - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - arg->name = tmp_name[arg_index]; - break; - default: - g_error ("Unknown texture combine operator %d", op); - break; - } -} - -static gboolean -fragend_arbfp_args_equal (CoglPipelineFragendARBfpArg *arg0, - CoglPipelineFragendARBfpArg *arg1) -{ - if (arg0->type != arg1->type) - return FALSE; - - if (arg0->name != arg1->name && - strcmp (arg0->name, arg1->name) != 0) - return FALSE; - - if (arg0->type == COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE && - arg0->texture_unit != arg1->texture_unit) - return FALSE; - /* Note we don't have to check the target; a texture unit can only - * have one target enabled at a time. */ - - if (arg0->type == COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT && - arg0->constant_id != arg0->constant_id) - return FALSE; - - if (arg0->swizzle != arg1->swizzle && - strcmp (arg0->swizzle, arg1->swizzle) != 0) - return FALSE; - - return TRUE; -} - -static void -append_function (CoglPipeline *pipeline, - CoglBlendStringChannelMask mask, - GLint function, - CoglPipelineFragendARBfpArg *args, - int n_args) -{ - ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline); - const char *mask_name; - - switch (mask) - { - case COGL_BLEND_STRING_CHANNEL_MASK_RGB: - mask_name = ".rgb"; - break; - case COGL_BLEND_STRING_CHANNEL_MASK_ALPHA: - mask_name = ".a"; - break; - case COGL_BLEND_STRING_CHANNEL_MASK_RGBA: - mask_name = ""; - break; - default: - g_error ("Unknown channel mask %d", mask); - mask_name = ""; - } - - switch (function) - { - case COGL_PIPELINE_COMBINE_FUNC_ADD: - g_string_append_printf (arbfp_program_state->source, - "ADD_SAT output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - /* Note: no need to saturate since we can assume operands - * have values in the range [0,1] */ - g_string_append_printf (arbfp_program_state->source, "MUL output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - /* Note: no need to saturate since we can assume operand - * has a value in the range [0,1] */ - g_string_append_printf (arbfp_program_state->source, "MOV output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - g_string_append_printf (arbfp_program_state->source, - "SUB_SAT output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - g_string_append_printf (arbfp_program_state->source, "ADD tmp3%s, ", - mask_name); - append_arg (arbfp_program_state->source, &args[0]); - g_string_append (arbfp_program_state->source, ", "); - append_arg (arbfp_program_state->source, &args[1]); - g_string_append (arbfp_program_state->source, ";\n"); - g_string_append_printf (arbfp_program_state->source, - "SUB_SAT output%s, tmp3, half", - mask_name); - n_args = 0; - break; - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - /* These functions are the same except that GL_DOT3_RGB never - * updates the alpha channel. - * - * NB: GL_DOT3_RGBA is a bit special because it effectively forces - * an RGBA mask and we end up ignoring any separate alpha channel - * function. - */ - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - { - const char *tmp4 = "tmp4"; - - /* The maths for this was taken from Mesa; - * apparently: - * - * tmp3 = 2*src0 - 1 - * tmp4 = 2*src1 - 1 - * output = DP3 (tmp3, tmp4) - * - * is the same as: - * - * output = 4 * DP3 (src0 - 0.5, src1 - 0.5) - */ - - g_string_append (arbfp_program_state->source, "MAD tmp3, two, "); - append_arg (arbfp_program_state->source, &args[0]); - g_string_append (arbfp_program_state->source, ", minus_one;\n"); - - if (!fragend_arbfp_args_equal (&args[0], &args[1])) - { - g_string_append (arbfp_program_state->source, "MAD tmp4, two, "); - append_arg (arbfp_program_state->source, &args[1]); - g_string_append (arbfp_program_state->source, ", minus_one;\n"); - } - else - tmp4 = "tmp3"; - - g_string_append_printf (arbfp_program_state->source, - "DP3_SAT output%s, tmp3, %s", - mask_name, tmp4); - n_args = 0; - } - break; - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - /* Note: no need to saturate since we can assume operands - * have values in the range [0,1] */ - - /* NB: GL_INTERPOLATE = arg0*arg2 + arg1*(1-arg2) - * but LRP dst, a, b, c = b*a + c*(1-a) */ - g_string_append_printf (arbfp_program_state->source, "LRP output%s, ", - mask_name); - append_arg (arbfp_program_state->source, &args[2]); - g_string_append (arbfp_program_state->source, ", "); - append_arg (arbfp_program_state->source, &args[0]); - g_string_append (arbfp_program_state->source, ", "); - append_arg (arbfp_program_state->source, &args[1]); - n_args = 0; - break; - default: - g_error ("Unknown texture combine function %d", function); - g_string_append_printf (arbfp_program_state->source, "MUL_SAT output%s, ", - mask_name); - n_args = 2; - break; - } - - if (n_args > 0) - append_arg (arbfp_program_state->source, &args[0]); - if (n_args > 1) - { - g_string_append (arbfp_program_state->source, ", "); - append_arg (arbfp_program_state->source, &args[1]); - } - g_string_append (arbfp_program_state->source, ";\n"); -} - -static void -append_masked_combine (CoglPipeline *arbfp_authority, - CoglPipelineLayer *layer, - CoglBlendStringChannelMask mask, - CoglPipelineCombineFunc function, - CoglPipelineCombineSource *src, - CoglPipelineCombineOp *op) -{ - int i; - int n_args; - CoglPipelineFragendARBfpArg args[3]; - - n_args = _cogl_get_n_args_for_combine_func (function); - - for (i = 0; i < n_args; i++) - { - setup_arg (arbfp_authority, - layer, - mask, - i, - src[i], - op[i], - &args[i]); - } - - append_function (arbfp_authority, - mask, - function, - args, - n_args); -} - -static gboolean -_cogl_pipeline_fragend_arbfp_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline); - CoglPipelineLayer *combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - - /* Notes... - * - * We are ignoring the issue of texture indirection limits until - * someone complains (Ref Section 3.11.6 in the ARB_fragment_program - * spec) - * - * There always five TEMPs named tmp0, tmp1 and tmp2, tmp3 and tmp4 - * available and these constants: 'one' = {1, 1, 1, 1}, 'half' - * {.5, .5, .5, .5}, 'two' = {2, 2, 2, 2}, 'minus_one' = {-1, -1, - * -1, -1} - * - * tmp0-2 are intended for dealing with some of the texture combine - * operands (e.g. GL_ONE_MINUS_SRC_COLOR) tmp3/4 are for dealing - * with the GL_ADD_SIGNED texture combine and the GL_DOT3_RGB[A] - * functions. - * - * Each layer outputs to the TEMP called "output", and reads from - * output if it needs to refer to GL_PREVIOUS. (we detect if we are - * layer0 so we will read fragment.color for GL_PREVIOUS in that - * case) - * - * We aim to do all the channels together if the same function is - * used for RGB as for A. - * - * We aim to avoid string duplication / allocations during codegen. - * - * We are careful to only saturate when writing to output. - */ - - if (!arbfp_program_state->source) - return TRUE; - - if (!_cogl_pipeline_need_texture_combine_separate (combine_authority)) - { - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_RGBA, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - } - else if (big_state->texture_combine_rgb_func == - COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA) - { - /* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function - * since if you use it, it overrides your ALPHA function... - */ - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_RGBA, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - } - else - { - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_RGB, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_ALPHA, - big_state->texture_combine_alpha_func, - big_state->texture_combine_alpha_src, - big_state->texture_combine_alpha_op); - } - - return TRUE; -} - -gboolean -_cogl_pipeline_fragend_arbfp_passthrough (CoglPipeline *pipeline) -{ - ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline); - - if (!arbfp_program_state->source) - return TRUE; - - g_string_append (arbfp_program_state->source, - "MOV output, fragment.color.primary;\n"); - return TRUE; -} - -typedef struct _UpdateConstantsState -{ - int unit; - gboolean update_all; - ArbfpProgramState *arbfp_program_state; -} UpdateConstantsState; - -static gboolean -update_constants_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateConstantsState *state = user_data; - ArbfpProgramState *arbfp_program_state = state->arbfp_program_state; - UnitState *unit_state = &arbfp_program_state->unit_state[state->unit++]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (state->update_all || unit_state->dirty_combine_constant) - { - float constant[4]; - _cogl_pipeline_get_layer_combine_constant (pipeline, - layer_index, - constant); - GE (glProgramLocalParameter4fv (GL_FRAGMENT_PROGRAM_ARB, - unit_state->constant_id, - constant)); - unit_state->dirty_combine_constant = FALSE; - } - return TRUE; -} - -static gboolean -_cogl_pipeline_fragend_arbfp_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (pipeline); - GLuint gl_program; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (arbfp_program_state->source) - { - GLenum gl_error; - COGL_STATIC_COUNTER (fragend_arbfp_compile_counter, - "arbfp compile counter", - "Increments each time a new ARBfp " - "program is compiled", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, fragend_arbfp_compile_counter); - - g_string_append (arbfp_program_state->source, - "MOV result.color,output;\n"); - g_string_append (arbfp_program_state->source, "END\n"); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - g_message ("pipeline program:\n%s", arbfp_program_state->source->str); - - GE (glGenPrograms (1, &arbfp_program_state->gl_program)); - - GE (glBindProgram (GL_FRAGMENT_PROGRAM_ARB, - arbfp_program_state->gl_program)); - - while ((gl_error = glGetError ()) != GL_NO_ERROR) - ; - glProgramString (GL_FRAGMENT_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - arbfp_program_state->source->len, - arbfp_program_state->source->str); - if (glGetError () != GL_NO_ERROR) - { - g_warning ("\n%s\n%s", - arbfp_program_state->source->str, - glGetString (GL_PROGRAM_ERROR_STRING_ARB)); - } - - arbfp_program_state->source = NULL; - - if (G_LIKELY (!(COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - CoglPipeline *key; - - /* XXX: I wish there was a way to insert into a GHashTable - * with a pre-calculated hash value since there is a cost to - * calculating the hash of a CoglPipeline and in this case - * we know we have already called _cogl_pipeline_hash during - * _cogl_pipeline_fragend_arbfp_backend_start so we could pass the - * value through to here to avoid hashing it again. - */ - - /* XXX: Any keys referenced by the hash table need to remain - * valid all the while that there are corresponding values, - * so for now we simply make a copy of the current authority - * pipeline. - * - * FIXME: A problem with this is that our key into the cache - * may hold references to some arbitrary user textures which - * will now be kept alive indefinitly which is a shame. A - * better solution will be to derive a special "key - * pipeline" from the authority which derives from the base - * Cogl pipeline (to avoid affecting the lifetime of any - * other pipelines) and only takes a copy of the state that - * relates to the arbfp program and references small dummy - * textures instead of potentially large user textures. */ - key = cogl_pipeline_copy (arbfp_program_state->arbfp_authority); - arbfp_program_state_ref (arbfp_program_state); - g_hash_table_insert (ctx->arbfp_cache, key, arbfp_program_state); - if (G_UNLIKELY (g_hash_table_size (ctx->arbfp_cache) > 50)) - { - static gboolean seen = FALSE; - if (!seen) - g_warning ("Over 50 separate ARBfp programs have been " - "generated which is very unusual, so something " - "is probably wrong!\n"); - seen = TRUE; - } - } - - /* The authority is only valid during codegen since the program - * state may have a longer lifetime than the original authority - * it is created for. */ - arbfp_program_state->arbfp_authority = NULL; - } - - if (arbfp_program_state->user_program != COGL_INVALID_HANDLE) - { - /* An arbfp program should contain exactly one shader which we - can use directly */ - CoglProgram *program = arbfp_program_state->user_program; - CoglShader *shader = program->attached_shaders->data; - - gl_program = shader->gl_handle; - } - else - gl_program = arbfp_program_state->gl_program; - - GE (glBindProgram (GL_FRAGMENT_PROGRAM_ARB, gl_program)); - _cogl_use_fragment_program (0, COGL_PIPELINE_PROGRAM_TYPE_ARBFP); - - if (arbfp_program_state->user_program == COGL_INVALID_HANDLE) - { - UpdateConstantsState state; - state.unit = 0; - state.arbfp_program_state = arbfp_program_state; - /* If this arbfp program was last used with a different pipeline - * then we need to ensure we update all program.local params */ - state.update_all = - pipeline != arbfp_program_state->last_used_for_pipeline; - cogl_pipeline_foreach_layer (pipeline, - update_constants_cb, - &state); - } - else - { - CoglProgram *program = arbfp_program_state->user_program; - gboolean program_changed; - - /* If the shader has changed since it was last flushed then we - need to update all uniforms */ - program_changed = program->age != arbfp_program_state->user_program_age; - - _cogl_program_flush_uniforms (program, gl_program, program_changed); - - arbfp_program_state->user_program_age = program->age; - } - - /* We need to track what pipeline used this arbfp program last since - * we will need to update program.local params when switching - * between different pipelines. */ - arbfp_program_state->last_used_for_pipeline = pipeline; - - return TRUE; -} - -static void -dirty_arbfp_program_state (CoglPipeline *pipeline) -{ - CoglPipelineFragendARBfpPrivate *priv; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - priv = get_arbfp_priv (pipeline); - if (!priv) - return; - - if (priv->arbfp_program_state) - { - arbfp_program_state_unref (priv->arbfp_program_state); - priv->arbfp_program_state = NULL; - } -} - -static void -_cogl_pipeline_fragend_arbfp_pipeline_pre_change_notify ( - CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - if ((change & COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN)) - dirty_arbfp_program_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_fragend_arbfp_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineFragendARBfpPrivate *priv = get_arbfp_priv (owner); - if (!priv) - return; - - if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN)) - { - dirty_arbfp_program_state (owner); - return; - } - - if (change & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT) - { - ArbfpProgramState *arbfp_program_state = get_arbfp_program_state (owner); - - if (arbfp_program_state) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - arbfp_program_state->unit_state[unit_index].dirty_combine_constant = - TRUE; - } - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ - return; -} - -static void -_cogl_pipeline_fragend_arbfp_free_priv (CoglPipeline *pipeline) -{ - CoglPipelineFragendARBfpPrivate *priv = get_arbfp_priv (pipeline); - if (priv) - { - if (priv->arbfp_program_state) - arbfp_program_state_unref (priv->arbfp_program_state); - g_slice_free (CoglPipelineFragendARBfpPrivate, priv); - set_arbfp_priv (pipeline, NULL); - } -} - -const CoglPipelineFragend _cogl_pipeline_arbfp_fragend = -{ - _cogl_pipeline_fragend_arbfp_start, - _cogl_pipeline_fragend_arbfp_add_layer, - _cogl_pipeline_fragend_arbfp_passthrough, - _cogl_pipeline_fragend_arbfp_end, - _cogl_pipeline_fragend_arbfp_pipeline_pre_change_notify, - NULL, - _cogl_pipeline_fragend_arbfp_layer_pre_change_notify, - _cogl_pipeline_fragend_arbfp_free_priv -}; - -#endif /* COGL_PIPELINE_FRAGEND_ARBFP */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-fragend-fixed-private.h b/clutter/cogl/cogl/cogl-pipeline-fragend-fixed-private.h deleted file mode 100644 index 79aaf83..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-fragend-fixed-private.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PIPELINE_FRAGEND_FIXED_PRIVATE_H -#define __COGL_PIPELINE_FRAGEND_FIXED_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineFragend _cogl_pipeline_fixed_fragend; - -#endif /* __COGL_PIPELINE_FRAGEND_FIXED_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-fragend-fixed.c b/clutter/cogl/cogl/cogl-pipeline-fragend-fixed.c deleted file mode 100644 index 5f9fb7f..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-fragend-fixed.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" - -#ifdef COGL_PIPELINE_FRAGEND_FIXED - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" - -#include "cogl-texture-private.h" -#include "cogl-blend-string.h" -#include "cogl-profile.h" -#include "cogl-program-private.h" - -#include -#include -#include - -const CoglPipelineFragend _cogl_pipeline_fixed_fragend; - -static void -_cogl_disable_texture_unit (int unit_index) -{ - CoglTextureUnit *unit; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - unit = &g_array_index (ctx->texture_units, CoglTextureUnit, unit_index); - - if (unit->enabled_gl_target) - { - _cogl_set_active_texture_unit (unit_index); - GE (glDisable (unit->enabled_gl_target)); - unit->enabled_gl_target = 0; - } -} - -static int -get_max_texture_units (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - /* This function is called quite often so we cache the value to - avoid too many GL calls */ - if (ctx->max_texture_units == -1) - { - ctx->max_texture_units = 1; - GE (glGetIntegerv (GL_MAX_TEXTURE_UNITS, - &ctx->max_texture_units)); - } - - return ctx->max_texture_units; -} - -static gboolean -_cogl_pipeline_fragend_fixed_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference, - int n_tex_coord_attribs) -{ - CoglHandle user_program; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) - return FALSE; - - /* If there is a user program with a fragment shader then the - appropriate backend for that language should handle it. We can - still use the fixed fragment backend if the program only contains - a vertex shader */ - user_program = cogl_pipeline_get_user_program (pipeline); - if (user_program != COGL_INVALID_HANDLE && - _cogl_program_has_fragment_shader (user_program)) - return FALSE; - - _cogl_use_fragment_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED); - return TRUE; -} - -static gboolean -_cogl_pipeline_fragend_fixed_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - CoglTextureUnit *unit = - _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer)); - int unit_index = unit->index; - int n_rgb_func_args; - int n_alpha_func_args; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* XXX: Beware that since we are changing the active texture unit we - * must make sure we don't call into other Cogl components that may - * temporarily bind texture objects to query/modify parameters since - * they will end up binding texture unit 1. See - * _cogl_bind_gl_texture_transient for more details. - */ - _cogl_set_active_texture_unit (unit_index); - - if (G_UNLIKELY (unit_index >= get_max_texture_units ())) - { - _cogl_disable_texture_unit (unit_index); - /* TODO: although this isn't considered an error that - * warrants falling back to a different backend we - * should print a warning here. */ - return TRUE; - } - - /* Handle enabling or disabling the right texture target */ - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET) - { - CoglPipelineLayer *tex_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - CoglPipelineLayer *target_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET); - /* XXX: currently layers with no associated texture fallback to - * using ctx->default_gl_texture_2d_tex so they have a texture - * target of GL_TEXTURE_2D */ - GLenum gl_target = - tex_authority->texture ? target_authority->target : GL_TEXTURE_2D; - - _cogl_set_active_texture_unit (unit_index); - - /* The common GL code handles binding the right texture so we - just need to handle enabling and disabling it */ - - if (unit->enabled_gl_target != gl_target) - { - /* Disable the previous target if it's still enabled */ - if (unit->enabled_gl_target) - GE (glDisable (unit->enabled_gl_target)); - - /* Enable the new target */ - if (!G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) - { - GE (glEnable (gl_target)); - unit->enabled_gl_target = gl_target; - } - } - } - else - { - /* Even though there may be no difference between the last flushed - * texture state and the current layers texture state it may be that the - * texture unit has been disabled for some time so we need to assert that - * it's enabled now. - */ - if (!G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)) && - !unit->enabled_gl_target == 0) - { - _cogl_set_active_texture_unit (unit_index); - GE (glEnable (unit->gl_target)); - unit->enabled_gl_target = unit->gl_target; - } - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE) - { - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = authority->big_state; - - GE (glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE)); - - /* Set the combiner functions... */ - GE (glTexEnvi (GL_TEXTURE_ENV, - GL_COMBINE_RGB, - big_state->texture_combine_rgb_func)); - GE (glTexEnvi (GL_TEXTURE_ENV, - GL_COMBINE_ALPHA, - big_state->texture_combine_alpha_func)); - - /* - * Setup the function arguments... - */ - - /* For the RGB components... */ - n_rgb_func_args = - _cogl_get_n_args_for_combine_func (big_state->texture_combine_rgb_func); - - GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, - big_state->texture_combine_rgb_src[0])); - GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, - big_state->texture_combine_rgb_op[0])); - if (n_rgb_func_args > 1) - { - GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, - big_state->texture_combine_rgb_src[1])); - GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, - big_state->texture_combine_rgb_op[1])); - } - if (n_rgb_func_args > 2) - { - GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_RGB, - big_state->texture_combine_rgb_src[2])); - GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB, - big_state->texture_combine_rgb_op[2])); - } - - /* For the Alpha component */ - n_alpha_func_args = - _cogl_get_n_args_for_combine_func (big_state->texture_combine_alpha_func); - - GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, - big_state->texture_combine_alpha_src[0])); - GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, - big_state->texture_combine_alpha_op[0])); - if (n_alpha_func_args > 1) - { - GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, - big_state->texture_combine_alpha_src[1])); - GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, - big_state->texture_combine_alpha_op[1])); - } - if (n_alpha_func_args > 2) - { - GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_ALPHA, - big_state->texture_combine_alpha_src[2])); - GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, - big_state->texture_combine_alpha_op[2])); - } - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT) - { - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority - (layer, COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT); - CoglPipelineLayerBigState *big_state = authority->big_state; - - GE (glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, - big_state->texture_combine_constant)); - } - - return TRUE; -} - -static gboolean -get_highest_unit_index_cb (CoglPipelineLayer *layer, - void *user_data) -{ - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - int *highest_index = user_data; - - *highest_index = unit_index; - - return TRUE; -} - -static gboolean -_cogl_pipeline_fragend_fixed_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - int highest_unit_index = -1; - int i; - - _COGL_GET_CONTEXT (ctx, FALSE); - - _cogl_pipeline_foreach_layer_internal (pipeline, - get_highest_unit_index_cb, - &highest_unit_index); - - /* Disable additional texture units that may have previously been in use.. */ - for (i = highest_unit_index + 1; i < ctx->texture_units->len; i++) - _cogl_disable_texture_unit (i); - - if (pipelines_difference & COGL_PIPELINE_STATE_FOG) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_FOG); - CoglPipelineFogState *fog_state = &authority->big_state->fog_state; - - if (fog_state->enabled) - { - GLfloat fogColor[4]; - GLenum gl_mode = GL_LINEAR; - - fogColor[0] = cogl_color_get_red_float (&fog_state->color); - fogColor[1] = cogl_color_get_green_float (&fog_state->color); - fogColor[2] = cogl_color_get_blue_float (&fog_state->color); - fogColor[3] = cogl_color_get_alpha_float (&fog_state->color); - - GE (glEnable (GL_FOG)); - - GE (glFogfv (GL_FOG_COLOR, fogColor)); - -#if HAVE_COGL_GLES - switch (fog_state->mode) - { - case COGL_FOG_MODE_LINEAR: - gl_mode = GL_LINEAR; - break; - case COGL_FOG_MODE_EXPONENTIAL: - gl_mode = GL_EXP; - break; - case COGL_FOG_MODE_EXPONENTIAL_SQUARED: - gl_mode = GL_EXP2; - break; - } -#endif - /* TODO: support other modes for GLES2 */ - - /* NB: GLES doesn't have glFogi */ - GE (glFogf (GL_FOG_MODE, gl_mode)); - GE (glHint (GL_FOG_HINT, GL_NICEST)); - - GE (glFogf (GL_FOG_DENSITY, fog_state->density)); - GE (glFogf (GL_FOG_START, fog_state->z_near)); - GE (glFogf (GL_FOG_END, fog_state->z_far)); - } - else - GE (glDisable (GL_FOG)); - } - - return TRUE; -} - -const CoglPipelineFragend _cogl_pipeline_fixed_fragend = -{ - _cogl_pipeline_fragend_fixed_start, - _cogl_pipeline_fragend_fixed_add_layer, - NULL, /* passthrough */ - _cogl_pipeline_fragend_fixed_end, - NULL, /* pipeline_change_notify */ - NULL, /* pipeline_set_parent_notify */ - NULL, /* layer_change_notify */ - NULL /* free_priv */ -}; - -#endif /* COGL_PIPELINE_FRAGEND_FIXED */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-fragend-glsl-private.h b/clutter/cogl/cogl/cogl-pipeline-fragend-glsl-private.h deleted file mode 100644 index 3542d6c..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-fragend-glsl-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PIPELINE_FRAGEND_GLSL_PRIVATE_H -#define __COGL_PIPELINE_FRAGEND_GLSL_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineFragend _cogl_pipeline_glsl_fragend; - -GLuint -_cogl_pipeline_fragend_glsl_get_shader (CoglPipeline *pipeline); - -#endif /* __COGL_PIPELINE_FRAGEND_GLSL_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-fragend-glsl.c b/clutter/cogl/cogl/cogl-pipeline-fragend-glsl.c deleted file mode 100644 index b101ab3..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-fragend-glsl.c +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl-pipeline-private.h" -#include "cogl-shader-private.h" -#include "cogl-blend-string.h" - -#ifdef COGL_PIPELINE_FRAGEND_GLSL - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-shader-private.h" -#include "cogl-program-private.h" - -#ifndef HAVE_COGL_GLES2 - -#define glCreateShader ctx->drv.pf_glCreateShader -#define glGetShaderiv ctx->drv.pf_glGetShaderiv -#define glGetShaderInfoLog ctx->drv.pf_glGetShaderInfoLog -#define glCompileShader ctx->drv.pf_glCompileShader -#define glShaderSource ctx->drv.pf_glShaderSource -#define glDeleteShader ctx->drv.pf_glDeleteShader - -#endif /* HAVE_COGL_GLES2 */ - -#include - -/* - * GL/GLES compatability defines for pipeline thingies: - */ - -/* This might not be defined on GLES */ -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif - -typedef struct _UnitState -{ - unsigned int sampled:1; - unsigned int combine_constant_used:1; -} UnitState; - -typedef struct _GlslShaderState -{ - int ref_count; - - GLuint gl_shader; - GString *header, *source; - UnitState *unit_state; - - /* Age of the user program that was current when the shader was - generated. We need to keep track of this because if the user - program changes then we may need to redecide whether to generate - a shader at all */ - unsigned int user_program_age; -} GlslShaderState; - -typedef struct _CoglPipelineFragendGlslPrivate -{ - GlslShaderState *glsl_shader_state; -} CoglPipelineFragendGlslPrivate; - -const CoglPipelineFragend _cogl_pipeline_glsl_backend; - -static GlslShaderState * -glsl_shader_state_new (int n_layers) -{ - GlslShaderState *state = g_slice_new0 (GlslShaderState); - - state->ref_count = 1; - state->unit_state = g_new0 (UnitState, n_layers); - - return state; -} - -static GlslShaderState * -glsl_shader_state_ref (GlslShaderState *state) -{ - state->ref_count++; - return state; -} - -void -glsl_shader_state_unref (GlslShaderState *state) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (state->ref_count > 0); - - state->ref_count--; - if (state->ref_count == 0) - { - if (state->gl_shader) - GE( glDeleteShader (state->gl_shader) ); - - g_free (state->unit_state); - - g_slice_free (GlslShaderState, state); - } -} - -static CoglPipelineFragendGlslPrivate * -get_glsl_priv (CoglPipeline *pipeline) -{ - if (!(pipeline->fragend_priv_set_mask & COGL_PIPELINE_FRAGEND_GLSL_MASK)) - return NULL; - - return pipeline->fragend_privs[COGL_PIPELINE_FRAGEND_GLSL]; -} - -static void -set_glsl_priv (CoglPipeline *pipeline, CoglPipelineFragendGlslPrivate *priv) -{ - if (priv) - { - pipeline->fragend_privs[COGL_PIPELINE_FRAGEND_GLSL] = priv; - pipeline->fragend_priv_set_mask |= COGL_PIPELINE_FRAGEND_GLSL_MASK; - } - else - pipeline->fragend_priv_set_mask &= ~COGL_PIPELINE_FRAGEND_GLSL_MASK; -} - -static GlslShaderState * -get_glsl_shader_state (CoglPipeline *pipeline) -{ - CoglPipelineFragendGlslPrivate *priv = get_glsl_priv (pipeline); - if (!priv) - return NULL; - return priv->glsl_shader_state; -} - -GLuint -_cogl_pipeline_fragend_glsl_get_shader (CoglPipeline *pipeline) -{ - GlslShaderState *glsl_shader_state = get_glsl_shader_state (pipeline); - - if (glsl_shader_state) - return glsl_shader_state->gl_shader; - else - return 0; -} - -static void -dirty_glsl_shader_state (CoglPipeline *pipeline) -{ - CoglPipelineFragendGlslPrivate *priv; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - priv = get_glsl_priv (pipeline); - if (!priv) - return; - - if (priv->glsl_shader_state) - { - glsl_shader_state_unref (priv->glsl_shader_state); - priv->glsl_shader_state = NULL; - } -} - -static gboolean -_cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference, - int n_tex_coord_attribs) -{ - CoglPipelineFragendGlslPrivate *priv; - CoglPipeline *authority; - CoglPipelineFragendGlslPrivate *authority_priv; - CoglProgram *user_program; - int i; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) - return FALSE; - - user_program = cogl_pipeline_get_user_program (pipeline); - - /* If the user fragment shader isn't GLSL then we should let - another backend handle it */ - if (user_program && - _cogl_program_has_fragment_shader (user_program) && - _cogl_program_get_language (user_program) != COGL_SHADER_LANGUAGE_GLSL) - return FALSE; - - /* Now lookup our glsl backend private state (allocating if - * necessary) */ - priv = get_glsl_priv (pipeline); - if (!priv) - { - priv = g_slice_new0 (CoglPipelineFragendGlslPrivate); - set_glsl_priv (pipeline, priv); - } - - if (!priv->glsl_shader_state) - { - /* If we don't have an associated glsl shader yet then find the - * glsl-authority (the oldest ancestor whose state will result in - * the same shader being generated as for this pipeline). - * - * We always make sure to associate new shader with the - * glsl-authority to maximize the chance that other pipelines can - * share it. - */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN & - ~COGL_PIPELINE_STATE_LAYERS, - COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN); - - authority_priv = get_glsl_priv (authority); - if (!authority_priv) - { - authority_priv = g_slice_new0 (CoglPipelineFragendGlslPrivate); - set_glsl_priv (authority, authority_priv); - } - - /* If we don't have an existing program associated with the - * glsl-authority then start generating code for a new shader... - */ - if (!authority_priv->glsl_shader_state) - { - GlslShaderState *glsl_shader_state = - glsl_shader_state_new (n_layers); - authority_priv->glsl_shader_state = glsl_shader_state; - } - - /* If the pipeline isn't actually its own glsl-authority - * then take a reference to the program state associated - * with the glsl-authority... */ - if (authority != pipeline) - priv->glsl_shader_state = - glsl_shader_state_ref (authority_priv->glsl_shader_state); - } - - if (priv->glsl_shader_state->gl_shader) - { - /* If we already have a valid GLSL shader then we don't need to - generate a new one. However if there's a user program and it - has changed since the last link then we do need a new shader */ - if (user_program == NULL || - (priv->glsl_shader_state->user_program_age == user_program->age)) - return TRUE; - - /* We need to recreate the shader so destroy the existing one */ - GE( glDeleteShader (priv->glsl_shader_state->gl_shader) ); - priv->glsl_shader_state->gl_shader = 0; - } - - /* If we make it here then we have a glsl_shader_state struct - without a gl_shader either because this is the first time we've - encountered it or because the user program has changed */ - - if (user_program) - priv->glsl_shader_state->user_program_age = user_program->age; - - /* If the user program contains a fragment shader then we don't need - to generate one */ - if (user_program && - _cogl_program_has_fragment_shader (user_program)) - return TRUE; - - /* We reuse two grow-only GStrings for code-gen. One string - contains the uniform and attribute declarations while the - other contains the main function. We need two strings - because we need to dynamically declare attributes as the - add_layer callback is invoked */ - g_string_set_size (ctx->codegen_header_buffer, 0); - g_string_set_size (ctx->codegen_source_buffer, 0); - priv->glsl_shader_state->header = ctx->codegen_header_buffer; - priv->glsl_shader_state->source = ctx->codegen_source_buffer; - - g_string_append (priv->glsl_shader_state->source, - "void\n" - "main ()\n" - "{\n"); - - for (i = 0; i < n_layers; i++) - { - priv->glsl_shader_state->unit_state[i].sampled = FALSE; - priv->glsl_shader_state->unit_state[i].combine_constant_used = FALSE; - } - - return TRUE; -} - -static void -add_constant_lookup (GlslShaderState *glsl_shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - const char *swizzle) -{ - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - /* Create a sampler uniform for this layer if we haven't already */ - if (!glsl_shader_state->unit_state[unit_index].combine_constant_used) - { - g_string_append_printf (glsl_shader_state->header, - "uniform vec4 _cogl_layer_constant_%i;\n", - unit_index); - glsl_shader_state->unit_state[unit_index].combine_constant_used = TRUE; - } - - g_string_append_printf (glsl_shader_state->source, - "_cogl_layer_constant_%i.%s", - unit_index, swizzle); -} - -static void -add_texture_lookup (GlslShaderState *glsl_shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - const char *swizzle) -{ - CoglHandle texture; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - const char *target_string, *tex_coord_swizzle; - - texture = _cogl_pipeline_layer_get_texture (layer); - - if (texture == COGL_INVALID_HANDLE) - { - target_string = "2D"; - tex_coord_swizzle = "st"; - } - else - { - GLenum gl_target; - - cogl_texture_get_gl_texture (texture, NULL, &gl_target); - switch (gl_target) - { -#ifndef HAVE_COGL_GLES2 - case GL_TEXTURE_1D: - target_string = "1D"; - tex_coord_swizzle = "s"; - break; -#endif - - case GL_TEXTURE_2D: - target_string = "2D"; - tex_coord_swizzle = "st"; - break; - -#ifdef GL_ARB_texture_rectangle - case GL_TEXTURE_RECTANGLE_ARB: - target_string = "2DRect"; - tex_coord_swizzle = "st"; - break; -#endif - - case GL_TEXTURE_3D: - target_string = "3D"; - tex_coord_swizzle = "stp"; - break; - - default: - g_assert_not_reached (); - } - } - - /* Create a sampler uniform for this layer if we haven't already */ - if (!glsl_shader_state->unit_state[unit_index].sampled) - { - g_string_append_printf (glsl_shader_state->header, - "uniform sampler%s _cogl_sampler_%i;\n", - target_string, - unit_index); - glsl_shader_state->unit_state[unit_index].sampled = TRUE; - } - - g_string_append_printf (glsl_shader_state->source, - "texture%s (_cogl_sampler_%i, ", - target_string, unit_index); - - /* If point sprite coord generation is being used then divert to the - built-in varying var for that instead of the texture - coordinates. We don't want to do this under GL because in that - case we will instead use glTexEnv(GL_COORD_REPLACE) to replace - the texture coords with the point sprite coords. Although GL also - supports the gl_PointCoord variable, it requires GLSL 1.2 which - would mean we would have to declare the GLSL version and check - for it */ -#ifdef HAVE_COGL_GLES2 - if (cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline, - layer->index)) - g_string_append_printf (glsl_shader_state->source, - "gl_PointCoord.%s", - tex_coord_swizzle); - else -#endif - g_string_append_printf (glsl_shader_state->source, - "cogl_tex_coord_in[%d].%s", - unit_index, tex_coord_swizzle); - - g_string_append_printf (glsl_shader_state->source, ").%s", swizzle); -} - -typedef struct -{ - int unit_index; - CoglPipelineLayer *layer; -} FindPipelineLayerData; - -static gboolean -find_pipeline_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - FindPipelineLayerData *data = user_data; - int unit_index; - - unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - if (unit_index == data->unit_index) - { - data->layer = layer; - return FALSE; - } - - return TRUE; -} - -static void -add_arg (GlslShaderState *glsl_shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - CoglPipelineCombineSource src, - CoglPipelineCombineOp operand, - const char *swizzle) -{ - GString *shader_source = glsl_shader_state->source; - char alpha_swizzle[5] = "aaaa"; - - g_string_append_c (shader_source, '('); - - if (operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR || - operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA) - g_string_append_printf (shader_source, - "vec4(1.0, 1.0, 1.0, 1.0).%s - ", - swizzle); - - /* If the operand is reading from the alpha then replace the swizzle - with the same number of copies of the alpha */ - if (operand == COGL_PIPELINE_COMBINE_OP_SRC_ALPHA || - operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA) - { - alpha_swizzle[strlen (swizzle)] = '\0'; - swizzle = alpha_swizzle; - } - - switch (src) - { - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - add_texture_lookup (glsl_shader_state, - pipeline, - layer, - swizzle); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - add_constant_lookup (glsl_shader_state, - pipeline, - layer, - swizzle); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - if (_cogl_pipeline_layer_get_unit_index (layer) > 0) - { - g_string_append_printf (shader_source, "cogl_color_out.%s", swizzle); - break; - } - /* flow through */ - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - g_string_append_printf (shader_source, "cogl_color_in.%s", swizzle); - break; - - default: - if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 && - src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32) - { - FindPipelineLayerData data; - - data.unit_index = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - data.layer = layer; - - _cogl_pipeline_foreach_layer_internal (pipeline, - find_pipeline_layer_cb, - &data); - - add_texture_lookup (glsl_shader_state, - pipeline, - data.layer, - swizzle); - } - break; - } - - g_string_append_c (shader_source, ')'); -} - -static void -append_masked_combine (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - const char *swizzle, - CoglPipelineCombineFunc function, - CoglPipelineCombineSource *src, - CoglPipelineCombineOp *op) -{ - GlslShaderState *glsl_shader_state = get_glsl_shader_state (pipeline); - GString *shader_source = glsl_shader_state->source; - - g_string_append_printf (glsl_shader_state->source, - " cogl_color_out.%s = ", swizzle); - - switch (function) - { - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], swizzle); - g_string_append (shader_source, " * "); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_ADD: - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], swizzle); - g_string_append (shader_source, " + "); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], swizzle); - g_string_append (shader_source, " + "); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], swizzle); - g_string_append_printf (shader_source, - " - vec4(0.5, 0.5, 0.5, 0.5).%s", - swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], swizzle); - g_string_append (shader_source, " - "); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], swizzle); - g_string_append (shader_source, " * "); - add_arg (glsl_shader_state, pipeline, layer, - src[2], op[2], swizzle); - g_string_append (shader_source, " + "); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], swizzle); - g_string_append_printf (shader_source, - " * (vec4(1.0, 1.0, 1.0, 1.0).%s - ", - swizzle); - add_arg (glsl_shader_state, pipeline, layer, - src[2], op[2], swizzle); - g_string_append_c (shader_source, ')'); - break; - - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - g_string_append (shader_source, "vec4(4.0 * (("); - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], "r"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], "r"); - g_string_append (shader_source, " - 0.5) + ("); - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], "g"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], "g"); - g_string_append (shader_source, " - 0.5) + ("); - add_arg (glsl_shader_state, pipeline, layer, - src[0], op[0], "b"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (glsl_shader_state, pipeline, layer, - src[1], op[1], "b"); - g_string_append_printf (shader_source, " - 0.5))).%s", swizzle); - break; - } - - g_string_append_printf (shader_source, ";\n"); -} - -static gboolean -_cogl_pipeline_fragend_glsl_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - GlslShaderState *glsl_shader_state = get_glsl_shader_state (pipeline); - CoglPipelineLayer *combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - - if (!glsl_shader_state->source) - return TRUE; - - if (!_cogl_pipeline_need_texture_combine_separate (combine_authority) || - /* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function - * since if you use it, it overrides your ALPHA function... - */ - big_state->texture_combine_rgb_func == - COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA) - append_masked_combine (pipeline, - layer, - "rgba", - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - else - { - append_masked_combine (pipeline, - layer, - "rgb", - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - append_masked_combine (pipeline, - layer, - "a", - big_state->texture_combine_alpha_func, - big_state->texture_combine_alpha_src, - big_state->texture_combine_alpha_op); - } - - return TRUE; -} - -gboolean -_cogl_pipeline_fragend_glsl_passthrough (CoglPipeline *pipeline) -{ - GlslShaderState *glsl_shader_state = get_glsl_shader_state (pipeline); - - if (!glsl_shader_state->source) - return TRUE; - - g_string_append (glsl_shader_state->source, - " cogl_color_out = cogl_color_in;\n"); - - return TRUE; -} - -/* GLES2 doesn't have alpha testing so we need to implement it in the - shader */ - -#ifdef HAVE_COGL_GLES2 - -static void -add_alpha_test_snippet (CoglPipeline *pipeline, - GlslShaderState *glsl_shader_state) -{ - CoglPipelineAlphaFunc alpha_func; - - alpha_func = cogl_pipeline_get_alpha_test_function (pipeline); - - if (alpha_func == COGL_PIPELINE_ALPHA_FUNC_ALWAYS) - /* Do nothing */ - return; - - if (alpha_func == COGL_PIPELINE_ALPHA_FUNC_NEVER) - { - /* Always discard the fragment */ - g_string_append (glsl_shader_state->source, - " discard;\n"); - return; - } - - /* For all of the other alpha functions we need a uniform for the - reference */ - - g_string_append (glsl_shader_state->header, - "uniform float _cogl_alpha_test_ref;\n"); - - g_string_append (glsl_shader_state->source, - " if (cogl_color_out.a "); - - switch (alpha_func) - { - case COGL_PIPELINE_ALPHA_FUNC_LESS: - g_string_append (glsl_shader_state->source, ">="); - break; - case COGL_PIPELINE_ALPHA_FUNC_EQUAL: - g_string_append (glsl_shader_state->source, "!="); - break; - case COGL_PIPELINE_ALPHA_FUNC_LEQUAL: - g_string_append (glsl_shader_state->source, ">"); - break; - case COGL_PIPELINE_ALPHA_FUNC_GREATER: - g_string_append (glsl_shader_state->source, "<="); - break; - case COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL: - g_string_append (glsl_shader_state->source, "=="); - break; - case COGL_PIPELINE_ALPHA_FUNC_GEQUAL: - g_string_append (glsl_shader_state->source, "< "); - break; - - case COGL_PIPELINE_ALPHA_FUNC_ALWAYS: - case COGL_PIPELINE_ALPHA_FUNC_NEVER: - g_assert_not_reached (); - break; - } - - g_string_append (glsl_shader_state->source, - " _cogl_alpha_test_ref)\n discard;\n"); -} - -#endif /* HAVE_COGL_GLES2 */ - -gboolean -_cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - GlslShaderState *glsl_shader_state = get_glsl_shader_state (pipeline); - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (glsl_shader_state->source) - { - const char *source_strings[2]; - GLint lengths[2]; - GLint compile_status; - GLuint shader; - int n_tex_coord_attribs = 0; - int i, n_layers; - - COGL_STATIC_COUNTER (fragend_glsl_compile_counter, - "glsl fragment compile counter", - "Increments each time a new GLSL " - "fragment shader is compiled", - 0 /* no application private data */); - COGL_COUNTER_INC (_cogl_uprof_context, fragend_glsl_compile_counter); - -#ifdef HAVE_COGL_GLES2 - add_alpha_test_snippet (pipeline, glsl_shader_state); -#endif - - g_string_append (glsl_shader_state->source, "}\n"); - - GE_RET( shader, glCreateShader (GL_FRAGMENT_SHADER) ); - - lengths[0] = glsl_shader_state->header->len; - source_strings[0] = glsl_shader_state->header->str; - lengths[1] = glsl_shader_state->source->len; - source_strings[1] = glsl_shader_state->source->str; - - /* Find the highest texture unit that is sampled to pass as the - number of texture coordinate attributes */ - n_layers = cogl_pipeline_get_n_layers (pipeline); - for (i = 0; i < n_layers; i++) - if (glsl_shader_state->unit_state[i].sampled) - n_tex_coord_attribs = i + 1; - - _cogl_shader_set_source_with_boilerplate (shader, GL_FRAGMENT_SHADER, - n_tex_coord_attribs, - 2, /* count */ - source_strings, lengths); - - GE( glCompileShader (shader) ); - GE( glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status) ); - - if (!compile_status) - { - GLint len = 0; - char *shader_log; - - GE( glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &len) ); - shader_log = g_alloca (len); - GE( glGetShaderInfoLog (shader, len, &len, shader_log) ); - g_warning ("Shader compilation failed:\n%s", shader_log); - } - - glsl_shader_state->header = NULL; - glsl_shader_state->source = NULL; - glsl_shader_state->gl_shader = shader; - } - - return TRUE; -} - -static void -_cogl_pipeline_fragend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - if ((change & COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN)) - dirty_glsl_shader_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_fragend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineFragendGlslPrivate *priv; - - priv = get_glsl_priv (owner); - if (!priv) - return; - - if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN)) - { - dirty_glsl_shader_state (owner); - return; - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ -} - -static void -_cogl_pipeline_fragend_glsl_free_priv (CoglPipeline *pipeline) -{ - CoglPipelineFragendGlslPrivate *priv = get_glsl_priv (pipeline); - if (priv) - { - if (priv->glsl_shader_state) - glsl_shader_state_unref (priv->glsl_shader_state); - g_slice_free (CoglPipelineFragendGlslPrivate, priv); - set_glsl_priv (pipeline, NULL); - } -} - -const CoglPipelineFragend _cogl_pipeline_glsl_fragend = -{ - _cogl_pipeline_fragend_glsl_start, - _cogl_pipeline_fragend_glsl_add_layer, - _cogl_pipeline_fragend_glsl_passthrough, - _cogl_pipeline_fragend_glsl_end, - _cogl_pipeline_fragend_glsl_pre_change_notify, - NULL, /* pipeline_set_parent_notify */ - _cogl_pipeline_fragend_glsl_layer_pre_change_notify, - _cogl_pipeline_fragend_glsl_free_priv, -}; - -#endif /* COGL_PIPELINE_FRAGEND_GLSL */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-opengl-private.h b/clutter/cogl/cogl/cogl-pipeline-opengl-private.h deleted file mode 100644 index aa8dc1b..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-opengl-private.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PIPELINE_OPENGL_PRIVATE_H -#define __COGL_PIPELINE_OPENGL_PRIVATE_H - -#include "cogl.h" - -#include "cogl-pipeline-private.h" -#include "cogl-matrix-stack.h" - -/* - * cogl-pipeline.c owns the GPU's texture unit state so we have some - * private structures for describing the current state of a texture - * unit that we track in a per context array (ctx->texture_units) that - * grows according to the largest texture unit used so far... - * - * Roughly speaking the members in this structure are of two kinds: - * either they are a low level reflection of the state we send to - * OpenGL or they are for high level meta data assoicated with the - * texture unit when flushing CoglPipelineLayers that is typically - * used to optimize subsequent re-flushing of the same layer. - * - * The low level members are at the top, and the high level members - * start with the .layer member. - */ -typedef struct _CoglTextureUnit -{ - /* The base 0 texture unit index which can be used with - * glActiveTexture () */ - int index; - - /* The GL target currently glEnabled or 0 if nothing is - * enabled. This is only used by the fixed pipeline fragend */ - GLenum enabled_gl_target; - - /* The raw GL texture object name for which we called glBindTexture when - * we flushed the last layer. (NB: The CoglTexture associated - * with a layer may represent more than one GL texture) */ - GLuint gl_texture; - /* The target of the GL texture object. This is just used so that we - * can quickly determine the intended target to flush when - * dirty_gl_texture == TRUE */ - GLenum gl_target; - - /* Foreign textures are those not created or deleted by Cogl. If we ever - * call glBindTexture for a foreign texture then the next time we are - * asked to glBindTexture we can't try and optimize a redundant state - * change because we don't know if the original texture name was deleted - * and now we are being asked to bind a recycled name. */ - gboolean is_foreign; - - /* We have many components in Cogl that need to temporarily bind arbitrary - * textures e.g. to query texture object parameters and since we don't - * want that to result in too much redundant reflushing of layer state - * when all that's needed is to re-bind the layer's gl_texture we use this - * to track when the unit->gl_texture state is out of sync with the GL - * texture object really bound too (GL_TEXTURE0+unit->index). - * - * XXX: as a further optimization cogl-pipeline.c uses a convention - * of always using texture unit 1 for these transient bindings so we - * can assume this is only ever TRUE for unit 1. - */ - gboolean dirty_gl_texture; - - /* A matrix stack giving us the means to associate a texture - * transform matrix with the texture unit. */ - CoglMatrixStack *matrix_stack; - - /* - * Higher level layer state associated with the unit... - */ - - /* The CoglPipelineLayer whos state was flushed to update this - * texture unit last. - * - * This will be set to NULL if the layer is modified or freed which - * means when we come to flush a layer; if this pointer is still - * valid and == to the layer being flushed we don't need to update - * any texture unit state. */ - CoglPipelineLayer *layer; - - /* To help minimize the state changes required we track the - * difference flags associated with the layer whos state was last - * flushed to update this texture unit. - * - * Note: we track this explicitly because .layer may get invalidated - * if that layer is modified or deleted. Even if the layer is - * invalidated though these flags can be used to optimize the state - * flush of the next layer - */ - unsigned long layer_changes_since_flush; - - /* Whenever a CoglTexture's internal GL texture storage changes - * cogl-pipeline.c is notified with a call to - * _cogl_pipeline_texture_storage_change_notify which inturn sets - * this to TRUE for each texture unit that it is currently bound - * too. When we later come to flush some pipeline state then we will - * always check this to potentially force an update of the texture - * state even if the pipeline hasn't changed. */ - gboolean texture_storage_changed; - -} CoglTextureUnit; - -CoglTextureUnit * -_cogl_get_texture_unit (int index_); - -void -_cogl_destroy_texture_units (void); - -void -_cogl_set_active_texture_unit (int unit_index); - -void -_cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture, - gboolean is_foreign); - -void -_cogl_delete_gl_texture (GLuint gl_texture); - -void -_cogl_gl_use_program_wrapper (CoglHandle program); - -void -_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline, - gboolean skip_gl_state, - int n_tex_coord_attribs); - -#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-opengl.c b/clutter/cogl/cogl/cogl-pipeline-opengl.c deleted file mode 100644 index 1bf9f4d..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-opengl.c +++ /dev/null @@ -1,1332 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" - -#include "cogl-debug.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-context-private.h" -#include "cogl-texture-private.h" - -/* This is needed to set the color attribute on GLES2 */ -#ifdef HAVE_COGL_GLES2 -#include "cogl-pipeline-progend-glsl-private.h" -#endif - -#include -#include - -/* - * GL/GLES compatability defines for pipeline thingies: - */ - -#ifdef HAVE_COGL_GL -#define glActiveTexture ctx->drv.pf_glActiveTexture -#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture -#define glBlendFuncSeparate ctx->drv.pf_glBlendFuncSeparate -#define glBlendEquation ctx->drv.pf_glBlendEquation -#define glBlendColor ctx->drv.pf_glBlendColor -#define glBlendEquationSeparate ctx->drv.pf_glBlendEquationSeparate - -#define glProgramString ctx->drv.pf_glProgramString -#define glBindProgram ctx->drv.pf_glBindProgram -#define glDeletePrograms ctx->drv.pf_glDeletePrograms -#define glGenPrograms ctx->drv.pf_glGenPrograms -#define glProgramLocalParameter4fv ctx->drv.pf_glProgramLocalParameter4fv -#define glUseProgram ctx->drv.pf_glUseProgram -#endif - -/* These aren't defined in the GLES headers */ -#ifndef GL_POINT_SPRITE -#define GL_POINT_SPRITE 0x8861 -#endif -#ifndef GL_COORD_REPLACE -#define GL_COORD_REPLACE 0x8862 -#endif -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812d -#endif - - -static void -texture_unit_init (CoglTextureUnit *unit, int index_) -{ - unit->index = index_; - unit->enabled_gl_target = 0; - unit->gl_texture = 0; - unit->gl_target = 0; - unit->is_foreign = FALSE; - unit->dirty_gl_texture = FALSE; - unit->matrix_stack = _cogl_matrix_stack_new (); - - unit->layer = NULL; - unit->layer_changes_since_flush = 0; - unit->texture_storage_changed = FALSE; -} - -static void -texture_unit_free (CoglTextureUnit *unit) -{ - if (unit->layer) - cogl_object_unref (unit->layer); - cogl_object_unref (unit->matrix_stack); -} - -CoglTextureUnit * -_cogl_get_texture_unit (int index_) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - if (ctx->texture_units->len < (index_ + 1)) - { - int i; - int prev_len = ctx->texture_units->len; - ctx->texture_units = g_array_set_size (ctx->texture_units, index_ + 1); - for (i = prev_len; i <= index_; i++) - { - CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); - - texture_unit_init (unit, i); - } - } - - return &g_array_index (ctx->texture_units, CoglTextureUnit, index_); -} - -void -_cogl_destroy_texture_units (void) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (i = 0; i < ctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); - texture_unit_free (unit); - } - g_array_free (ctx->texture_units, TRUE); -} - -void -_cogl_set_active_texture_unit (int unit_index) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->active_texture_unit != unit_index) - { - GE (glActiveTexture (GL_TEXTURE0 + unit_index)); - ctx->active_texture_unit = unit_index; - } -} - -/* Note: _cogl_bind_gl_texture_transient conceptually has slightly - * different semantics to OpenGL's glBindTexture because Cogl never - * cares about tracking multiple textures bound to different targets - * on the same texture unit. - * - * glBindTexture lets you bind multiple textures to a single texture - * unit if they are bound to different targets. So it does something - * like: - * unit->current_texture[target] = texture; - * - * Cogl only lets you associate one texture with the currently active - * texture unit, so the target is basically a redundant parameter - * that's implicitly set on that texture. - * - * Technically this is just a thin wrapper around glBindTexture so - * actually it does have the GL semantics but it seems worth - * mentioning the conceptual difference in case anyone wonders why we - * don't associate the gl_texture with a gl_target in the - * CoglTextureUnit. - */ -void -_cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture, - gboolean is_foreign) -{ - CoglTextureUnit *unit; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* We choose to always make texture unit 1 active for transient - * binds so that in the common case where multitexturing isn't used - * we can simply ignore the state of this texture unit. Notably we - * didn't use a large texture unit (.e.g. (GL_MAX_TEXTURE_UNITS - 1) - * in case the driver doesn't have a sparse data structure for - * texture units. - */ - _cogl_set_active_texture_unit (1); - unit = _cogl_get_texture_unit (1); - - /* NB: If we have previously bound a foreign texture to this texture - * unit we don't know if that texture has since been deleted and we - * are seeing the texture name recycled */ - if (unit->gl_texture == gl_texture && - !unit->dirty_gl_texture && - !unit->is_foreign) - return; - - GE (glBindTexture (gl_target, gl_texture)); - - unit->dirty_gl_texture = TRUE; - unit->is_foreign = is_foreign; -} - -void -_cogl_delete_gl_texture (GLuint gl_texture) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (i = 0; i < ctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); - - if (unit->gl_texture == gl_texture) - { - unit->gl_texture = 0; - unit->gl_target = 0; - unit->dirty_gl_texture = FALSE; - } - } - - GE (glDeleteTextures (1, &gl_texture)); -} - -/* Whenever the underlying GL texture storage of a CoglTexture is - * changed (e.g. due to migration out of a texture atlas) then we are - * notified. This lets us ensure that we reflush that texture's state - * if it is reused again with the same texture unit. - */ -void -_cogl_pipeline_texture_storage_change_notify (CoglHandle texture) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (i = 0; i < ctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); - - if (unit->layer && - _cogl_pipeline_layer_get_texture (unit->layer) == texture) - unit->texture_storage_changed = TRUE; - - /* NB: the texture may be bound to multiple texture units so - * we continue to check the rest */ - } -} - -static void -set_glsl_program (GLuint gl_program) -{ -#ifdef HAVE_COGL_GLES - - g_return_if_reached (); - -#else /* HAVE_COGL_GLES */ - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->current_gl_program != gl_program) - { - GLenum gl_error; - - while ((gl_error = glGetError ()) != GL_NO_ERROR) - ; - glUseProgram (gl_program); - if (glGetError () == GL_NO_ERROR) - ctx->current_gl_program = gl_program; - else - { - GE( glUseProgram (0) ); - ctx->current_gl_program = 0; - } - } - -#endif /* HAVE_COGL_GLES */ -} - -void -_cogl_use_fragment_program (GLuint gl_program, CoglPipelineProgramType type) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If we're changing program type... */ - if (type != ctx->current_fragment_program_type) - { - /* ... disable the old type */ - switch (ctx->current_fragment_program_type) - { - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - /* If the program contains a vertex shader then we shouldn't - disable it */ - if (ctx->current_vertex_program_type != - COGL_PIPELINE_PROGRAM_TYPE_GLSL) - set_glsl_program (0); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: -#ifdef HAVE_COGL_GL - GE( glDisable (GL_FRAGMENT_PROGRAM_ARB) ); -#endif - break; - - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - - /* ... and enable the new type */ - switch (type) - { - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: -#ifdef HAVE_COGL_GL - GE( glEnable (GL_FRAGMENT_PROGRAM_ARB) ); -#endif - break; - - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - } - - if (type == COGL_PIPELINE_PROGRAM_TYPE_GLSL) - { -#ifdef COGL_PIPELINE_FRAGEND_GLSL - set_glsl_program (gl_program); - -#else - - g_warning ("Unexpected use of GLSL fragend!"); - -#endif /* COGL_PIPELINE_FRAGEND_GLSL */ - } -#ifndef COGL_PIPELINE_FRAGEND_ARBFP - else if (type == COGL_PIPELINE_PROGRAM_TYPE_ARBFP) - g_warning ("Unexpected use of ARBFP fragend!"); -#endif /* COGL_PIPELINE_FRAGEND_ARBFP */ - - ctx->current_fragment_program_type = type; -} - -void -_cogl_use_vertex_program (GLuint gl_program, CoglPipelineProgramType type) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If we're changing program type... */ - if (type != ctx->current_vertex_program_type) - { - /* ... disable the old type */ - switch (ctx->current_vertex_program_type) - { - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - /* If the program contains a fragment shader then we shouldn't - disable it */ - if (ctx->current_fragment_program_type != - COGL_PIPELINE_PROGRAM_TYPE_GLSL) - set_glsl_program (0); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: - /* It doesn't make sense to enable ARBfp for the vertex program */ - g_assert_not_reached (); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - - /* ... and enable the new type */ - switch (type) - { - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: - /* It doesn't make sense to enable ARBfp for the vertex program */ - g_assert_not_reached (); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - } - - if (type == COGL_PIPELINE_PROGRAM_TYPE_GLSL) - { -#ifdef COGL_PIPELINE_VERTEND_GLSL - set_glsl_program (gl_program); - -#else - - g_warning ("Unexpected use of GLSL vertend!"); - -#endif /* COGL_PIPELINE_VERTEND_GLSL */ - } -#ifndef COGL_PIPELINE_VERTEND_ARBFP - else if (type == COGL_PIPELINE_PROGRAM_TYPE_ARBFP) - g_warning ("Unexpected use of ARBFP vertend!"); -#endif /* COGL_PIPELINE_VERTEND_ARBFP */ - - ctx->current_vertex_program_type = type; -} - -#if defined (COGL_PIPELINE_FRAGEND_GLSL) || \ - defined (COGL_PIPELINE_FRAGEND_ARBFP) -int -_cogl_get_max_texture_image_units (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - /* This function is called quite often so we cache the value to - avoid too many GL calls */ - if (G_UNLIKELY (ctx->max_texture_image_units == -1)) - { - ctx->max_texture_image_units = 1; - GE (glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, - &ctx->max_texture_image_units)); - } - - return ctx->max_texture_image_units; -} -#endif - -#ifndef HAVE_COGL_GLES - -static gboolean -blend_factor_uses_constant (GLenum blend_factor) -{ - return (blend_factor == GL_CONSTANT_COLOR || - blend_factor == GL_ONE_MINUS_CONSTANT_COLOR || - blend_factor == GL_CONSTANT_ALPHA || - blend_factor == GL_ONE_MINUS_CONSTANT_ALPHA); -} - -#endif - -static void -flush_depth_state (CoglPipelineDepthState *depth_state) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->depth_test_function_cache != depth_state->depth_test_function) - { - GE (glDepthFunc (depth_state->depth_test_function)); - ctx->depth_test_function_cache = depth_state->depth_test_function; - } - - if (ctx->depth_writing_enabled_cache != depth_state->depth_writing_enabled) - { - GE (glDepthMask (depth_state->depth_writing_enabled ? - GL_TRUE : GL_FALSE)); - ctx->depth_writing_enabled_cache = depth_state->depth_writing_enabled; - } - -#ifndef COGL_HAS_GLES - if (ctx->depth_range_near_cache != depth_state->depth_range_near || - ctx->depth_range_far_cache != depth_state->depth_range_far) - { -#ifdef COGL_HAS_GLES2 - GE (glDepthRangef (depth_state->depth_range_near, - depth_state->depth_range_far)); -#else - GE (glDepthRange (depth_state->depth_range_near, - depth_state->depth_range_far)); -#endif - ctx->depth_range_near_cache = depth_state->depth_range_near; - ctx->depth_range_far_cache = depth_state->depth_range_far; - } -#endif /* COGL_HAS_GLES */ -} - -static void -_cogl_pipeline_flush_color_blend_alpha_depth_state ( - CoglPipeline *pipeline, - unsigned long pipelines_difference, - gboolean skip_gl_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* On GLES2 we'll flush the color later */ -#ifndef HAVE_COGL_GLES2 - if (!skip_gl_color) - { - if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) || - /* Assume if we were previously told to skip the color, then - * the current color needs updating... */ - ctx->current_pipeline_skip_gl_color) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - GE (glColor4ub (cogl_color_get_red_byte (&authority->color), - cogl_color_get_green_byte (&authority->color), - cogl_color_get_blue_byte (&authority->color), - cogl_color_get_alpha_byte (&authority->color))); - } - } -#endif - - if (pipelines_difference & COGL_PIPELINE_STATE_BLEND) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND); - CoglPipelineBlendState *blend_state = - &authority->big_state->blend_state; - -#if defined (HAVE_COGL_GLES2) - gboolean have_blend_equation_seperate = TRUE; - gboolean have_blend_func_separate = TRUE; -#elif defined (HAVE_COGL_GL) - gboolean have_blend_equation_seperate = FALSE; - gboolean have_blend_func_separate = FALSE; - if (ctx->drv.pf_glBlendEquationSeparate) /* Only GL 2.0 + */ - have_blend_equation_seperate = TRUE; - if (ctx->drv.pf_glBlendFuncSeparate) /* Only GL 1.4 + */ - have_blend_func_separate = TRUE; -#endif - -#ifndef HAVE_COGL_GLES /* GLES 1 only has glBlendFunc */ - if (blend_factor_uses_constant (blend_state->blend_src_factor_rgb) || - blend_factor_uses_constant (blend_state->blend_src_factor_alpha) || - blend_factor_uses_constant (blend_state->blend_dst_factor_rgb) || - blend_factor_uses_constant (blend_state->blend_dst_factor_alpha)) - { - float red = - cogl_color_get_red_float (&blend_state->blend_constant); - float green = - cogl_color_get_green_float (&blend_state->blend_constant); - float blue = - cogl_color_get_blue_float (&blend_state->blend_constant); - float alpha = - cogl_color_get_alpha_float (&blend_state->blend_constant); - - - GE (glBlendColor (red, green, blue, alpha)); - } - - if (have_blend_equation_seperate && - blend_state->blend_equation_rgb != blend_state->blend_equation_alpha) - GE (glBlendEquationSeparate (blend_state->blend_equation_rgb, - blend_state->blend_equation_alpha)); - else - GE (glBlendEquation (blend_state->blend_equation_rgb)); - - if (have_blend_func_separate && - (blend_state->blend_src_factor_rgb != blend_state->blend_src_factor_alpha || - (blend_state->blend_src_factor_rgb != - blend_state->blend_src_factor_alpha))) - GE (glBlendFuncSeparate (blend_state->blend_src_factor_rgb, - blend_state->blend_dst_factor_rgb, - blend_state->blend_src_factor_alpha, - blend_state->blend_dst_factor_alpha)); - else -#endif - GE (glBlendFunc (blend_state->blend_src_factor_rgb, - blend_state->blend_dst_factor_rgb)); - } - -#ifndef HAVE_COGL_GLES2 - - /* Under GLES2 the alpha function is implemented as part of the - fragment shader */ - if (pipelines_difference & (COGL_PIPELINE_STATE_ALPHA_FUNC | - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE)) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC); - CoglPipelineAlphaFuncState *alpha_state = - &authority->big_state->alpha_state; - - /* NB: Currently the Cogl defines are compatible with the GL ones: */ - GE (glAlphaFunc (alpha_state->alpha_func, - alpha_state->alpha_func_reference)); - } - - /* Under GLES2 the lighting parameters are implemented as uniforms - in the progend */ - if (pipelines_difference & COGL_PIPELINE_STATE_LIGHTING) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - CoglPipelineLightingState *lighting_state = - &authority->big_state->lighting_state; - - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, - lighting_state->ambient)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, - lighting_state->diffuse)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, - lighting_state->specular)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, - lighting_state->emission)); - GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, - &lighting_state->shininess)); - } - -#endif /* HAVE_COGL_GLES2 */ - - if (pipelines_difference & COGL_PIPELINE_STATE_DEPTH) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - CoglPipelineDepthState *depth_state = &authority->big_state->depth_state; - - if (depth_state->depth_test_enabled) - { - if (ctx->depth_test_enabled_cache != TRUE) - { - GE (glEnable (GL_DEPTH_TEST)); - ctx->depth_test_enabled_cache = depth_state->depth_test_enabled; - } - flush_depth_state (depth_state); - } - else if (ctx->depth_test_enabled_cache != FALSE) - { - GE (glDisable (GL_DEPTH_TEST)); - ctx->depth_test_enabled_cache = depth_state->depth_test_enabled; - } - } - - if (pipeline->real_blend_enable != ctx->gl_blend_enable_cache) - { - if (pipeline->real_blend_enable) - GE (glEnable (GL_BLEND)); - else - GE (glDisable (GL_BLEND)); - /* XXX: we shouldn't update any other blend state if blending - * is disabled! */ - ctx->gl_blend_enable_cache = pipeline->real_blend_enable; - } -} - -static int -get_max_activateable_texture_units (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - if (G_UNLIKELY (ctx->max_activateable_texture_units == -1)) - { -#if defined (HAVE_COGL_GL) - GLint max_tex_coords; - GLint max_combined_tex_units; - GE (glGetIntegerv (GL_MAX_TEXTURE_COORDS, &max_tex_coords)); - GE (glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - &max_combined_tex_units)); - ctx->max_activateable_texture_units = - MAX (max_tex_coords - 1, max_combined_tex_units); -#elif defined (HAVE_COGL_GLES2) - GLint max_vertex_attribs; - GLint max_combined_tex_units; - GE (glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs)); - GE (glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - &max_combined_tex_units)); - /* Two of the vertex attribs need to be used for the position - and color */ - ctx->max_activateable_texture_units = - MAX (max_vertex_attribs - 2, max_combined_tex_units); -#else - GE (glGetIntegerv (GL_MAX_TEXTURE_UNITS, - &ctx->max_activateable_texture_units)); -#endif - } - - return ctx->max_activateable_texture_units; -} - -typedef struct -{ - int i; - unsigned long *layer_differences; -} CoglPipelineFlushLayerState; - -static gboolean -flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineFlushLayerState *flush_state = user_data; - int unit_index = flush_state->i; - CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index); - unsigned long layers_difference = - flush_state->layer_differences[unit_index]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* There may not be enough texture units so we can bail out if - * that's the case... - */ - if (G_UNLIKELY (unit_index >= get_max_activateable_texture_units ())) - { - static gboolean shown_warning = FALSE; - - if (!shown_warning) - { - g_warning ("Your hardware does not have enough texture units" - "to handle this many texture layers"); - shown_warning = TRUE; - } - return FALSE; - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - unsigned long state = COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, state); - CoglHandle texture; - GLuint gl_texture; - GLenum gl_target; - - texture = (authority->texture == COGL_INVALID_HANDLE ? - ctx->default_gl_texture_2d_tex : - authority->texture); - - cogl_texture_get_gl_texture (texture, - &gl_texture, - &gl_target); - - _cogl_set_active_texture_unit (unit_index); - - /* NB: There are several Cogl components and some code in - * Clutter that will temporarily bind arbitrary GL textures to - * query and modify texture object parameters. If you look at - * _cogl_bind_gl_texture_transient() you can see we make sure - * that such code always binds to texture unit 1 which means we - * can't rely on the unit->gl_texture state if unit->index == 1. - * - * Because texture unit 1 is a bit special we actually defer any - * necessary glBindTexture for it until the end of - * _cogl_pipeline_flush_gl_state(). - * - * NB: we get notified whenever glDeleteTextures is used (see - * _cogl_delete_gl_texture()) where we invalidate - * unit->gl_texture references to deleted textures so it's safe - * to compare unit->gl_texture with gl_texture. (Without the - * hook it would be possible to delete a GL texture and create a - * new one with the same name and comparing unit->gl_texture and - * gl_texture wouldn't detect that.) - * - * NB: for foreign textures we don't know how the deletion of - * the GL texture objects correspond to the deletion of the - * CoglTextures so if there was previously a foreign texture - * associated with the texture unit then we can't assume that we - * aren't seeing a recycled texture name so we have to bind. - */ - if (unit->gl_texture != gl_texture || unit->is_foreign) - { - if (unit_index == 1) - unit->dirty_gl_texture = TRUE; - else - GE (glBindTexture (gl_target, gl_texture)); - unit->gl_texture = gl_texture; - unit->gl_target = gl_target; - } - - unit->is_foreign = _cogl_texture_is_foreign (texture); - - /* The texture_storage_changed boolean indicates if the - * CoglTexture's underlying GL texture storage has changed since - * it was flushed to the texture unit. We've just flushed the - * latest state so we can reset this. */ - unit->texture_storage_changed = FALSE; - } - - /* Under GLES2 the fragment shader will use gl_PointCoord instead of - replacing the texture coordinates */ -#ifndef HAVE_COGL_GLES2 - if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS) - { - CoglPipelineState change = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, change); - CoglPipelineLayerBigState *big_state = authority->big_state; - - _cogl_set_active_texture_unit (unit_index); - - GE (glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, - big_state->point_sprite_coords)); - } -#endif /* HAVE_COGL_GLES2 */ - - cogl_handle_ref (layer); - if (unit->layer != COGL_INVALID_HANDLE) - cogl_handle_unref (unit->layer); - - unit->layer = layer; - unit->layer_changes_since_flush = 0; - - flush_state->i++; - - return TRUE; -} - -static void -_cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline, - unsigned long pipelines_difference, - unsigned long *layer_differences, - gboolean skip_gl_color) -{ - CoglPipelineFlushLayerState state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_pipeline_flush_color_blend_alpha_depth_state (pipeline, - pipelines_difference, - skip_gl_color); - - state.i = 0; - state.layer_differences = layer_differences; - _cogl_pipeline_foreach_layer_internal (pipeline, - flush_layers_common_gl_state_cb, - &state); -} - -/* Re-assert the layer's wrap modes on the given CoglTexture. - * - * Note: we don't simply forward the wrap modes to layer->texture - * since the actual texture being used may have been overridden. - */ -static void -_cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer, - CoglHandle texture) -{ - CoglPipelineWrapModeInternal wrap_mode_s, wrap_mode_t, wrap_mode_p; - GLenum gl_wrap_mode_s, gl_wrap_mode_t, gl_wrap_mode_p; - - if (texture == COGL_INVALID_HANDLE) - return; - - _cogl_pipeline_layer_get_wrap_modes (layer, - &wrap_mode_s, - &wrap_mode_t, - &wrap_mode_p); - - /* Update the wrap mode on the texture object. The texture backend - should cache the value so that it will be a no-op if the object - already has the same wrap mode set. The backend is best placed to - do this because it knows how many of the coordinates will - actually be used (ie, a 1D texture only cares about the 's' - coordinate but a 3D texture would use all three). GL uses the - wrap mode as part of the texture object state but we are - pretending it's part of the per-layer environment state. This - will break if the application tries to use different modes in - different layers using the same texture. */ - - if (wrap_mode_s == COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC) - gl_wrap_mode_s = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_s = wrap_mode_s; - - if (wrap_mode_t == COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC) - gl_wrap_mode_t = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_t = wrap_mode_t; - - if (wrap_mode_p == COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC) - gl_wrap_mode_p = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_p = wrap_mode_p; - - _cogl_texture_set_wrap_mode_parameters (texture, - gl_wrap_mode_s, - gl_wrap_mode_t, - gl_wrap_mode_p); -} - -/* OpenGL associates the min/mag filters and repeat modes with the - * texture object not the texture unit so we always have to re-assert - * the filter and repeat modes whenever we use a texture since it may - * be referenced by multiple pipelines with different modes. - * - * XXX: GL_ARB_sampler_objects fixes this in OpenGL so we should - * eventually look at using this extension when available. - */ -static void -foreach_texture_unit_update_filter_and_wrap_modes (void) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (i = 0; i < ctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); - - if (unit->layer) - { - CoglHandle texture = _cogl_pipeline_layer_get_texture (unit->layer); - - if (texture != COGL_INVALID_HANDLE) - { - CoglPipelineFilter min; - CoglPipelineFilter mag; - - _cogl_pipeline_layer_get_filters (unit->layer, &min, &mag); - _cogl_texture_set_filters (texture, min, mag); - - _cogl_pipeline_layer_forward_wrap_modes (unit->layer, texture); - } - } - } -} - -typedef struct -{ - int i; - unsigned long *layer_differences; -} CoglPipelineCompareLayersState; - -static gboolean -compare_layer_differences_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineCompareLayersState *state = user_data; - CoglTextureUnit *unit = _cogl_get_texture_unit (state->i); - - if (unit->layer == layer) - state->layer_differences[state->i] = unit->layer_changes_since_flush; - else if (unit->layer) - { - state->layer_differences[state->i] = unit->layer_changes_since_flush; - state->layer_differences[state->i] |= - _cogl_pipeline_layer_compare_differences (layer, unit->layer); - } - else - state->layer_differences[state->i] = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - - /* XXX: There is always a possibility that a CoglTexture's - * underlying GL texture storage has been changed since it was last - * bound to a texture unit which is why we have a callback into - * _cogl_pipeline_texture_storage_change_notify whenever a textures - * underlying GL texture storage changes which will set the - * unit->texture_intern_changed flag. If we see that's been set here - * then we force an update of the texture state... - */ - if (unit->texture_storage_changed) - state->layer_differences[state->i] |= - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; - - state->i++; - - return TRUE; -} - -typedef struct -{ - const CoglPipelineFragend *fragend; - CoglPipeline *pipeline; - unsigned long *layer_differences; - gboolean error_adding_layer; - gboolean added_layer; -} CoglPipelineFragendAddLayerState; - - -static gboolean -fragend_add_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineFragendAddLayerState *state = user_data; - const CoglPipelineFragend *fragend = state->fragend; - CoglPipeline *pipeline = state->pipeline; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* Either generate per layer code snippets or setup the - * fixed function glTexEnv for each layer... */ - if (G_LIKELY (fragend->add_layer (pipeline, - layer, - state->layer_differences[unit_index]))) - state->added_layer = TRUE; - else - { - state->error_adding_layer = TRUE; - return FALSE; - } - - return TRUE; -} - -typedef struct -{ - const CoglPipelineVertend *vertend; - CoglPipeline *pipeline; - unsigned long *layer_differences; - gboolean error_adding_layer; - gboolean added_layer; -} CoglPipelineVertendAddLayerState; - - -static gboolean -vertend_add_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineVertendAddLayerState *state = user_data; - const CoglPipelineVertend *vertend = state->vertend; - CoglPipeline *pipeline = state->pipeline; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* Either enerate per layer code snippets or setup the - * fixed function matrix uniforms for each layer... */ - if (G_LIKELY (vertend->add_layer (pipeline, - layer, - state->layer_differences[unit_index]))) - state->added_layer = TRUE; - else - { - state->error_adding_layer = TRUE; - return FALSE; - } - - return TRUE; -} - -/* - * _cogl_pipeline_flush_gl_state: - * - * Details of override options: - * ->fallback_mask: is a bitmask of the pipeline layers that need to be - * replaced with the default, fallback textures. The fallback textures are - * fully transparent textures so they hopefully wont contribute to the - * texture combining. - * - * The intention of fallbacks is to try and preserve - * the number of layers the user is expecting so that texture coordinates - * they gave will mostly still correspond to the textures they intended, and - * have a fighting chance of looking close to their originally intended - * result. - * - * ->disable_mask: is a bitmask of the pipeline layers that will simply have - * texturing disabled. It's only really intended for disabling all layers - * > X; i.e. we'd expect to see a contiguous run of 0 starting from the LSB - * and at some point the remaining bits flip to 1. It might work to disable - * arbitrary layers; though I'm not sure a.t.m how OpenGL would take to - * that. - * - * The intention of the disable_mask is for emitting geometry when the user - * hasn't supplied enough texture coordinates for all the layers and it's - * not possible to auto generate default texture coordinates for those - * layers. - * - * ->layer0_override_texture: forcibly tells us to bind this GL texture name for - * layer 0 instead of plucking the gl_texture from the CoglTexture of layer - * 0. - * - * The intention of this is for any primitives that supports sliced textures. - * The code will can iterate each of the slices and re-flush the pipeline - * forcing the GL texture of each slice in turn. - * - * ->wrap_mode_overrides: overrides the wrap modes set on each - * layer. This is used to implement the automatic wrap mode. - * - * XXX: It might also help if we could specify a texture matrix for code - * dealing with slicing that would be multiplied with the users own matrix. - * - * Normaly texture coords in the range [0, 1] refer to the extents of the - * texture, but when your GL texture represents a slice of the real texture - * (from the users POV) then a texture matrix would be a neat way of - * transforming the mapping for each slice. - * - * Currently for textured rectangles we manually calculate the texture - * coords for each slice based on the users given coords, but this solution - * isn't ideal, and can't be used with CoglVertexBuffers. - */ -void -_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline, - gboolean skip_gl_color, - int n_tex_coord_attribs) -{ - unsigned long pipelines_difference; - int n_layers; - unsigned long *layer_differences; - int i; - CoglTextureUnit *unit1; - - COGL_STATIC_TIMER (pipeline_flush_timer, - "Mainloop", /* parent */ - "Material Flush", - "The time spent flushing material state", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - COGL_TIMER_START (_cogl_uprof_context, pipeline_flush_timer); - - if (ctx->current_pipeline == pipeline) - { - /* Bail out asap if we've been asked to re-flush the already current - * pipeline and we can see the pipeline hasn't changed */ - if (ctx->current_pipeline_age == pipeline->age && - ctx->current_pipeline_skip_gl_color == skip_gl_color) - goto done; - - pipelines_difference = ctx->current_pipeline_changes_since_flush; - } - else if (ctx->current_pipeline) - { - pipelines_difference = ctx->current_pipeline_changes_since_flush; - pipelines_difference |= - _cogl_pipeline_compare_differences (ctx->current_pipeline, - pipeline); - } - else - pipelines_difference = COGL_PIPELINE_STATE_ALL_SPARSE; - - /* Get a layer_differences mask for each layer to be flushed */ - n_layers = cogl_pipeline_get_n_layers (pipeline); - if (n_layers) - { - CoglPipelineCompareLayersState state; - layer_differences = g_alloca (sizeof (unsigned long *) * n_layers); - memset (layer_differences, 0, sizeof (layer_differences)); - state.i = 0; - state.layer_differences = layer_differences; - _cogl_pipeline_foreach_layer_internal (pipeline, - compare_layer_differences_cb, - &state); - } - else - layer_differences = NULL; - - /* First flush everything that's the same regardless of which - * pipeline backend is being used... - * - * 1) top level state: - * glColor (or skip if a vertex attribute is being used for color) - * blend state - * alpha test state (except for GLES 2.0) - * - * 2) then foreach layer: - * determine gl_target/gl_texture - * bind texture - * - * Note: After _cogl_pipeline_flush_common_gl_state you can expect - * all state of the layers corresponding texture unit to be - * updated. - */ - _cogl_pipeline_flush_common_gl_state (pipeline, - pipelines_difference, - layer_differences, - skip_gl_color); - - /* Now flush the fragment processing state according to the current - * fragment processing backend. - * - * Note: Some of the backends may not support the current pipeline - * configuration and in that case it will report an error and we - * will fallback to a different backend. - * - * NB: if pipeline->backend != COGL_PIPELINE_FRAGEND_UNDEFINED then - * we have previously managed to successfully flush this pipeline - * with the given backend so we will simply use that to avoid - * fallback code paths. - */ - - if (pipeline->fragend == COGL_PIPELINE_FRAGEND_UNDEFINED) - _cogl_pipeline_set_fragend (pipeline, COGL_PIPELINE_FRAGEND_DEFAULT); - - for (i = pipeline->fragend; - i < G_N_ELEMENTS (_cogl_pipeline_fragends); - i++, _cogl_pipeline_set_fragend (pipeline, i)) - { - const CoglPipelineFragend *fragend = _cogl_pipeline_fragends[i]; - CoglPipelineFragendAddLayerState state; - - /* E.g. For fragends generating code they can setup their - * scratch buffers here... */ - if (G_UNLIKELY (!fragend->start (pipeline, - n_layers, - pipelines_difference, - n_tex_coord_attribs))) - continue; - - state.fragend = fragend; - state.pipeline = pipeline; - state.layer_differences = layer_differences; - state.error_adding_layer = FALSE; - state.added_layer = FALSE; - _cogl_pipeline_foreach_layer_internal (pipeline, - fragend_add_layer_cb, - &state); - - if (G_UNLIKELY (state.error_adding_layer)) - continue; - - if (!state.added_layer && - fragend->passthrough && - G_UNLIKELY (!fragend->passthrough (pipeline))) - continue; - - /* For fragends generating code they may compile and link their - * programs here, update any uniforms and tell OpenGL to use - * that program. - */ - if (G_UNLIKELY (!fragend->end (pipeline, pipelines_difference))) - continue; - - break; - } - - if (G_UNLIKELY (i >= G_N_ELEMENTS (_cogl_pipeline_fragends))) - g_warning ("No usable pipeline fragment backend was found!"); - - /* Now flush the vertex processing state according to the current - * vertex processing backend. - */ - - if (pipeline->vertend == COGL_PIPELINE_VERTEND_UNDEFINED) - _cogl_pipeline_set_vertend (pipeline, COGL_PIPELINE_VERTEND_DEFAULT); - - for (i = pipeline->vertend; - i < G_N_ELEMENTS (_cogl_pipeline_vertends); - i++, _cogl_pipeline_set_vertend (pipeline, i)) - { - const CoglPipelineVertend *vertend = _cogl_pipeline_vertends[i]; - CoglPipelineVertendAddLayerState state; - - /* E.g. For vertends generating code they can setup their - * scratch buffers here... */ - if (G_UNLIKELY (!vertend->start (pipeline, - n_layers, - pipelines_difference))) - continue; - - state.vertend = vertend; - state.pipeline = pipeline; - state.layer_differences = layer_differences; - state.error_adding_layer = FALSE; - state.added_layer = FALSE; - _cogl_pipeline_foreach_layer_internal (pipeline, - vertend_add_layer_cb, - &state); - - if (G_UNLIKELY (state.error_adding_layer)) - continue; - - /* For vertends generating code they may compile and link their - * programs here, update any uniforms and tell OpenGL to use - * that program. - */ - if (G_UNLIKELY (!vertend->end (pipeline, pipelines_difference))) - continue; - - break; - } - - if (G_UNLIKELY (i >= G_N_ELEMENTS (_cogl_pipeline_vertends))) - g_warning ("No usable pipeline vertex backend was found!"); - - for (i = 0; i < COGL_PIPELINE_N_PROGENDS; i++) - if (_cogl_pipeline_progends[i]->end) - _cogl_pipeline_progends[i]->end (pipeline, pipelines_difference, - n_tex_coord_attribs); - - /* FIXME: This reference is actually resulting in lots of - * copy-on-write reparenting because one-shot pipelines end up - * living for longer than necessary and so any later modification of - * the parent will cause a copy-on-write. - * - * XXX: The issue should largely go away when we switch to using - * weak pipelines for overrides. - */ - cogl_object_ref (pipeline); - if (ctx->current_pipeline != NULL) - cogl_object_unref (ctx->current_pipeline); - ctx->current_pipeline = pipeline; - ctx->current_pipeline_changes_since_flush = 0; - ctx->current_pipeline_skip_gl_color = skip_gl_color; - ctx->current_pipeline_age = pipeline->age; - -done: - - /* We can't assume the color will be retained between flushes on - GLES2 because the generic attribute values are not stored as part - of the program object so they could be overridden by any - attribute changes in another program */ -#ifdef HAVE_COGL_GLES2 - if (!skip_gl_color) - { - int attribute; - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - - attribute = _cogl_pipeline_progend_glsl_get_color_attribute (pipeline); - if (attribute != -1) - GE (glVertexAttrib4f (attribute, - cogl_color_get_red_float (&authority->color), - cogl_color_get_green_float (&authority->color), - cogl_color_get_blue_float (&authority->color), - cogl_color_get_alpha_float (&authority->color))); - } -#endif - - /* Give any progends a chance to update any uniforms that might not - depend on the material state. This is used on GLES2 to update the - matrices */ - for (i = 0; i < COGL_PIPELINE_N_PROGENDS; i++) - if (_cogl_pipeline_progends[i]->pre_paint) - _cogl_pipeline_progends[i]->pre_paint (pipeline); - - /* Handle the fact that OpenGL associates texture filter and wrap - * modes with the texture objects not the texture units... */ - foreach_texture_unit_update_filter_and_wrap_modes (); - - /* If this pipeline has more than one layer then we always need - * to make sure we rebind the texture for unit 1. - * - * NB: various components of Cogl may temporarily bind arbitrary - * textures to texture unit 1 so they can query and modify texture - * object parameters. cogl-pipeline.c (See - * _cogl_bind_gl_texture_transient) - */ - unit1 = _cogl_get_texture_unit (1); - if (cogl_pipeline_get_n_layers (pipeline) > 1 && unit1->dirty_gl_texture) - { - _cogl_set_active_texture_unit (1); - GE (glBindTexture (unit1->gl_target, unit1->gl_texture)); - unit1->dirty_gl_texture = FALSE; - } - - COGL_TIMER_STOP (_cogl_uprof_context, pipeline_flush_timer); -} - diff --git a/clutter/cogl/cogl/cogl-pipeline-private.h b/clutter/cogl/cogl/cogl-pipeline-private.h deleted file mode 100644 index 47007fb..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-private.h +++ /dev/null @@ -1,1258 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PIPELINE_PRIVATE_H -#define __COGL_PIPELINE_PRIVATE_H - -#include "cogl.h" - -#include "cogl-pipeline.h" -#include "cogl-matrix.h" -#include "cogl-object-private.h" -#include "cogl-profile.h" - -#include - -typedef struct _CoglPipelineLayer CoglPipelineLayer; -#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT) - -#if defined (HAVE_COGL_GL) - -/* NB: pipeline->fragend is currently a 3bit unsigned int bitfield */ -#define COGL_PIPELINE_FRAGEND_ARBFP 0 -#define COGL_PIPELINE_FRAGEND_ARBFP_MASK (1L<<0) -#define COGL_PIPELINE_FRAGEND_FIXED 1 -#define COGL_PIPELINE_FRAGEND_FIXED_MASK (1L<<1) -#define COGL_PIPELINE_FRAGEND_GLSL 2 -#define COGL_PIPELINE_FRAGEND_GLSL_MASK (1L<<2) - -#define COGL_PIPELINE_N_FRAGENDS 3 - -#elif defined (HAVE_COGL_GLES2) - -#define COGL_PIPELINE_FRAGEND_GLSL 0 -#define COGL_PIPELINE_FRAGEND_GLSL_MASK (1L<<0) - -#define COGL_PIPELINE_N_FRAGENDS 1 - -#else /* HAVE_COGL_GLES */ - -#define COGL_PIPELINE_FRAGEND_FIXED 0 -#define COGL_PIPELINE_FRAGEND_FIXED_MASK (1L<<0) - -#define COGL_PIPELINE_N_FRAGENDS 1 - -#endif - -#define COGL_PIPELINE_FRAGEND_DEFAULT 0 -#define COGL_PIPELINE_FRAGEND_UNDEFINED 3 - -#if defined (HAVE_COGL_GL) - -#define COGL_PIPELINE_VERTEND_FIXED 0 -#define COGL_PIPELINE_VERTEND_GLSL 1 - -#define COGL_PIPELINE_N_VERTENDS 2 - -#elif defined (HAVE_COGL_GLES2) - -#define COGL_PIPELINE_VERTEND_GLSL 0 - -#define COGL_PIPELINE_N_VERTENDS 1 - -#else /* HAVE_COGL_GLES */ - -#define COGL_PIPELINE_VERTEND_FIXED 0 - -#define COGL_PIPELINE_N_VERTENDS 1 - -#endif - -#define COGL_PIPELINE_VERTEND_DEFAULT 0 -#define COGL_PIPELINE_VERTEND_UNDEFINED 3 - -/* If we have either of the GLSL backends then we also need a GLSL - progend to combine the shaders generated into a single - program. Currently there is only one progend but if we ever add - other languages they would likely need their own progend too. The - progends are different from the other backends because there can be - more than one in use for each pipeline. All of the progends are - invoked whenever a pipeline is flushed. */ -#ifdef COGL_PIPELINE_FRAGEND_GLSL -#define COGL_PIPELINE_PROGEND_GLSL 0 -#define COGL_PIPELINE_N_PROGENDS 1 -#else -#define COGL_PIPELINE_N_PROGENDS 0 -#endif - -/* XXX: should I rename these as - * COGL_PIPELINE_LAYER_STATE_INDEX_XYZ... ? - */ -typedef enum -{ - /* sparse state */ - COGL_PIPELINE_LAYER_STATE_UNIT_INDEX, - COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX, - COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX, - COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX, - COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX, - COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX, - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX, - - /* note: layers don't currently have any non-sparse state */ - - COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT, - COGL_PIPELINE_LAYER_STATE_COUNT = COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT -} CoglPipelineLayerStateIndex; - -/* XXX: If you add or remove state groups here you may need to update - * some of the state masks following this enum too! - * - * FIXME: perhaps it would be better to rename this enum to - * CoglPipelineLayerStateGroup to better convey the fact that a single - * enum here can map to multiple properties. - */ -typedef enum -{ - COGL_PIPELINE_LAYER_STATE_UNIT = - 1L<first_child and node->children are - * initialized pointers. */ - gboolean has_children; - - /* Materials and layers are sparse structures defined as a diff - * against their parent and may have multiple children which depend - * on them to define the values of properties which they don't - * change. */ - GList *children; -}; - -#define COGL_PIPELINE_NODE(X) ((CoglPipelineNode *)(X)) - -typedef void (*CoglPipelineNodeUnparentVFunc) (CoglPipelineNode *node); - -typedef gboolean (*CoglPipelineNodeChildCallback) (CoglPipelineNode *child, - void *user_data); - -void -_cogl_pipeline_node_foreach_child (CoglPipelineNode *node, - CoglPipelineNodeChildCallback callback, - void *user_data); - -/* This isn't defined in the GLES headers */ -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812d -#endif - -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes. - * - * XXX: keep the values in sync with the CoglPipelineWrapMode enum - * so no conversion is actually needed. - */ -typedef enum _CoglPipelineWrapModeInternal -{ - COGL_PIPELINE_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT, - COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, - COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER, - COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS -} CoglPipelineWrapModeInternal; - -struct _CoglPipelineLayer -{ - /* XXX: Please think twice about adding members that *have* be - * initialized during a _cogl_pipeline_layer_copy. We are aiming - * to have copies be as cheap as possible and copies may be - * done by the primitives APIs which means they may happen - * in performance critical code paths. - * - * XXX: If you are extending the state we track please consider if - * the state is expected to vary frequently across many pipelines or - * if the state can be shared among many derived pipelines instead. - * This will determine if the state should be added directly to this - * structure which will increase the memory overhead for *all* - * layers or if instead it can go under ->big_state. - */ - - /* Layers represent their state in a tree structure where some of - * the state relating to a given pipeline or layer may actually be - * owned by one if is ancestors in the tree. We have a common data - * type to track the tree heirachy so we can share code... */ - CoglPipelineNode _parent; - - /* Some layers have a pipeline owner, which is to say that the layer - * is referenced in that pipelines->layer_differences list. A layer - * doesn't always have an owner and may simply be an ancestor for - * other layers that keeps track of some shared state. */ - CoglPipeline *owner; - - /* The lowest index is blended first then others on top */ - int index; - - /* A mask of which state groups are different in this layer - * in comparison to its parent. */ - unsigned long differences; - - /* Common differences - * - * As a basic way to reduce memory usage we divide the layer - * state into two groups; the minimal state modified in 90% of - * all layers and the rest, so that the second group can - * be allocated dynamically when required. - */ - - /* Each layer is directly associated with a single texture unit */ - int unit_index; - - /* The texture for this layer, or COGL_INVALID_HANDLE for an empty - * layer */ - CoglHandle texture; - GLenum target; - - CoglPipelineFilter mag_filter; - CoglPipelineFilter min_filter; - - CoglPipelineWrapModeInternal wrap_mode_s; - CoglPipelineWrapModeInternal wrap_mode_t; - CoglPipelineWrapModeInternal wrap_mode_p; - - /* Infrequent differences aren't currently tracked in - * a separate, dynamically allocated structure as they are - * for pipelines... */ - CoglPipelineLayerBigState *big_state; - - /* bitfields */ - - /* Determines if layer->big_state is valid */ - unsigned int has_big_state:1; - -}; - -/* XXX: should I rename these as - * COGL_PIPELINE_STATE_INDEX_XYZ... ? - */ -typedef enum -{ - /* sparse state */ - COGL_PIPELINE_STATE_COLOR_INDEX, - COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX, - COGL_PIPELINE_STATE_LAYERS_INDEX, - COGL_PIPELINE_STATE_LIGHTING_INDEX, - COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX, - COGL_PIPELINE_STATE_BLEND_INDEX, - COGL_PIPELINE_STATE_USER_SHADER_INDEX, - COGL_PIPELINE_STATE_DEPTH_INDEX, - COGL_PIPELINE_STATE_FOG_INDEX, - COGL_PIPELINE_STATE_POINT_SIZE_INDEX, - - /* non-sparse */ - COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX, - - COGL_PIPELINE_STATE_COUNT, - COGL_PIPELINE_STATE_SPARSE_COUNT = COGL_PIPELINE_STATE_COUNT - 1, -} CoglPipelineStateIndex; - -/* Used in pipeline->differences masks and for notifying pipeline - * state changes. - * - * XXX: If you add or remove state groups here you may need to update - * some of the state masks following this enum too! - * - * FIXME: perhaps it would be better to rename this enum to - * CoglPipelineStateGroup to better convey the fact that a single enum - * here can map to multiple properties. - */ -typedef enum _CoglPipelineState -{ - COGL_PIPELINE_STATE_COLOR = - 1L<big_state. - */ - - /* Layers represent their state in a tree structure where some of - * the state relating to a given pipeline or layer may actually be - * owned by one if is ancestors in the tree. We have a common data - * type to track the tree heirachy so we can share code... */ - CoglPipelineNode _parent; - - /* We need to track if a pipeline is referenced in the journal - * because we can't allow modification to these pipelines without - * flushing the journal first */ - unsigned long journal_ref_count; - - /* When weak pipelines are destroyed the user is notified via this - * callback */ - CoglPipelineDestroyCallback destroy_callback; - - /* When notifying that a weak pipeline has been destroyed this - * private data is passed to the above callback */ - void *destroy_data; - - /* A mask of which sparse state groups are different in this - * pipeline in comparison to its parent. */ - unsigned long differences; - - /* The fragment processing backends can associate private data with a - * pipeline. */ - void *fragend_privs[COGL_PIPELINE_N_FRAGENDS]; - - /* Whenever a pipeline is modified we increment the age. There's no - * guarantee that it won't wrap but it can nevertheless be a - * convenient mechanism to determine when a pipeline has been - * changed to you can invalidate some some associated cache that - * depends on the old state. */ - unsigned long age; - - /* This is the primary color of the pipeline. - * - * This is a sparse property, ref COGL_PIPELINE_STATE_COLOR */ - CoglColor color; - - /* A pipeline may be made up with multiple layers used to combine - * textures together. - * - * This is sparse state, ref COGL_PIPELINE_STATE_LAYERS */ - GList *layer_differences; - unsigned int n_layers; - - /* As a basic way to reduce memory usage we divide the pipeline - * state into two groups; the minimal state modified in 90% of - * all pipelines and the rest, so that the second group can - * be allocated dynamically when required... */ - CoglPipelineBigState *big_state; - - /* For debugging purposes it's possible to associate a static const - * string with a pipeline which can be an aid when trying to trace - * where the pipeline originates from */ - const char *static_breadcrumb; - - /* Cached state... */ - - /* A cached, complete list of the layers this pipeline depends - * on sorted by layer->unit_index. */ - CoglPipelineLayer **layers_cache; - /* To avoid a separate ->layers_cache allocation for common - * pipelines with only a few layers... */ - CoglPipelineLayer *short_layers_cache[3]; - - /* The deprecated cogl_pipeline_get_layers() API returns a - * const GList of layers, which we track here... */ - GList *deprecated_get_layers_list; - - /* XXX: consider adding an authorities cache to speed up sparse - * property value lookups: - * CoglPipeline *authorities_cache[COGL_PIPELINE_N_SPARSE_PROPERTIES]; - * and corresponding authorities_cache_dirty:1 bitfield - */ - - /* bitfields */ - - /* A pipeline can have private data associated with it for multiple - * fragment processing backends. Although only one backend is - * associated with a pipeline the backends may want to cache private - * state with the ancestors of other pipelines and those ancestors - * could currently be associated with different backends. - * - * Each set bit indicates if the corresponding ->fragend_privs[] - * entry is valid. - */ - unsigned int fragend_priv_set_mask:COGL_PIPELINE_N_FRAGENDS; - - /* Weak pipelines don't count as dependants on their parents which - * means that the parent pipeline can be modified without - * considering how the modifications may affect the weak pipeline. - */ - unsigned int is_weak:1; - - /* Determines if pipeline->big_state is valid */ - unsigned int has_big_state:1; - - /* By default blending is enabled automatically depending on the - * unlit color, the lighting colors or the texture format. The user - * can override this to explicitly enable or disable blending. - * - * This is a sparse property */ - unsigned int blend_enable:3; - - /* There are many factors that can determine if we need to enable - * blending, this holds our final decision */ - unsigned int real_blend_enable:1; - - unsigned int layers_cache_dirty:1; - unsigned int deprecated_get_layers_list_dirty:1; - - /* For debugging purposes it's possible to associate a static const - * string with a pipeline which can be an aid when trying to trace - * where the pipeline originates from */ - unsigned int has_static_breadcrumb:1; - - /* There are multiple fragment processing backends for CoglPipeline, - * glsl, arbfp and fixed. This identifies the backend being used for - * the pipeline and any private state the backend has associated - * with the pipeline. */ - unsigned int fragend:3; - unsigned int vertend:3; -}; - -typedef struct _CoglPipelineFragend -{ - gboolean (*start) (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference, - int n_tex_coord_attribs); - gboolean (*add_layer) (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference); - gboolean (*passthrough) (CoglPipeline *pipeline); - gboolean (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*pipeline_set_parent_notify) (CoglPipeline *pipeline); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); - - void (*free_priv) (CoglPipeline *pipeline); -} CoglPipelineFragend; - -typedef struct _CoglPipelineVertend -{ - gboolean (*start) (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference); - gboolean (*add_layer) (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference); - gboolean (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); -} CoglPipelineVertend; - -typedef struct -{ - void (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference, - int n_tex_coord_attribs); - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); - /* This is called after all of the other functions whenever the - pipeline is flushed, even if the pipeline hasn't changed since - the last flush */ - void (* pre_paint) (CoglPipeline *pipeline); -} CoglPipelineProgend; - -typedef enum -{ - COGL_PIPELINE_PROGRAM_TYPE_GLSL = 1, - COGL_PIPELINE_PROGRAM_TYPE_ARBFP, - COGL_PIPELINE_PROGRAM_TYPE_FIXED -} CoglPipelineProgramType; - -extern const CoglPipelineFragend * -_cogl_pipeline_fragends[COGL_PIPELINE_N_FRAGENDS]; -extern const CoglPipelineVertend * -_cogl_pipeline_vertends[COGL_PIPELINE_N_VERTENDS]; -extern const CoglPipelineProgend * -_cogl_pipeline_progends[]; - -void -_cogl_pipeline_init_default_pipeline (void); - -void -_cogl_pipeline_init_default_layers (void); - -static inline CoglPipeline * -_cogl_pipeline_get_parent (CoglPipeline *pipeline) -{ - CoglPipelineNode *parent_node = COGL_PIPELINE_NODE (pipeline)->parent; - return COGL_PIPELINE (parent_node); -} - -static inline CoglPipeline * -_cogl_pipeline_get_authority (CoglPipeline *pipeline, - unsigned long difference) -{ - CoglPipeline *authority = pipeline; - while (!(authority->differences & difference)) - authority = _cogl_pipeline_get_parent (authority); - return authority; -} - -/* - * SECTION:cogl-pipeline-internals - * @short_description: Functions for creating custom primitives that make use - * of Cogl pipelines for filling. - * - * Normally you shouldn't need to use this API directly, but if you need to - * developing a custom/specialised primitive - probably using raw OpenGL - then - * this API aims to expose enough of the pipeline internals to support being - * able to fill your geometry according to a given Cogl pipeline. - */ - -gboolean -_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline, - int layer_index); - -/* - * Calls the pre_paint method on the layer texture if there is - * one. This will determine whether mipmaps are needed based on the - * filter settings. - */ -void -_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layerr); - -/* - * Calls the pre_paint method on the layer texture if there is - * one. This will determine whether mipmaps are needed based on the - * filter settings. - */ -void -_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline, - int layer_id); - -/* - * CoglPipelineFlushFlag: - * @COGL_PIPELINE_FLUSH_FALLBACK_MASK: The fallback_layers member is set to - * a guint32 mask of the layers that can't be supported with the user - * supplied texture and need to be replaced with fallback textures. (1 = - * fallback, and the least significant bit = layer 0) - * @COGL_PIPELINE_FLUSH_DISABLE_MASK: The disable_layers member is set to - * a guint32 mask of the layers that you want to completly disable - * texturing for (1 = fallback, and the least significant bit = layer 0) - * @COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE: The layer0_override_texture member is - * set to a GLuint OpenGL texture name to override the texture used for - * layer 0 of the pipeline. This is intended for dealing with sliced - * textures where you will need to point to each of the texture slices in - * turn when drawing your geometry. Passing a value of 0 is the same as - * not passing the option at all. - * @COGL_PIPELINE_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the - * pipeline don't call glColor. - */ -typedef enum _CoglPipelineFlushFlag -{ - COGL_PIPELINE_FLUSH_FALLBACK_MASK = 1L<<0, - COGL_PIPELINE_FLUSH_DISABLE_MASK = 1L<<1, - COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE = 1L<<2, - COGL_PIPELINE_FLUSH_SKIP_GL_COLOR = 1L<<3 -} CoglPipelineFlushFlag; - -/* - * CoglPipelineFlushOptions: - * - */ -typedef struct _CoglPipelineFlushOptions -{ - CoglPipelineFlushFlag flags; - - guint32 fallback_layers; - guint32 disable_layers; - CoglHandle layer0_override_texture; -} CoglPipelineFlushOptions; - - -int -_cogl_get_max_texture_image_units (void); - - -void -_cogl_use_fragment_program (GLuint gl_program, CoglPipelineProgramType type); - -void -_cogl_use_vertex_program (GLuint gl_program, CoglPipelineProgramType type); - -unsigned int -_cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func); - -/* - * _cogl_pipeline_weak_copy: - * @pipeline: A #CoglPipeline object - * @callback: A callback to notify when your weak pipeline is destroyed - * @user_data: Private data to pass to your given callback. - * - * Returns a weak copy of the given source @pipeline. Unlike a normal - * copy no internal reference is taken on the source @pipeline and you - * can expect that later modifications of the source pipeline (or in - * fact any other pipeline) can result in the weak pipeline being - * destroyed. - * - * To understand this better its good to know a bit about the internal - * design of #CoglPipeline... - * - * Internally #CoglPipelines are represented as a graph of - * property diff's, where each node is a diff of properties that gets - * applied on top of its parent. Copying a pipeline creates an empty - * diff and a child->parent relationship between the empty diff and - * the source @pipeline, parent. - * - * Because of this internal graph design a single #CoglPipeline may - * indirectly depend on a chain of ancestors to fully define all of - * its properties. Because a node depends on its ancestors it normally - * owns a reference to its parent to stop it from being freed. Also if - * you try to modify a pipeline with children we internally use a - * copy-on-write mechanism to ensure that you don't indirectly change - * the properties those children. - * - * Weak pipelines avoid the use of copy-on-write to preserve the - * integrity of weak dependants and instead weak dependants are - * simply destroyed allowing the parent to be modified directly. Also - * because weak pipelines don't own a reference to their parent they - * won't stop the source @pipeline from being freed when the user - * releases their reference on it. - * - * Because weak pipelines don't own a reference on their parent they - * are the recommended mechanism for creating derived pipelines that you - * want to cache as a private property of the original pipeline - * because they won't result in a circular dependency. - * - * An example use case: - * - * Consider for example you are implementing a custom primitive that is - * not compatible with certain source pipelines. To handle this you - * implement a validation stage that given an arbitrary pipeline as - * input will create a derived pipeline that is suitable for drawing - * your primitive. - * - * Because you don't want to have to repeat this validation every time - * the same incompatible pipeline is given as input you want to cache - * the result as a private property of the original pipeline. If the - * derived pipeline were created using cogl_pipeline_copy that would - * create a circular dependency so the original pipeline can never be - * freed. - * - * If you instead create a weak copy you won't stop the original pipeline - * from being freed if it's no longer needed, and you will instead simply - * be notified that your weak pipeline has been destroyed. - * - * This is the recommended coding pattern for validating an input - * pipeline and caching a derived result: - * |[ - * static CoglUserDataKey _cogl_my_cache_key; - * - * typedef struct { - * CoglPipeline *validated_source; - * } MyValidatedMaterialCache; - * - * static void - * destroy_cache_cb (CoglObject *object, void *user_data) - * { - * g_slice_free (MyValidatedMaterialCache, user_data); - * } - * - * static void - * invalidate_cache_cb (CoglPipeline *destroyed, void *user_data) - * { - * MyValidatedMaterialCache *cache = user_data; - * cogl_object_unref (cache->validated_source); - * cache->validated_source = NULL; - * } - * - * static CoglPipeline * - * get_validated_pipeline (CoglPipeline *source) - * { - * MyValidatedMaterialCache *cache = - * cogl_object_get_user_data (COGL_OBJECT (source), - * &_cogl_my_cache_key); - * if (G_UNLIKELY (cache == NULL)) - * { - * cache = g_slice_new (MyValidatedMaterialCache); - * cogl_object_set_user_data (COGL_OBJECT (source), - * &_cogl_my_cache_key, - * cache, destroy_cache_cb); - * cache->validated_source = source; - * } - * - * if (G_UNLIKELY (cache->validated_source == NULL)) - * { - * cache->validated_source = source; - * - * / * Start validating source... * / - * - * / * If you find you need to change something... * / - * if (cache->validated_source == source) - * cache->validated_source = - * cogl_pipeline_weak_copy (source, - * invalidate_cache_cb, - * cache); - * - * / * Modify cache->validated_source * / - * } - * - * return cache->validated_source; - * } - * ]| - */ -CoglPipeline * -_cogl_pipeline_weak_copy (CoglPipeline *pipeline, - CoglPipelineDestroyCallback callback, - void *user_data); - -void -_cogl_pipeline_set_fragend (CoglPipeline *pipeline, int fragend); - -void -_cogl_pipeline_set_vertend (CoglPipeline *pipeline, int vertend); - -CoglPipeline * -_cogl_pipeline_get_parent (CoglPipeline *pipeline); - -void -_cogl_pipeline_get_colorubv (CoglPipeline *pipeline, - guint8 *color); - -/* XXX: At some point it could be good for this to accept a mask of - * the state groups we are interested in comparing since we can - * probably use that information in a number situations to reduce - * the work we do. */ -unsigned long -_cogl_pipeline_compare_differences (CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -/* Sometimes when evaluating pipelines, either during comparisons or - * if calculating a hash value we need to tweak the evaluation - * semantics */ -typedef enum _CoglPipelineEvalFlags -{ - COGL_PIPELINE_EVAL_FLAG_NONE = 0 -} CoglPipelineEvalFlags; - -gboolean -_cogl_pipeline_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1, - unsigned long differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags); - -unsigned int -_cogl_pipeline_hash (CoglPipeline *pipeline, - unsigned long differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags); - -CoglPipeline * -_cogl_pipeline_journal_ref (CoglPipeline *pipeline); - -void -_cogl_pipeline_journal_unref (CoglPipeline *pipeline); - -CoglPipelineFilter -_cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline, - int layer_index); - -CoglPipelineFilter -_cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, - int layer_index); - -const CoglMatrix * -_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline, - int layer_index); - -void -_cogl_pipeline_texture_storage_change_notify (CoglHandle texture); - -void -_cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline); - -void -_cogl_pipeline_apply_overrides (CoglPipeline *pipeline, - CoglPipelineFlushOptions *options); - -CoglPipelineBlendEnable -_cogl_pipeline_get_blend_enabled (CoglPipeline *pipeline); - -void -_cogl_pipeline_set_blend_enabled (CoglPipeline *pipeline, - CoglPipelineBlendEnable enable); - -void -_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, - const char *breadcrumb); - -unsigned long -_cogl_pipeline_get_age (CoglPipeline *pipeline); - -CoglPipeline * -_cogl_pipeline_get_authority (CoglPipeline *pipeline, - unsigned long difference); - -CoglPipeline * -_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline, - CoglPipelineState pipeline_state, - CoglPipelineLayerState layer_state); - -CoglHandle -_cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, - int layer_index); - -void -_cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - float *constant); - -void -_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n); - - -/* - * API to support the deprecate cogl_pipeline_layer_xyz functions... - */ - -G_CONST_RETURN GList * -_cogl_pipeline_get_layers (CoglPipeline *pipeline); - -void -_cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, - CoglPipelineWrapModeInternal *wrap_mode_s, - CoglPipelineWrapModeInternal *wrap_mode_t, - CoglPipelineWrapModeInternal *wrap_mode_r); - -void -_cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter); - -void -_cogl_pipeline_get_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter); - -typedef enum { - COGL_PIPELINE_LAYER_TYPE_TEXTURE -} CoglPipelineLayerType; - -CoglPipelineLayerType -_cogl_pipeline_layer_get_type (CoglPipelineLayer *layer); - -CoglHandle -_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer); - -CoglHandle -_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer); - -CoglPipelineFilter -_cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer); - -CoglPipelineFilter -_cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer); - -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer); - -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer); - -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_p (CoglPipelineLayer *layer); - -unsigned long -_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1); - -CoglPipelineLayer * -_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer, - unsigned long difference); - -CoglHandle -_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer); - -typedef gboolean (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer, - void *user_data); - -void -_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, - CoglPipelineInternalLayerCallback callback, - void *user_data); - -int -_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_need_texture_combine_separate - (CoglPipelineLayer *combine_authority); - -void -_cogl_pipeline_init_state_hash_functions (void); - -void -_cogl_pipeline_init_layer_state_hash_functions (void); - -#endif /* __COGL_PIPELINE_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-progend-glsl-private.h b/clutter/cogl/cogl/cogl-pipeline-progend-glsl-private.h deleted file mode 100644 index c100269..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-progend-glsl-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H -#define __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H - -#include "cogl-pipeline-private.h" -#include "cogl-attribute-private.h" - -extern const CoglPipelineProgend _cogl_pipeline_glsl_progend; - -#ifdef HAVE_COGL_GLES2 - -int -_cogl_pipeline_progend_glsl_get_position_attribute (CoglPipeline *pipeline); - -int -_cogl_pipeline_progend_glsl_get_color_attribute (CoglPipeline *pipeline); - -int -_cogl_pipeline_progend_glsl_get_normal_attribute (CoglPipeline *pipeline); - -int -_cogl_pipeline_progend_glsl_get_tex_coord_attribute (CoglPipeline *pipeline, - int unit); - -#endif /* HAVE_COGL_GLES2 */ - -#endif /* __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-progend-glsl.c b/clutter/cogl/cogl/cogl-pipeline-progend-glsl.c deleted file mode 100644 index cc0f3dc..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-progend-glsl.c +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" - -#ifdef COGL_PIPELINE_PROGEND_GLSL - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-program-private.h" -#include "cogl-pipeline-fragend-glsl-private.h" -#include "cogl-pipeline-vertend-glsl-private.h" - -#ifndef HAVE_COGL_GLES2 - -#define glCreateProgram ctx->drv.pf_glCreateProgram -#define glAttachShader ctx->drv.pf_glAttachShader -#define glUseProgram ctx->drv.pf_glUseProgram -#define glLinkProgram ctx->drv.pf_glLinkProgram -#define glDeleteProgram ctx->drv.pf_glDeleteProgram -#define glGetProgramInfoLog ctx->drv.pf_glGetProgramInfoLog -#define glGetProgramiv ctx->drv.pf_glGetProgramiv -#define glGetUniformLocation ctx->drv.pf_glGetUniformLocation -#define glUniform1i ctx->drv.pf_glUniform1i -#define glUniform1f ctx->drv.pf_glUniform1f -#define glUniform4fv ctx->drv.pf_glUniform4fv - -#else - -/* These are used to generalise updating some uniforms that are - required when building for GLES2 */ - -typedef void (* UpdateUniformFunc) (CoglPipeline *pipeline, - int uniform_location, - void *getter_func); - -static void update_float_uniform (CoglPipeline *pipeline, - int uniform_location, - void *getter_func); - -typedef struct -{ - const char *uniform_name; - void *getter_func; - UpdateUniformFunc update_func; - CoglPipelineState change; -} BuiltinUniformData; - -static BuiltinUniformData builtin_uniforms[] = - { - { "cogl_point_size_in", - cogl_pipeline_get_point_size, update_float_uniform, - COGL_PIPELINE_STATE_POINT_SIZE }, - { "_cogl_alpha_test_ref", - cogl_pipeline_get_alpha_test_reference, update_float_uniform, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE } - }; - -#endif /* HAVE_COGL_GLES2 */ - -const CoglPipelineProgend _cogl_pipeline_glsl_progend; - -typedef struct _UnitState -{ - unsigned int dirty_combine_constant:1; - unsigned int dirty_texture_matrix:1; - - GLint combine_constant_uniform; - - GLint texture_matrix_uniform; -} UnitState; - -typedef struct -{ - unsigned int ref_count; - - /* Age that the user program had last time we generated a GL - program. If it's different then we need to relink the program */ - unsigned int user_program_age; - - GLuint program; - - /* To allow writing shaders that are portable between GLES 2 and - * OpenGL Cogl prepends a number of boilerplate #defines and - * declarations to user shaders. One of those declarations is an - * array of texture coordinate varyings, but to know how to emit the - * declaration we need to know how many texture coordinate - * attributes are in use. The boilerplate also needs to be changed - * if this increases. */ - int n_tex_coord_attribs; - -#ifdef HAVE_COGL_GLES2 - unsigned long dirty_builtin_uniforms; - GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)]; - - /* Under GLES2 we can't use the builtin functions to set attribute - pointers such as the vertex position. Instead the vertex - attribute code needs to query the attribute numbers from the - progend backend */ - int position_attribute_location; - int color_attribute_location; - int normal_attribute_location; - int tex_coord0_attribute_location; - /* We only allocate this array if more than one tex coord attribute - is requested because most pipelines will only use one layer */ - GArray *tex_coord_attribute_locations; - - GLint modelview_uniform; - GLint projection_uniform; - GLint mvp_uniform; - - CoglMatrixStack *flushed_modelview_stack; - unsigned int flushed_modelview_stack_age; - gboolean flushed_modelview_is_identity; - CoglMatrixStack *flushed_projection_stack; - unsigned int flushed_projection_stack_age; -#endif - - /* We need to track the last pipeline that the program was used with - * so know if we need to update all of the uniforms */ - CoglPipeline *last_used_for_pipeline; - - UnitState *unit_state; -} CoglPipelineProgendPrivate; - -static CoglUserDataKey glsl_priv_key; - -static CoglPipelineProgendPrivate * -get_glsl_priv (CoglPipeline *pipeline) -{ - return cogl_object_get_user_data (COGL_OBJECT (pipeline), &glsl_priv_key); -} - -#ifdef HAVE_COGL_GLES2 - -#define ATTRIBUTE_LOCATION_UNKNOWN -2 - -/* Under GLES2 the vertex attribute API needs to query the attribute - numbers because it can't used the fixed function API to set the - builtin attributes. We cache the attributes here because the - progend knows when the program is changed so it can clear the - cache. This should always be called after the pipeline is flushed - so they can assert that the gl program is valid */ - -int -_cogl_pipeline_progend_glsl_get_position_attribute (CoglPipeline *pipeline) -{ - CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline); - - g_return_val_if_fail (priv != NULL, -1); - g_return_val_if_fail (priv->program != 0, -1); - - if (priv->position_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN) - GE_RET( priv->position_attribute_location, - glGetAttribLocation (priv->program, "cogl_position_in") ); - - return priv->position_attribute_location; -} - -int -_cogl_pipeline_progend_glsl_get_color_attribute (CoglPipeline *pipeline) -{ - CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline); - - g_return_val_if_fail (priv != NULL, -1); - g_return_val_if_fail (priv->program != 0, -1); - - if (priv->color_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN) - GE_RET( priv->color_attribute_location, - glGetAttribLocation (priv->program, "cogl_color_in") ); - - return priv->color_attribute_location; -} - -int -_cogl_pipeline_progend_glsl_get_normal_attribute (CoglPipeline *pipeline) -{ - CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline); - - g_return_val_if_fail (priv != NULL, -1); - g_return_val_if_fail (priv->program != 0, -1); - - if (priv->normal_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN) - GE_RET( priv->normal_attribute_location, - glGetAttribLocation (priv->program, "cogl_normal_in") ); - - return priv->normal_attribute_location; -} - -int -_cogl_pipeline_progend_glsl_get_tex_coord_attribute (CoglPipeline *pipeline, - int unit) -{ - CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline); - - g_return_val_if_fail (priv != NULL, -1); - g_return_val_if_fail (priv->program != 0, -1); - - if (unit == 0) - { - if (priv->tex_coord0_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN) - GE_RET( priv->tex_coord0_attribute_location, - glGetAttribLocation (priv->program, "cogl_tex_coord0_in") ); - - return priv->tex_coord0_attribute_location; - } - else - { - char *name = g_strdup_printf ("cogl_tex_coord%i_in", unit); - int *locations; - - if (priv->tex_coord_attribute_locations == NULL) - priv->tex_coord_attribute_locations = g_array_new (FALSE, FALSE, - sizeof (int)); - if (priv->tex_coord_attribute_locations->len <= unit - 1) - { - int i = priv->tex_coord_attribute_locations->len; - g_array_set_size (priv->tex_coord_attribute_locations, unit); - for (; i < unit; i++) - g_array_index (priv->tex_coord_attribute_locations, int, i) = - ATTRIBUTE_LOCATION_UNKNOWN; - } - - locations = &g_array_index (priv->tex_coord_attribute_locations, int, 0); - - if (locations[unit - 1] == ATTRIBUTE_LOCATION_UNKNOWN) - GE_RET( locations[unit - 1], - glGetAttribLocation (priv->program, name) ); - - g_free (name); - - return locations[unit - 1]; - } -} - -static void -clear_attribute_cache (CoglPipelineProgendPrivate *priv) -{ - priv->position_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN; - priv->color_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN; - priv->normal_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN; - priv->tex_coord0_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN; - if (priv->tex_coord_attribute_locations) - { - g_array_free (priv->tex_coord_attribute_locations, TRUE); - priv->tex_coord_attribute_locations = NULL; - } -} - -static void -clear_flushed_matrix_stacks (CoglPipelineProgendPrivate *priv) -{ - if (priv->flushed_modelview_stack) - { - cogl_object_unref (priv->flushed_modelview_stack); - priv->flushed_modelview_stack = NULL; - } - if (priv->flushed_projection_stack) - { - cogl_object_unref (priv->flushed_projection_stack); - priv->flushed_projection_stack = NULL; - } - priv->flushed_modelview_is_identity = FALSE; -} - -#endif /* HAVE_COGL_GLES2 */ - -static void -destroy_glsl_priv (void *user_data) -{ - CoglPipelineProgendPrivate *priv = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (--priv->ref_count == 0) - { -#ifdef HAVE_COGL_GLES2 - clear_attribute_cache (priv); - clear_flushed_matrix_stacks (priv); -#endif - - if (priv->program) - GE( glDeleteProgram (priv->program) ); - - g_free (priv->unit_state); - - g_slice_free (CoglPipelineProgendPrivate, priv); - } -} - -static void -set_glsl_priv (CoglPipeline *pipeline, CoglPipelineProgendPrivate *priv) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &glsl_priv_key, - priv, - destroy_glsl_priv); -} - -static void -dirty_glsl_program_state (CoglPipeline *pipeline) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &glsl_priv_key, - NULL, - destroy_glsl_priv); -} - -static void -link_program (GLint gl_program) -{ - GLint link_status; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - GE( glLinkProgram (gl_program) ); - - GE( glGetProgramiv (gl_program, GL_LINK_STATUS, &link_status) ); - - if (!link_status) - { - GLint log_length; - GLsizei out_log_length; - char *log; - - GE( glGetProgramiv (gl_program, GL_INFO_LOG_LENGTH, &log_length) ); - - log = g_malloc (log_length); - - GE( glGetProgramInfoLog (gl_program, log_length, - &out_log_length, log) ); - - g_warning ("Failed to link GLSL program:\n%.*s\n", - log_length, log); - - g_free (log); - } -} - -typedef struct -{ - int unit; - GLuint gl_program; - gboolean update_all; - CoglPipelineProgendPrivate *priv; -} UpdateUniformsState; - -static gboolean -get_uniform_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateUniformsState *state = user_data; - CoglPipelineProgendPrivate *priv = state->priv; - UnitState *unit_state = &priv->unit_state[state->unit]; - GLint uniform_location; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* We can reuse the source buffer to create the uniform name because - the program has now been linked */ - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "_cogl_sampler_%i", state->unit); - - GE_RET( uniform_location, - glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - /* We can set the uniform immediately because the samplers are the - unit index not the texture object number so it will never - change. Unfortunately GL won't let us use a constant instead of a - uniform */ - if (uniform_location != -1) - GE( glUniform1i (uniform_location, state->unit) ); - - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "_cogl_layer_constant_%i", state->unit); - - GE_RET( uniform_location, - glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - unit_state->combine_constant_uniform = uniform_location; - -#ifdef HAVE_COGL_GLES2 - - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "cogl_texture_matrix[%i]", state->unit); - - GE_RET( uniform_location, - glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - unit_state->texture_matrix_uniform = uniform_location; - -#endif - - state->unit++; - - return TRUE; -} - -static gboolean -update_constants_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateUniformsState *state = user_data; - CoglPipelineProgendPrivate *priv = state->priv; - UnitState *unit_state = &priv->unit_state[state->unit++]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (unit_state->combine_constant_uniform != -1 && - (state->update_all || unit_state->dirty_combine_constant)) - { - float constant[4]; - _cogl_pipeline_get_layer_combine_constant (pipeline, - layer_index, - constant); - GE (glUniform4fv (unit_state->combine_constant_uniform, - 1, constant)); - unit_state->dirty_combine_constant = FALSE; - } - -#ifdef HAVE_COGL_GLES2 - - if (unit_state->texture_matrix_uniform != -1 && - (state->update_all || unit_state->dirty_texture_matrix)) - { - const CoglMatrix *matrix; - const float *array; - - matrix = _cogl_pipeline_get_layer_matrix (pipeline, layer_index); - array = cogl_matrix_get_array (matrix); - GE (glUniformMatrix4fv (unit_state->texture_matrix_uniform, - 1, FALSE, array)); - unit_state->dirty_texture_matrix = FALSE; - } - -#endif /* HAVE_COGL_GLES2 */ - - return TRUE; -} - -#ifdef HAVE_COGL_GLES2 - -static void -update_builtin_uniforms (CoglPipeline *pipeline, - GLuint gl_program, - CoglPipelineProgendPrivate *priv) -{ - int i; - - if (priv->dirty_builtin_uniforms == 0) - return; - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if ((priv->dirty_builtin_uniforms & (1 << i)) && - priv->builtin_uniform_locations[i] != -1) - builtin_uniforms[i].update_func (pipeline, - priv->builtin_uniform_locations[i], - builtin_uniforms[i].getter_func); - - priv->dirty_builtin_uniforms = 0; -} - -#endif /* HAVE_COGL_GLES2 */ - -static void -_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference, - int n_tex_coord_attribs) -{ - CoglPipelineProgendPrivate *priv; - GLuint gl_program; - gboolean program_changed = FALSE; - UpdateUniformsState state; - CoglProgram *user_program; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If neither of the glsl fragend or vertends are used then we don't - need to do anything */ - if (pipeline->fragend != COGL_PIPELINE_FRAGEND_GLSL && - pipeline->vertend != COGL_PIPELINE_VERTEND_GLSL) - return; - - priv = get_glsl_priv (pipeline); - - user_program = cogl_pipeline_get_user_program (pipeline); - - if (priv == NULL) - { - CoglPipeline *authority; - - /* Get the authority for anything affecting program state. This - should include both fragment codegen state and vertex codegen - state */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - (COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN | - COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN) & - ~COGL_PIPELINE_STATE_LAYERS, - COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN | - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN); - - priv = get_glsl_priv (authority); - - if (priv == NULL) - { - priv = g_slice_new (CoglPipelineProgendPrivate); - priv->ref_count = 1; - priv->program = 0; - priv->n_tex_coord_attribs = 0; - priv->unit_state = g_new (UnitState, - cogl_pipeline_get_n_layers (pipeline)); -#ifdef HAVE_COGL_GLES2 - priv->tex_coord_attribute_locations = NULL; - priv->flushed_modelview_stack = NULL; - priv->flushed_modelview_is_identity = FALSE; - priv->flushed_projection_stack = NULL; -#endif - set_glsl_priv (authority, priv); - } - - if (authority != pipeline) - { - priv->ref_count++; - set_glsl_priv (pipeline, priv); - } - } - - /* If the program has changed since the last link then we do - * need to relink - * - * Also if the number of texture coordinate attributes in use has - * increased, then delete the program so we can prepend a new - * _cogl_tex_coord[] varying array declaration. */ - if (priv->program && user_program && - (user_program->age != priv->user_program_age || - n_tex_coord_attribs > priv->n_tex_coord_attribs)) - { - GE( glDeleteProgram (priv->program) ); - priv->program = 0; - } - - if (priv->program == 0) - { - GLuint backend_shader; - GSList *l; - - GE_RET( priv->program, glCreateProgram () ); - - /* Attach all of the shader from the user program */ - if (user_program) - { - if (priv->n_tex_coord_attribs > n_tex_coord_attribs) - n_tex_coord_attribs = priv->n_tex_coord_attribs; - -#ifdef HAVE_COGL_GLES2 - /* Find the largest count of texture coordinate attributes - * associated with each of the shaders so we can ensure a consistent - * _cogl_tex_coord[] array declaration across all of the shaders.*/ - if (user_program) - for (l = user_program->attached_shaders; l; l = l->next) - { - CoglShader *shader = l->data; - n_tex_coord_attribs = MAX (shader->n_tex_coord_attribs, - n_tex_coord_attribs); - } -#endif - - for (l = user_program->attached_shaders; l; l = l->next) - { - CoglShader *shader = l->data; - - _cogl_shader_compile_real (shader, n_tex_coord_attribs); - - g_assert (shader->language == COGL_SHADER_LANGUAGE_GLSL); - - GE( glAttachShader (priv->program, - shader->gl_handle) ); - } - - priv->user_program_age = user_program->age; - } - - /* Attach any shaders from the GLSL backends */ - if (pipeline->fragend == COGL_PIPELINE_FRAGEND_GLSL && - (backend_shader = _cogl_pipeline_fragend_glsl_get_shader (pipeline))) - GE( glAttachShader (priv->program, backend_shader) ); - if (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL && - (backend_shader = _cogl_pipeline_vertend_glsl_get_shader (pipeline))) - GE( glAttachShader (priv->program, backend_shader) ); - - link_program (priv->program); - - program_changed = TRUE; - - priv->n_tex_coord_attribs = n_tex_coord_attribs; - } - - gl_program = priv->program; - - if (pipeline->fragend == COGL_PIPELINE_FRAGEND_GLSL) - _cogl_use_fragment_program (gl_program, COGL_PIPELINE_PROGRAM_TYPE_GLSL); - if (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL) - _cogl_use_vertex_program (gl_program, COGL_PIPELINE_PROGRAM_TYPE_GLSL); - - state.unit = 0; - state.gl_program = gl_program; - state.priv = priv; - - if (program_changed) - cogl_pipeline_foreach_layer (pipeline, - get_uniform_cb, - &state); - - state.unit = 0; - state.update_all = (program_changed || - priv->last_used_for_pipeline != pipeline); - - cogl_pipeline_foreach_layer (pipeline, - update_constants_cb, - &state); - -#ifdef HAVE_COGL_GLES2 - if (program_changed) - { - int i; - - clear_attribute_cache (priv); - clear_flushed_matrix_stacks (priv); - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - GE_RET( priv->builtin_uniform_locations[i], - glGetUniformLocation (gl_program, - builtin_uniforms[i].uniform_name) ); - - GE_RET( priv->modelview_uniform, - glGetUniformLocation (gl_program, - "cogl_modelview_matrix") ); - - GE_RET( priv->projection_uniform, - glGetUniformLocation (gl_program, - "cogl_projection_matrix") ); - - GE_RET( priv->mvp_uniform, - glGetUniformLocation (gl_program, - "cogl_modelview_projection_matrix") ); - } - if (program_changed || - priv->last_used_for_pipeline != pipeline) - priv->dirty_builtin_uniforms = ~(unsigned long) 0; - - update_builtin_uniforms (pipeline, gl_program, priv); -#endif - - if (user_program) - _cogl_program_flush_uniforms (user_program, - gl_program, - program_changed); - - /* We need to track the last pipeline that the program was used with - * so know if we need to update all of the uniforms */ - priv->last_used_for_pipeline = pipeline; -} - -static void -_cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - if ((change & COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN)) - dirty_glsl_program_state (pipeline); -#ifdef HAVE_COGL_GLES2 - else - { - int i; - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if ((change & builtin_uniforms[i].change)) - { - CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline); - if (priv) - priv->dirty_builtin_uniforms |= 1 << i; - return; - } - } -#endif /* HAVE_COGL_GLES2 */ -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_progend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_FRAGMENT_CODEGEN)) - { - dirty_glsl_program_state (owner); - return; - } - - if (change & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT) - { - CoglPipelineProgendPrivate *priv = get_glsl_priv (owner); - if (priv) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - priv->unit_state[unit_index].dirty_combine_constant = TRUE; - } - } - - if (change & COGL_PIPELINE_LAYER_STATE_USER_MATRIX) - { - CoglPipelineProgendPrivate *priv = get_glsl_priv (owner); - if (priv) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - priv->unit_state[unit_index].dirty_texture_matrix = TRUE; - } - } -} - -#ifdef HAVE_COGL_GLES2 - -static void -flush_modelview_cb (gboolean is_identity, - const CoglMatrix *matrix, - void *user_data) -{ - CoglPipelineProgendPrivate *priv = user_data; - - GE( glUniformMatrix4fv (priv->modelview_uniform, 1, FALSE, - cogl_matrix_get_array (matrix)) ); -} - -static void -flush_projection_cb (gboolean is_identity, - const CoglMatrix *matrix, - void *user_data) -{ - CoglPipelineProgendPrivate *priv = user_data; - - GE( glUniformMatrix4fv (priv->projection_uniform, 1, FALSE, - cogl_matrix_get_array (matrix)) ); -} - -typedef struct -{ - CoglPipelineProgendPrivate *priv; - const CoglMatrix *projection_matrix; -} FlushCombinedData; - -static void -flush_combined_step_two_cb (gboolean is_identity, - const CoglMatrix *matrix, - void *user_data) -{ - FlushCombinedData *data = user_data; - CoglMatrix mvp_matrix; - - /* If the modelview is the identity then we can bypass the matrix - multiplication */ - if (is_identity) - GE( glUniformMatrix4fv (data->priv->mvp_uniform, 1, FALSE, - cogl_matrix_get_array (data->projection_matrix)) ); - else - { - cogl_matrix_multiply (&mvp_matrix, - data->projection_matrix, - matrix); - - GE( glUniformMatrix4fv (data->priv->mvp_uniform, 1, FALSE, - cogl_matrix_get_array (&mvp_matrix)) ); - } -} - -static void -flush_combined_step_one_cb (gboolean is_identity, - const CoglMatrix *matrix, - void *user_data) -{ - FlushCombinedData data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - data.priv = user_data; - data.projection_matrix = matrix; - - _cogl_matrix_stack_prepare_for_flush (ctx->flushed_modelview_stack, - COGL_MATRIX_MODELVIEW, - flush_combined_step_two_cb, - &data); -} - -static void -_cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline) -{ - CoglPipelineProgendPrivate *priv = get_glsl_priv (pipeline); - gboolean modelview_changed; - gboolean projection_changed; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* We only need to update the matrices if we're using the the GLSL - vertend, but this is a requirement on GLES2 anyway */ - g_return_if_fail (pipeline->vertend == COGL_PIPELINE_VERTEND_GLSL); - - priv = get_glsl_priv (pipeline); - - /* An initial pipeline is flushed while creating the context. At - this point there are no matrices flushed so we can't do - anything */ - if (ctx->flushed_modelview_stack == NULL || - ctx->flushed_projection_stack == NULL) - return; - - /* When flushing from the journal the modelview matrix is usually - the identity matrix so it makes sense to optimise this case by - specifically checking whether we already have the identity matrix - which will catch a lot of common cases of redundant flushing */ - if (priv->flushed_modelview_is_identity && - _cogl_matrix_stack_has_identity_flag (ctx->flushed_modelview_stack)) - modelview_changed = FALSE; - else - modelview_changed = - priv->flushed_modelview_stack != ctx->flushed_modelview_stack || - priv->flushed_modelview_stack_age != - _cogl_matrix_stack_get_age (priv->flushed_modelview_stack); - - projection_changed = - priv->flushed_projection_stack != ctx->flushed_projection_stack || - priv->flushed_projection_stack_age != - _cogl_matrix_stack_get_age (priv->flushed_projection_stack); - - if (modelview_changed) - { - cogl_object_ref (ctx->flushed_modelview_stack); - if (priv->flushed_modelview_stack) - cogl_object_unref (priv->flushed_modelview_stack); - priv->flushed_modelview_stack = ctx->flushed_modelview_stack; - priv->flushed_modelview_stack_age = - _cogl_matrix_stack_get_age (ctx->flushed_modelview_stack); - priv->flushed_modelview_is_identity = - _cogl_matrix_stack_has_identity_flag (ctx->flushed_modelview_stack); - - if (priv->modelview_uniform != -1) - _cogl_matrix_stack_prepare_for_flush (priv->flushed_modelview_stack, - COGL_MATRIX_MODELVIEW, - flush_modelview_cb, - priv); - } - - if (projection_changed) - { - cogl_object_ref (ctx->flushed_projection_stack); - if (priv->flushed_projection_stack) - cogl_object_unref (priv->flushed_projection_stack); - priv->flushed_projection_stack = ctx->flushed_projection_stack; - priv->flushed_projection_stack_age = - _cogl_matrix_stack_get_age (ctx->flushed_projection_stack); - - if (priv->projection_uniform != -1) - _cogl_matrix_stack_prepare_for_flush (priv->flushed_projection_stack, - COGL_MATRIX_PROJECTION, - flush_projection_cb, - priv); - } - - if (priv->mvp_uniform != -1 && (modelview_changed || projection_changed)) - _cogl_matrix_stack_prepare_for_flush (ctx->flushed_projection_stack, - COGL_MATRIX_PROJECTION, - flush_combined_step_one_cb, - priv); -} - -static void -update_float_uniform (CoglPipeline *pipeline, - int uniform_location, - void *getter_func) -{ - float (* float_getter_func) (CoglPipeline *) = getter_func; - float value; - - value = float_getter_func (pipeline); - GE( glUniform1f (uniform_location, value) ); -} - -#endif - -const CoglPipelineProgend _cogl_pipeline_glsl_progend = - { - _cogl_pipeline_progend_glsl_end, - _cogl_pipeline_progend_glsl_pre_change_notify, - _cogl_pipeline_progend_glsl_layer_pre_change_notify, -#ifdef HAVE_COGL_GLES2 - _cogl_pipeline_progend_glsl_pre_paint -#else - NULL -#endif - }; - -#endif /* COGL_PIPELINE_PROGEND_GLSL */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-vertend-fixed-private.h b/clutter/cogl/cogl/cogl-pipeline-vertend-fixed-private.h deleted file mode 100644 index 59bce34..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-vertend-fixed-private.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_PIPELINE_VERTEND_FIXED_PRIVATE_H -#define __COGL_PIPELINE_VERTEND_FIXED_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineVertend _cogl_pipeline_fixed_vertend; - -#endif /* __COGL_PIPELINE_VERTEND_FIXED_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-vertend-fixed.c b/clutter/cogl/cogl/cogl-pipeline-vertend-fixed.c deleted file mode 100644 index dc2008a..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-vertend-fixed.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" - -#ifdef COGL_PIPELINE_VERTEND_FIXED - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-program-private.h" - -const CoglPipelineVertend _cogl_pipeline_fixed_vertend; - -static gboolean -_cogl_pipeline_vertend_fixed_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - CoglProgram *user_program; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) - return FALSE; - - /* If there is a user program with a vertex shader then the - appropriate backend for that language should handle it. We can - still use the fixed vertex backend if the program only contains - a fragment shader */ - user_program = cogl_pipeline_get_user_program (pipeline); - if (user_program != COGL_INVALID_HANDLE && - _cogl_program_has_vertex_shader (user_program)) - return FALSE; - - _cogl_use_vertex_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED); - - return TRUE; -} - -static gboolean -_cogl_pipeline_vertend_fixed_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index); - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX) - { - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, state); - - _cogl_matrix_stack_set (unit->matrix_stack, - &authority->big_state->matrix); - - _cogl_set_active_texture_unit (unit_index); - - _cogl_matrix_stack_flush_to_gl (unit->matrix_stack, COGL_MATRIX_TEXTURE); - } - - return TRUE; -} - -static gboolean -_cogl_pipeline_vertend_fixed_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - if (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); - - if (ctx->point_size_cache != authority->big_state->point_size) - { - GE( glPointSize (authority->big_state->point_size) ); - ctx->point_size_cache = authority->big_state->point_size; - } - } - - return TRUE; -} - -const CoglPipelineVertend _cogl_pipeline_fixed_vertend = -{ - _cogl_pipeline_vertend_fixed_start, - _cogl_pipeline_vertend_fixed_add_layer, - _cogl_pipeline_vertend_fixed_end, - NULL, /* pipeline_change_notify */ - NULL /* layer_change_notify */ -}; - -#endif /* COGL_PIPELINE_VERTEND_FIXED */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-vertend-glsl-private.h b/clutter/cogl/cogl/cogl-pipeline-vertend-glsl-private.h deleted file mode 100644 index 52a078c..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-vertend-glsl-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PIPELINE_VERTEND_GLSL_PRIVATE_H -#define __COGL_PIPELINE_VERTEND_GLSL_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineVertend _cogl_pipeline_glsl_vertend; - -GLuint -_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline); - -#endif /* __COGL_PIPELINE_VERTEND_GLSL_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-pipeline-vertend-glsl.c b/clutter/cogl/cogl/cogl-pipeline-vertend-glsl.c deleted file mode 100644 index 84a5243..0000000 --- a/clutter/cogl/cogl/cogl-pipeline-vertend-glsl.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" - -#ifdef COGL_PIPELINE_VERTEND_GLSL - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-program-private.h" -#include "cogl-pipeline-vertend-glsl-private.h" - -#ifndef HAVE_COGL_GLES2 - -#define glCreateShader ctx->drv.pf_glCreateShader -#define glGetShaderiv ctx->drv.pf_glGetShaderiv -#define glGetShaderInfoLog ctx->drv.pf_glGetShaderInfoLog -#define glCompileShader ctx->drv.pf_glCompileShader -#define glShaderSource ctx->drv.pf_glShaderSource -#define glDeleteShader ctx->drv.pf_glDeleteShader - -#endif /* HAVE_COGL_GLES2 */ - -const CoglPipelineVertend _cogl_pipeline_glsl_vertend; - -typedef struct -{ - unsigned int ref_count; - - GLuint gl_shader; - GString *header, *source; - - /* Age of the user program that was current when the shader was - generated. We need to keep track of this because if the user - program changes then we may need to redecide whether to generate - a shader at all */ - unsigned int user_program_age; -} CoglPipelineVertendPrivate; - -static CoglUserDataKey glsl_priv_key; - -static CoglPipelineVertendPrivate * -get_glsl_priv (CoglPipeline *pipeline) -{ - return cogl_object_get_user_data (COGL_OBJECT (pipeline), &glsl_priv_key); -} - -static void -destroy_glsl_priv (void *user_data) -{ - CoglPipelineVertendPrivate *priv = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (--priv->ref_count == 0) - { - if (priv->gl_shader) - GE( glDeleteShader (priv->gl_shader) ); - - g_slice_free (CoglPipelineVertendPrivate, priv); - } -} - -static void -set_glsl_priv (CoglPipeline *pipeline, CoglPipelineVertendPrivate *priv) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &glsl_priv_key, - priv, - destroy_glsl_priv); -} - -static void -dirty_glsl_shader_state (CoglPipeline *pipeline) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &glsl_priv_key, - NULL, - destroy_glsl_priv); -} - -GLuint -_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline) -{ - CoglPipelineVertendPrivate *priv = get_glsl_priv (pipeline); - - if (priv) - return priv->gl_shader; - else - return 0; -} - -static gboolean -_cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - CoglPipelineVertendPrivate *priv; - CoglProgram *user_program; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) - return FALSE; - - user_program = cogl_pipeline_get_user_program (pipeline); - - /* If the user program has a vertex shader that isn't GLSL then the - appropriate vertend for that language should handle it */ - if (user_program && - _cogl_program_has_vertex_shader (user_program) && - _cogl_program_get_language (user_program) != COGL_SHADER_LANGUAGE_GLSL) - return FALSE; - - /* Now lookup our glsl backend private state (allocating if - * necessary) */ - priv = get_glsl_priv (pipeline); - - if (priv == NULL) - { - CoglPipeline *authority; - - /* Get the authority for anything affecting vertex shader - state */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN & - ~COGL_PIPELINE_STATE_LAYERS, - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN); - - priv = get_glsl_priv (authority); - - if (priv == NULL) - { - priv = g_slice_new0 (CoglPipelineVertendPrivate); - priv->ref_count = 1; - set_glsl_priv (authority, priv); - } - - if (authority != pipeline) - { - priv->ref_count++; - set_glsl_priv (pipeline, priv); - } - } - - if (priv->gl_shader) - { - /* If we already have a valid GLSL shader then we don't need to - generate a new one. However if there's a user program and it - has changed since the last link then we do need a new shader */ - if (user_program == NULL || - priv->user_program_age == user_program->age) - return TRUE; - - /* We need to recreate the shader so destroy the existing one */ - GE( glDeleteShader (priv->gl_shader) ); - priv->gl_shader = 0; - } - - /* If we make it here then we have a priv struct without a gl_shader - either because this is the first time we've encountered it or - because the user program has changed */ - - if (user_program) - priv->user_program_age = user_program->age; - - /* If the user program contains a vertex shader then we don't need - to generate one */ - if (user_program && - _cogl_program_has_vertex_shader (user_program)) - return TRUE; - - /* We reuse two grow-only GStrings for code-gen. One string - contains the uniform and attribute declarations while the - other contains the main function. We need two strings - because we need to dynamically declare attributes as the - add_layer callback is invoked */ - g_string_set_size (ctx->codegen_header_buffer, 0); - g_string_set_size (ctx->codegen_source_buffer, 0); - priv->header = ctx->codegen_header_buffer; - priv->source = ctx->codegen_source_buffer; - - g_string_append (priv->source, - "void\n" - "main ()\n" - "{\n"); - -#ifdef HAVE_COGL_GLES2 - - /* There is no builtin uniform for the pointsize on GLES2 so we need - to copy it from the custom uniform in the vertex shader */ - g_string_append (priv->source, - " cogl_point_size_out = cogl_point_size_in;\n"); - -#else /* HAVE_COGL_GLES2 */ - - /* On regular OpenGL we'll just flush the point size builtin */ - if (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); - - if (ctx->point_size_cache != authority->big_state->point_size) - { - GE( glPointSize (authority->big_state->point_size) ); - ctx->point_size_cache = authority->big_state->point_size; - } - } - -#endif /* HAVE_COGL_GLES2 */ - - return TRUE; -} - -static gboolean -_cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - CoglPipelineVertendPrivate *priv; - int unit_index; - - priv = get_glsl_priv (pipeline); - - unit_index = _cogl_pipeline_layer_get_unit_index (layer); - -#ifndef HAVE_COGL_GLES2 - - /* We are using the fixed function uniforms for the user matrices - and the only way to set them is with the fixed function API so we - still need to flush them here */ - if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX) - { - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, state); - CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index); - - _cogl_matrix_stack_set (unit->matrix_stack, - &authority->big_state->matrix); - - _cogl_set_active_texture_unit (unit_index); - - _cogl_matrix_stack_flush_to_gl (unit->matrix_stack, COGL_MATRIX_TEXTURE); - } - -#endif /* HAVE_COGL_GLES2 */ - - if (priv->source == NULL) - return TRUE; - - /* Transform the texture coordinates by the layer's user matrix. - * - * FIXME: this should avoid doing the transform if there is no user - * matrix set. This might need a separate layer state flag for - * whether there is a user matrix - * - * FIXME: we could be more clever here and try to detect if the - * fragment program is going to use the texture coordinates and - * avoid setting them if not - */ - - g_string_append_printf (priv->source, - " cogl_tex_coord_out[%i] = " - "cogl_texture_matrix[%i] * cogl_tex_coord%i_in;\n", - unit_index, unit_index, unit_index); - - return TRUE; -} - -static gboolean -_cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineVertendPrivate *priv; - - _COGL_GET_CONTEXT (ctx, FALSE); - - priv = get_glsl_priv (pipeline); - - if (priv->source) - { - const char *source_strings[2]; - GLint lengths[2]; - GLint compile_status; - GLuint shader; - int n_layers; - - COGL_STATIC_COUNTER (vertend_glsl_compile_counter, - "glsl vertex compile counter", - "Increments each time a new GLSL " - "vertex shader is compiled", - 0 /* no application private data */); - COGL_COUNTER_INC (_cogl_uprof_context, vertend_glsl_compile_counter); - - g_string_append (priv->source, - " cogl_position_out = " - "cogl_modelview_projection_matrix * " - "cogl_position_in;\n" - " cogl_color_out = cogl_color_in;\n" - "}\n"); - - GE_RET( shader, glCreateShader (GL_VERTEX_SHADER) ); - - lengths[0] = priv->header->len; - source_strings[0] = priv->header->str; - lengths[1] = priv->source->len; - source_strings[1] = priv->source->str; - - n_layers = cogl_pipeline_get_n_layers (pipeline); - - _cogl_shader_set_source_with_boilerplate (shader, GL_VERTEX_SHADER, - n_layers, - 2, /* count */ - source_strings, lengths); - - GE( glCompileShader (shader) ); - GE( glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status) ); - - if (!compile_status) - { - GLint len = 0; - char *shader_log; - - GE( glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &len) ); - shader_log = g_alloca (len); - GE( glGetShaderInfoLog (shader, len, &len, shader_log) ); - g_warning ("Shader compilation failed:\n%s", shader_log); - } - - priv->header = NULL; - priv->source = NULL; - priv->gl_shader = shader; - } - - return TRUE; -} - -static void -_cogl_pipeline_vertend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - if ((change & COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN)) - dirty_glsl_shader_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_vertend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineVertendPrivate *priv; - - priv = get_glsl_priv (owner); - if (!priv) - return; - - if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN)) - { - dirty_glsl_shader_state (owner); - return; - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ -} - -const CoglPipelineVertend _cogl_pipeline_glsl_vertend = - { - _cogl_pipeline_vertend_glsl_start, - _cogl_pipeline_vertend_glsl_add_layer, - _cogl_pipeline_vertend_glsl_end, - _cogl_pipeline_vertend_glsl_pre_change_notify, - _cogl_pipeline_vertend_glsl_layer_pre_change_notify - }; - -#endif /* COGL_PIPELINE_VERTEND_GLSL */ diff --git a/clutter/cogl/cogl/cogl-pipeline.c b/clutter/cogl/cogl/cogl-pipeline.c deleted file mode 100644 index 6dec6a0..0000000 --- a/clutter/cogl/cogl/cogl-pipeline.c +++ /dev/null @@ -1,6854 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-object.h" - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-texture-private.h" -#include "cogl-blend-string.h" -#include "cogl-journal-private.h" -#include "cogl-color-private.h" -#include "cogl-util.h" -#include "cogl-profile.h" - -#include -#include -#include - -typedef gboolean (*CoglPipelineStateComparitor) (CoglPipeline *authority0, - CoglPipeline *authority1); - -static CoglPipelineLayer *_cogl_pipeline_layer_copy (CoglPipelineLayer *layer); - -static void _cogl_pipeline_free (CoglPipeline *tex); -static void _cogl_pipeline_layer_free (CoglPipelineLayer *layer); -static void _cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean inc_n_layers); -static void handle_automatic_blend_enable (CoglPipeline *pipeline, - CoglPipelineState changes); -static void recursively_free_layer_caches (CoglPipeline *pipeline); -static gboolean _cogl_pipeline_is_weak (CoglPipeline *pipeline); - -const CoglPipelineFragend *_cogl_pipeline_fragends[COGL_PIPELINE_N_FRAGENDS]; -const CoglPipelineVertend *_cogl_pipeline_vertends[COGL_PIPELINE_N_VERTENDS]; -/* The 'MAX' here is so that we don't define an empty array when there - are no progends */ -const CoglPipelineProgend * -_cogl_pipeline_progends[MAX (COGL_PIPELINE_N_PROGENDS, 1)]; - -#ifdef COGL_PIPELINE_FRAGEND_GLSL -#include "cogl-pipeline-fragend-glsl-private.h" -#endif -#ifdef COGL_PIPELINE_FRAGEND_ARBFP -#include "cogl-pipeline-fragend-arbfp-private.h" -#endif -#ifdef COGL_PIPELINE_FRAGEND_FIXED -#include "cogl-pipeline-fragend-fixed-private.h" -#endif -#ifdef COGL_PIPELINE_PROGEND_GLSL -#include "cogl-pipeline-progend-glsl-private.h" -#endif - -#ifdef COGL_PIPELINE_VERTEND_GLSL -#include "cogl-pipeline-vertend-glsl-private.h" -#endif -#ifdef COGL_PIPELINE_VERTEND_FIXED -#include "cogl-pipeline-vertend-fixed-private.h" -#endif - -COGL_OBJECT_DEFINE (Pipeline, pipeline); -/* This type was made deprecated before the cogl_is_pipeline_layer - function was ever exposed in the public headers so there's no need - to make the cogl_is_pipeline_layer function public. We use INTERNAL - so that the cogl_is_* function won't get defined */ -COGL_OBJECT_INTERNAL_DEFINE (PipelineLayer, pipeline_layer); - -GQuark -_cogl_pipeline_error_quark (void) -{ - return g_quark_from_static_string ("cogl-pipeline-error-quark"); -} - -static void -_cogl_pipeline_node_init (CoglPipelineNode *node) -{ - node->parent = NULL; - node->has_children = FALSE; -} - -static void -_cogl_pipeline_node_set_parent_real (CoglPipelineNode *node, - CoglPipelineNode *parent, - CoglPipelineNodeUnparentVFunc unparent, - gboolean take_strong_reference) -{ - /* NB: the old parent may indirectly be keeping the new parent alive - * so we have to ref the new parent before unrefing the old. - * - * Note: we take a reference here regardless of - * take_strong_reference because weak children may need special - * handling when the parent disposes itself which relies on a - * consistent link to all weak nodes. Once the node is linked to its - * parent then we remove the reference at the end if - * take_strong_reference == FALSE. */ - cogl_object_ref (parent); - - if (node->parent) - unparent (node); - - if (G_UNLIKELY (parent->has_children)) - parent->children = g_list_prepend (parent->children, node); - else - { - parent->has_children = TRUE; - parent->first_child = node; - parent->children = NULL; - } - - node->parent = parent; - node->has_parent_reference = take_strong_reference; - - /* Now that there is a consistent parent->child link we can remove - * the parent reference if no reference was requested. If it turns - * out that the new parent was only being kept alive by the old - * parent then it will be disposed of here. */ - if (!take_strong_reference) - cogl_object_unref (parent); -} - -static void -_cogl_pipeline_node_unparent_real (CoglPipelineNode *node) -{ - CoglPipelineNode *parent = node->parent; - - if (parent == NULL) - return; - - g_return_if_fail (parent->has_children); - - if (parent->first_child == node) - { - if (parent->children) - { - parent->first_child = parent->children->data; - parent->children = - g_list_delete_link (parent->children, parent->children); - } - else - parent->has_children = FALSE; - } - else - parent->children = g_list_remove (parent->children, node); - - if (node->has_parent_reference) - cogl_object_unref (parent); - - node->parent = NULL; -} - -void -_cogl_pipeline_node_foreach_child (CoglPipelineNode *node, - CoglPipelineNodeChildCallback callback, - void *user_data) -{ - if (node->has_children) - { - callback (node->first_child, user_data); - g_list_foreach (node->children, (GFunc)callback, user_data); - } -} - -/* - * This initializes the first pipeline owned by the Cogl context. All - * subsequently instantiated pipelines created via the cogl_pipeline_new() - * API will initially be a copy of this pipeline. - * - * The default pipeline is the topmost ancester for all pipelines. - */ -void -_cogl_pipeline_init_default_pipeline (void) -{ - /* Create new - blank - pipeline */ - CoglPipeline *pipeline = g_slice_new0 (CoglPipeline); - /* XXX: NB: It's important that we zero this to avoid polluting - * pipeline hash values with un-initialized data */ - CoglPipelineBigState *big_state = g_slice_new0 (CoglPipelineBigState); - CoglPipelineLightingState *lighting_state = &big_state->lighting_state; - CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state; - CoglPipelineBlendState *blend_state = &big_state->blend_state; - CoglPipelineDepthState *depth_state = &big_state->depth_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Take this opportunity to setup the backends... */ -#ifdef COGL_PIPELINE_FRAGEND_GLSL - _cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_GLSL] = - &_cogl_pipeline_glsl_fragend; -#endif -#ifdef COGL_PIPELINE_FRAGEND_ARBFP - _cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_ARBFP] = - &_cogl_pipeline_arbfp_fragend; -#endif -#ifdef COGL_PIPELINE_FRAGEND_FIXED - _cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_FIXED] = - &_cogl_pipeline_fixed_fragend; -#endif -#ifdef COGL_PIPELINE_PROGEND_GLSL - _cogl_pipeline_progends[COGL_PIPELINE_PROGEND_GLSL] = - &_cogl_pipeline_glsl_progend; -#endif - -#ifdef COGL_PIPELINE_VERTEND_GLSL - _cogl_pipeline_vertends[COGL_PIPELINE_VERTEND_GLSL] = - &_cogl_pipeline_glsl_vertend; -#endif -#ifdef COGL_PIPELINE_VERTEND_FIXED - _cogl_pipeline_vertends[COGL_PIPELINE_VERTEND_FIXED] = - &_cogl_pipeline_fixed_vertend; -#endif - - _cogl_pipeline_node_init (COGL_PIPELINE_NODE (pipeline)); - - pipeline->is_weak = FALSE; - pipeline->journal_ref_count = 0; - pipeline->fragend = COGL_PIPELINE_FRAGEND_UNDEFINED; - pipeline->vertend = COGL_PIPELINE_VERTEND_UNDEFINED; - pipeline->differences = COGL_PIPELINE_STATE_ALL_SPARSE; - - pipeline->real_blend_enable = FALSE; - - pipeline->blend_enable = COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC; - pipeline->layer_differences = NULL; - pipeline->n_layers = 0; - - pipeline->big_state = big_state; - pipeline->has_big_state = TRUE; - - pipeline->static_breadcrumb = "default pipeline"; - pipeline->has_static_breadcrumb = TRUE; - - pipeline->age = 0; - - /* Use the same defaults as the GL spec... */ - cogl_color_init_from_4ub (&pipeline->color, 0xff, 0xff, 0xff, 0xff); - - /* Use the same defaults as the GL spec... */ - lighting_state->ambient[0] = 0.2; - lighting_state->ambient[1] = 0.2; - lighting_state->ambient[2] = 0.2; - lighting_state->ambient[3] = 1.0; - - lighting_state->diffuse[0] = 0.8; - lighting_state->diffuse[1] = 0.8; - lighting_state->diffuse[2] = 0.8; - lighting_state->diffuse[3] = 1.0; - - lighting_state->specular[0] = 0; - lighting_state->specular[1] = 0; - lighting_state->specular[2] = 0; - lighting_state->specular[3] = 1.0; - - lighting_state->emission[0] = 0; - lighting_state->emission[1] = 0; - lighting_state->emission[2] = 0; - lighting_state->emission[3] = 1.0; - - lighting_state->shininess = 0.0f; - - /* Use the same defaults as the GL spec... */ - alpha_state->alpha_func = COGL_PIPELINE_ALPHA_FUNC_ALWAYS; - alpha_state->alpha_func_reference = 0.0; - - /* Not the same as the GL default, but seems saner... */ -#ifndef HAVE_COGL_GLES - blend_state->blend_equation_rgb = GL_FUNC_ADD; - blend_state->blend_equation_alpha = GL_FUNC_ADD; - blend_state->blend_src_factor_alpha = GL_ONE; - blend_state->blend_dst_factor_alpha = GL_ONE_MINUS_SRC_ALPHA; - cogl_color_init_from_4ub (&blend_state->blend_constant, - 0x00, 0x00, 0x00, 0x00); -#endif - blend_state->blend_src_factor_rgb = GL_ONE; - blend_state->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA; - - big_state->user_program = COGL_INVALID_HANDLE; - - /* The same as the GL defaults */ - depth_state->depth_test_enabled = FALSE; - depth_state->depth_test_function = COGL_DEPTH_TEST_FUNCTION_LESS; - depth_state->depth_writing_enabled = TRUE; - depth_state->depth_range_near = 0; - depth_state->depth_range_far = 1; - - big_state->point_size = 1.0f; - - ctx->default_pipeline = _cogl_pipeline_object_new (pipeline); -} - -static void -_cogl_pipeline_unparent (CoglPipelineNode *pipeline) -{ - /* Chain up */ - _cogl_pipeline_node_unparent_real (pipeline); -} - -static gboolean -recursively_free_layer_caches_cb (CoglPipelineNode *node, - void *user_data) -{ - recursively_free_layer_caches (COGL_PIPELINE (node)); - return TRUE; -} - -/* This recursively frees the layers_cache of a pipeline and all of - * its descendants. - * - * For instance if we change a pipelines ->layer_differences list - * then that pipeline and all of its descendants may now have - * incorrect layer caches. */ -static void -recursively_free_layer_caches (CoglPipeline *pipeline) -{ - /* Note: we maintain the invariable that if a pipeline already has a - * dirty layers_cache then so do all of its descendants. */ - if (pipeline->layers_cache_dirty) - return; - - if (G_UNLIKELY (pipeline->layers_cache != pipeline->short_layers_cache)) - g_slice_free1 (sizeof (CoglPipelineLayer *) * pipeline->n_layers, - pipeline->layers_cache); - pipeline->layers_cache_dirty = TRUE; - - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (pipeline), - recursively_free_layer_caches_cb, - NULL); -} - -static void -_cogl_pipeline_set_parent (CoglPipeline *pipeline, - CoglPipeline *parent, - gboolean take_strong_reference) -{ - /* Chain up */ - _cogl_pipeline_node_set_parent_real (COGL_PIPELINE_NODE (pipeline), - COGL_PIPELINE_NODE (parent), - _cogl_pipeline_unparent, - take_strong_reference); - - /* Since we just changed the ancestry of the pipeline its cache of - * layers could now be invalid so free it... */ - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - recursively_free_layer_caches (pipeline); - - /* If the backends are also caching state along with the pipeline - * that depends on the pipeline's ancestry then it may be notified - * here... - */ - if (pipeline->fragend != COGL_PIPELINE_FRAGEND_UNDEFINED && - _cogl_pipeline_fragends[pipeline->fragend]->pipeline_set_parent_notify) - { - const CoglPipelineFragend *fragend = - _cogl_pipeline_fragends[pipeline->fragend]; - fragend->pipeline_set_parent_notify (pipeline); - } -} - -static void -_cogl_pipeline_promote_weak_ancestors (CoglPipeline *strong) -{ - CoglPipelineNode *n; - - g_return_if_fail (!strong->is_weak); - - for (n = COGL_PIPELINE_NODE (strong)->parent; n; n = n->parent) - { - CoglPipeline *pipeline = COGL_PIPELINE (n); - - cogl_object_ref (pipeline); - - if (!pipeline->is_weak) - return; - } -} - -static void -_cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong) -{ - CoglPipeline *parent = _cogl_pipeline_get_parent (strong); - CoglPipelineNode *n; - - g_return_if_fail (!strong->is_weak); - - if (!parent || !parent->is_weak) - return; - - for (n = COGL_PIPELINE_NODE (strong)->parent; n; n = n->parent) - { - CoglPipeline *pipeline = COGL_PIPELINE (n); - - cogl_object_unref (pipeline); - - if (!pipeline->is_weak) - return; - } -} - -/* XXX: Always have an eye out for opportunities to lower the cost of - * cogl_pipeline_copy. */ -static CoglPipeline * -_cogl_pipeline_copy (CoglPipeline *src, gboolean is_weak) -{ - CoglPipeline *pipeline = g_slice_new (CoglPipeline); - - _cogl_pipeline_node_init (COGL_PIPELINE_NODE (pipeline)); - - pipeline->is_weak = is_weak; - - pipeline->journal_ref_count = 0; - - pipeline->differences = 0; - - pipeline->has_big_state = FALSE; - - /* NB: real_blend_enable isn't a sparse property, it's valid for - * every pipeline node so we have fast access to it. */ - pipeline->real_blend_enable = src->real_blend_enable; - - /* XXX: - * consider generalizing the idea of "cached" properties. These - * would still have an authority like other sparse properties but - * you wouldn't have to walk up the ancestry to find the authority - * because the value would be cached directly in each pipeline. - */ - - pipeline->layers_cache_dirty = TRUE; - pipeline->deprecated_get_layers_list_dirty = TRUE; - - pipeline->fragend = src->fragend; - pipeline->fragend_priv_set_mask = 0; - - pipeline->vertend = src->vertend; - - pipeline->has_static_breadcrumb = FALSE; - - pipeline->age = 0; - - _cogl_pipeline_set_parent (pipeline, src, !is_weak); - - /* The semantics for copying a weak pipeline are that we promote all - * weak ancestors to temporarily become strong pipelines until the - * copy is freed. */ - if (!is_weak) - _cogl_pipeline_promote_weak_ancestors (pipeline); - - return _cogl_pipeline_object_new (pipeline); -} - -CoglPipeline * -cogl_pipeline_copy (CoglPipeline *src) -{ - return _cogl_pipeline_copy (src, FALSE); -} - -CoglPipeline * -_cogl_pipeline_weak_copy (CoglPipeline *pipeline, - CoglPipelineDestroyCallback callback, - void *user_data) -{ - CoglPipeline *copy; - CoglPipeline *copy_pipeline; - - copy = _cogl_pipeline_copy (pipeline, TRUE); - copy_pipeline = COGL_PIPELINE (copy); - copy_pipeline->destroy_callback = callback; - copy_pipeline->destroy_data = user_data; - - return copy; -} - -CoglPipeline * -cogl_pipeline_new (void) -{ - CoglPipeline *new; - - _COGL_GET_CONTEXT (ctx, NULL); - - new = cogl_pipeline_copy (ctx->default_pipeline); - _cogl_pipeline_set_static_breadcrumb (new, "new"); - return new; -} - -static void -_cogl_pipeline_fragend_free_priv (CoglPipeline *pipeline) -{ - if (pipeline->fragend != COGL_PIPELINE_FRAGEND_UNDEFINED && - _cogl_pipeline_fragends[pipeline->fragend]->free_priv) - { - const CoglPipelineFragend *fragend = - _cogl_pipeline_fragends[pipeline->fragend]; - fragend->free_priv (pipeline); - } -} - -static gboolean -destroy_weak_children_cb (CoglPipelineNode *node, - void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - - if (_cogl_pipeline_is_weak (pipeline)) - { - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - pipeline->destroy_callback (pipeline, pipeline->destroy_data); - _cogl_pipeline_unparent (COGL_PIPELINE_NODE (pipeline)); - } - - return TRUE; -} - -static void -_cogl_pipeline_free (CoglPipeline *pipeline) -{ - if (!pipeline->is_weak) - _cogl_pipeline_revert_weak_ancestors (pipeline); - - /* Weak pipelines don't take a reference on their parent */ - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - g_assert (!COGL_PIPELINE_NODE (pipeline)->has_children); - - _cogl_pipeline_fragend_free_priv (pipeline); - - _cogl_pipeline_unparent (COGL_PIPELINE_NODE (pipeline)); - - if (pipeline->differences & COGL_PIPELINE_STATE_USER_SHADER && - pipeline->big_state->user_program) - cogl_handle_unref (pipeline->big_state->user_program); - - if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) - g_slice_free (CoglPipelineBigState, pipeline->big_state); - - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - g_list_foreach (pipeline->layer_differences, - (GFunc)cogl_object_unref, NULL); - g_list_free (pipeline->layer_differences); - } - - g_slice_free (CoglPipeline, pipeline); -} - -gboolean -_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline) -{ - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - return pipeline->real_blend_enable; -} - -/* XXX: Think twice before making this non static since it is used - * heavily and we expect the compiler to inline it... - */ -static CoglPipelineLayer * -_cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer) -{ - CoglPipelineNode *parent_node = COGL_PIPELINE_NODE (layer)->parent; - return COGL_PIPELINE_LAYER (parent_node); -} - -CoglPipelineLayer * -_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer, - unsigned long difference) -{ - CoglPipelineLayer *authority = layer; - while (!(authority->differences & difference)) - authority = _cogl_pipeline_layer_get_parent (authority); - return authority; -} - -int -_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, COGL_PIPELINE_LAYER_STATE_UNIT); - return authority->unit_index; -} - -static void -_cogl_pipeline_update_layers_cache (CoglPipeline *pipeline) -{ - /* Note: we assume this pipeline is a _LAYERS authority */ - int n_layers; - CoglPipeline *current; - int layers_found; - - if (G_LIKELY (!pipeline->layers_cache_dirty) || - pipeline->n_layers == 0) - return; - - pipeline->layers_cache_dirty = FALSE; - - n_layers = pipeline->n_layers; - if (G_LIKELY (n_layers < G_N_ELEMENTS (pipeline->short_layers_cache))) - { - pipeline->layers_cache = pipeline->short_layers_cache; - memset (pipeline->layers_cache, 0, - sizeof (CoglPipelineLayer *) * - G_N_ELEMENTS (pipeline->short_layers_cache)); - } - else - { - pipeline->layers_cache = - g_slice_alloc0 (sizeof (CoglPipelineLayer *) * n_layers); - } - - /* Notes: - * - * Each pipeline doesn't have to contain a complete list of the layers - * it depends on, some of them are indirectly referenced through the - * pipeline's ancestors. - * - * pipeline->layer_differences only contains a list of layers that - * have changed in relation to its parent. - * - * pipeline->layer_differences is not maintained sorted, but it - * won't contain multiple layers corresponding to a particular - * ->unit_index. - * - * Some of the ancestor pipelines may reference layers with - * ->unit_index values >= n_layers so we ignore them. - * - * As we ascend through the ancestors we are searching for any - * CoglPipelineLayers corresponding to the texture ->unit_index - * values in the range [0,n_layers-1]. As soon as a pointer is found - * we ignore layers of further ancestors with the same ->unit_index - * values. - */ - - layers_found = 0; - for (current = pipeline; - _cogl_pipeline_get_parent (current); - current = _cogl_pipeline_get_parent (current)) - { - GList *l; - - if (!(current->differences & COGL_PIPELINE_STATE_LAYERS)) - continue; - - for (l = current->layer_differences; l; l = l->next) - { - CoglPipelineLayer *layer = l->data; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - if (unit_index < n_layers && !pipeline->layers_cache[unit_index]) - { - pipeline->layers_cache[unit_index] = layer; - layers_found++; - if (layers_found == n_layers) - return; - } - } - } - - g_warn_if_reached (); -} - -/* XXX: Be carefull when using this API that the callback given doesn't result - * in the layer cache being invalidated during the iteration! */ -void -_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, - CoglPipelineInternalLayerCallback callback, - void *user_data) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - int n_layers; - int i; - gboolean cont; - - n_layers = authority->n_layers; - if (n_layers == 0) - return; - - _cogl_pipeline_update_layers_cache (authority); - - for (i = 0, cont = TRUE; i < n_layers && cont == TRUE; i++) - { - g_return_if_fail (authority->layers_cache_dirty == FALSE); - cont = callback (authority->layers_cache[i], user_data); - } -} - -typedef struct -{ - int i; - int *indices; -} AppendLayerIndexState; - -static gboolean -append_layer_index_cb (CoglPipelineLayer *layer, - void *user_data) -{ - AppendLayerIndexState *state = user_data; - state->indices[state->i++] = layer->index; - return TRUE; -} - -void -cogl_pipeline_foreach_layer (CoglPipeline *pipeline, - CoglPipelineLayerCallback callback, - void *user_data) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - AppendLayerIndexState state; - gboolean cont; - int i; - - /* XXX: We don't know what the user is going to want to do to the layers - * but any modification of layers can result in the layer graph changing - * which could confuse _cogl_pipeline_foreach_layer_internal(). We first - * get a list of layer indices which will remain valid so long as the - * user doesn't remove layers. */ - - state.i = 0; - state.indices = g_alloca (authority->n_layers * sizeof (int)); - - _cogl_pipeline_foreach_layer_internal (pipeline, - append_layer_index_cb, - &state); - - for (i = 0, cont = TRUE; i < authority->n_layers && cont; i++) - cont = callback (pipeline, state.indices[i], user_data); -} - -static gboolean -layer_has_alpha_cb (CoglPipelineLayer *layer, void *data) -{ - CoglPipelineLayer *combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - CoglPipelineLayer *tex_authority; - gboolean *has_alpha = data; - - /* has_alpha maintains the alpha status for the GL_PREVIOUS layer */ - - /* For anything but the default texture combine we currently just - * assume it may result in an alpha value < 1 - * - * FIXME: we could do better than this. */ - if (big_state->texture_combine_alpha_func != - COGL_PIPELINE_COMBINE_FUNC_MODULATE || - big_state->texture_combine_alpha_src[0] != - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS || - big_state->texture_combine_alpha_op[0] != - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA || - big_state->texture_combine_alpha_src[1] != - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE || - big_state->texture_combine_alpha_op[1] != - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA) - { - *has_alpha = TRUE; - /* return FALSE to stop iterating layers... */ - return FALSE; - } - - /* NB: A layer may have a combine mode set on it but not yet - * have an associated texture which would mean we'd fallback - * to the default texture which doesn't have an alpha component - */ - tex_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - if (tex_authority->texture && - cogl_texture_get_format (tex_authority->texture) & COGL_A_BIT) - { - *has_alpha = TRUE; - /* return FALSE to stop iterating layers... */ - return FALSE; - } - - *has_alpha = FALSE; - /* return FALSE to continue iterating layers... */ - return TRUE; -} - -static CoglPipeline * -_cogl_pipeline_get_user_program (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_USER_SHADER); - - return authority->big_state->user_program; -} - -static gboolean -_cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline, - unsigned long changes, - const CoglColor *override_color) -{ - CoglPipeline *enable_authority; - CoglPipeline *blend_authority; - CoglPipelineBlendState *blend_state; - CoglPipelineBlendEnable enabled; - unsigned long other_state; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING))) - return FALSE; - - enable_authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE); - - enabled = enable_authority->blend_enable; - if (enabled != COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC) - return enabled == COGL_PIPELINE_BLEND_ENABLE_ENABLED ? TRUE : FALSE; - - blend_authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND); - - blend_state = &blend_authority->big_state->blend_state; - - /* We are trying to identify awkward cases that are equivalent to - * blending being disable, where the output is simply GL_SRC_COLOR. - * - * Note: we assume that all OpenGL drivers will identify the simple - * case of ADD (ONE, ZERO) as equivalent to blending being disabled. - * - * We should update this when we add support for more blend - * functions... - */ - -#ifndef HAVE_COGL_GLES - /* GLES 1 can't change the function or have separate alpha factors */ - if (blend_state->blend_equation_rgb != GL_FUNC_ADD || - blend_state->blend_equation_alpha != GL_FUNC_ADD) - return TRUE; - - if (blend_state->blend_src_factor_alpha != GL_ONE || - blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA) - return TRUE; -#endif - - if (blend_state->blend_src_factor_rgb != GL_ONE || - blend_state->blend_dst_factor_rgb != GL_ONE_MINUS_SRC_ALPHA) - return TRUE; - - /* Given the above constraints, it's now a case of finding any - * SRC_ALPHA that != 1 */ - - /* In the case of a layer state change we need to check everything - * else first since they contribute to the has_alpha status of the - * GL_PREVIOUS layer. */ - if (changes & COGL_PIPELINE_STATE_LAYERS) - changes = COGL_PIPELINE_STATE_AFFECTS_BLENDING; - - if ((override_color && cogl_color_get_alpha_byte (override_color) != 0xff)) - return TRUE; - - if (changes & COGL_PIPELINE_STATE_COLOR) - { - CoglColor tmp; - cogl_pipeline_get_color (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_USER_SHADER) - { - /* We can't make any assumptions about the alpha channel if the user - * is using an unknown fragment shader. - * - * TODO: check that it isn't just a vertex shader! - */ - if (_cogl_pipeline_get_user_program (pipeline) != COGL_INVALID_HANDLE) - return TRUE; - } - - /* XXX: we should only need to look at these if lighting is enabled - */ - if (changes & COGL_PIPELINE_STATE_LIGHTING) - { - /* XXX: This stuff is showing up in sysprof reports which is - * silly because lighting isn't currently actually supported - * by Cogl except for these token properties. When we actually - * expose lighting support we can avoid these checks when - * lighting is disabled. */ -#if 0 - CoglColor tmp; - cogl_pipeline_get_ambient (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - cogl_pipeline_get_diffuse (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - cogl_pipeline_get_specular (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - cogl_pipeline_get_emission (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; -#endif - } - - if (changes & COGL_PIPELINE_STATE_LAYERS) - { - /* has_alpha tracks the alpha status of the GL_PREVIOUS layer. - * To start with that's defined by the pipeline color which - * must be fully opaque if we got this far. */ - gboolean has_alpha = FALSE; - _cogl_pipeline_foreach_layer_internal (pipeline, - layer_has_alpha_cb, - &has_alpha); - if (has_alpha) - return TRUE; - } - - /* At this point, considering just the state that has changed it - * looks like blending isn't needed. If blending was previously - * enabled though it could be that some other state still requires - * that we have blending enabled. In this case we still need to - * go and check the other state... - * - * FIXME: We should explicitly keep track of the mask of state - * groups that are currently causing blending to be enabled so that - * we never have to resort to checking *all* the state and can - * instead always limit the check to those in the mask. - */ - if (pipeline->real_blend_enable) - { - other_state = COGL_PIPELINE_STATE_AFFECTS_BLENDING & ~changes; - if (other_state && - _cogl_pipeline_needs_blending_enabled (pipeline, - other_state, - NULL)) - return TRUE; - } - - return FALSE; -} - -void -_cogl_pipeline_set_fragend (CoglPipeline *pipeline, int fragend) -{ - _cogl_pipeline_fragend_free_priv (pipeline); - pipeline->fragend = fragend; -} - -void -_cogl_pipeline_set_vertend (CoglPipeline *pipeline, int vertend) -{ - pipeline->vertend = vertend; -} - -static void -_cogl_pipeline_copy_differences (CoglPipeline *dest, - CoglPipeline *src, - unsigned long differences) -{ - CoglPipelineBigState *big_state; - - if (differences & COGL_PIPELINE_STATE_COLOR) - dest->color = src->color; - - if (differences & COGL_PIPELINE_STATE_BLEND_ENABLE) - dest->blend_enable = src->blend_enable; - - if (differences & COGL_PIPELINE_STATE_LAYERS) - { - GList *l; - - if (dest->differences & COGL_PIPELINE_STATE_LAYERS && - dest->layer_differences) - { - g_list_foreach (dest->layer_differences, - (GFunc)cogl_object_unref, - NULL); - g_list_free (dest->layer_differences); - } - - for (l = src->layer_differences; l; l = l->next) - { - /* NB: a layer can't have more than one ->owner so we can't - * simply take a references on each of the original - * layer_differences, we have to derive new layers from the - * originals instead. */ - CoglPipelineLayer *copy = _cogl_pipeline_layer_copy (l->data); - _cogl_pipeline_add_layer_difference (dest, copy, FALSE); - cogl_object_unref (copy); - } - - /* Note: we initialize n_layers after adding the layer differences - * since the act of adding the layers will initialize n_layers to 0 - * because dest isn't initially a STATE_LAYERS authority. */ - dest->n_layers = src->n_layers; - } - - if (differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) - { - if (!dest->has_big_state) - { - dest->big_state = g_slice_new (CoglPipelineBigState); - dest->has_big_state = TRUE; - } - big_state = dest->big_state; - } - else - goto check_for_blending_change; - - if (differences & COGL_PIPELINE_STATE_LIGHTING) - { - memcpy (&big_state->lighting_state, - &src->big_state->lighting_state, - sizeof (CoglPipelineLightingState)); - } - - if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC) - big_state->alpha_state.alpha_func = - src->big_state->alpha_state.alpha_func; - - if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE) - big_state->alpha_state.alpha_func_reference = - src->big_state->alpha_state.alpha_func_reference; - - if (differences & COGL_PIPELINE_STATE_BLEND) - { - memcpy (&big_state->blend_state, - &src->big_state->blend_state, - sizeof (CoglPipelineBlendState)); - } - - if (differences & COGL_PIPELINE_STATE_USER_SHADER) - { - if (src->big_state->user_program) - big_state->user_program = - cogl_handle_ref (src->big_state->user_program); - else - big_state->user_program = COGL_INVALID_HANDLE; - } - - if (differences & COGL_PIPELINE_STATE_DEPTH) - { - memcpy (&big_state->depth_state, - &src->big_state->depth_state, - sizeof (CoglPipelineDepthState)); - } - - if (differences & COGL_PIPELINE_STATE_FOG) - { - memcpy (&big_state->fog_state, - &src->big_state->fog_state, - sizeof (CoglPipelineFogState)); - } - - if (differences & COGL_PIPELINE_STATE_POINT_SIZE) - big_state->point_size = src->big_state->point_size; - - /* XXX: we shouldn't bother doing this in most cases since - * _copy_differences is typically used to initialize pipeline state - * by copying it from the current authority, so it's not actually - * *changing* anything. - */ -check_for_blending_change: - if (differences & COGL_PIPELINE_STATE_AFFECTS_BLENDING) - handle_automatic_blend_enable (dest, differences); - - dest->differences |= differences; -} - -static void -_cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, - CoglPipelineState change) -{ - CoglPipeline *authority; - - g_return_if_fail (change & COGL_PIPELINE_STATE_ALL_SPARSE); - - if (!(change & COGL_PIPELINE_STATE_MULTI_PROPERTY)) - return; - - authority = _cogl_pipeline_get_authority (pipeline, change); - - switch (change) - { - /* XXX: avoid using a default: label so we get a warning if we - * don't explicitly handle a newly defined state-group here. */ - case COGL_PIPELINE_STATE_COLOR: - case COGL_PIPELINE_STATE_BLEND_ENABLE: - case COGL_PIPELINE_STATE_ALPHA_FUNC: - case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE: - case COGL_PIPELINE_STATE_POINT_SIZE: - case COGL_PIPELINE_STATE_USER_SHADER: - case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE: - g_return_if_reached (); - - case COGL_PIPELINE_STATE_LAYERS: - pipeline->n_layers = authority->n_layers; - pipeline->layer_differences = NULL; - break; - case COGL_PIPELINE_STATE_LIGHTING: - { - memcpy (&pipeline->big_state->lighting_state, - &authority->big_state->lighting_state, - sizeof (CoglPipelineLightingState)); - break; - } - case COGL_PIPELINE_STATE_BLEND: - { - memcpy (&pipeline->big_state->blend_state, - &authority->big_state->blend_state, - sizeof (CoglPipelineBlendState)); - break; - } - case COGL_PIPELINE_STATE_DEPTH: - { - memcpy (&pipeline->big_state->depth_state, - &authority->big_state->depth_state, - sizeof (CoglPipelineDepthState)); - break; - } - case COGL_PIPELINE_STATE_FOG: - { - memcpy (&pipeline->big_state->fog_state, - &authority->big_state->fog_state, - sizeof (CoglPipelineFogState)); - break; - } - } -} - -static gboolean -check_if_strong_cb (CoglPipelineNode *node, void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - gboolean *has_strong_child = user_data; - - if (!_cogl_pipeline_is_weak (pipeline)) - { - *has_strong_child = TRUE; - return FALSE; - } - - return TRUE; -} - -static gboolean -has_strong_children (CoglPipeline *pipeline) -{ - gboolean has_strong_child = FALSE; - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (pipeline), - check_if_strong_cb, - &has_strong_child); - return has_strong_child; -} - -static gboolean -_cogl_pipeline_is_weak (CoglPipeline *pipeline) -{ - if (pipeline->is_weak && !has_strong_children (pipeline)) - return TRUE; - else - return FALSE; -} - -static gboolean -reparent_children_cb (CoglPipelineNode *node, - void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - CoglPipeline *parent = user_data; - - _cogl_pipeline_set_parent (pipeline, parent, TRUE); - - return TRUE; -} - -static void -_cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color, - gboolean from_layer_change) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If primitives have been logged in the journal referencing the - * current state of this pipeline we need to flush the journal - * before we can modify it... */ - if (pipeline->journal_ref_count) - { - gboolean skip_journal_flush = FALSE; - - /* XXX: We don't usually need to flush the journal just due to - * color changes since pipeline colors are logged in the - * journal's vertex buffer. The exception is when the change in - * color enables or disables the need for blending. */ - if (change == COGL_PIPELINE_STATE_COLOR) - { - gboolean will_need_blending = - _cogl_pipeline_needs_blending_enabled (pipeline, - change, - new_color); - gboolean blend_enable = pipeline->real_blend_enable ? TRUE : FALSE; - - if (will_need_blending == blend_enable) - skip_journal_flush = TRUE; - } - - if (!skip_journal_flush) - { - /* XXX: note we use cogl_flush() not _cogl_flush_journal() so - * we will flush *all* known journals that might reference the - * current pipeline. */ - cogl_flush (); - } - } - - /* The fixed function backend has no private state and can't - * do anything special to handle small pipeline changes so we may as - * well try to find a better backend whenever the pipeline changes. - * - * The programmable backends may be able to cache a lot of the code - * they generate and only need to update a small section of that - * code in response to a pipeline change therefore we don't want to - * try searching for another backend when the pipeline changes. - */ -#ifdef COGL_PIPELINE_FRAGEND_FIXED - if (pipeline->fragend == COGL_PIPELINE_FRAGEND_FIXED) - _cogl_pipeline_set_fragend (pipeline, COGL_PIPELINE_FRAGEND_UNDEFINED); -#endif -#ifdef COGL_PIPELINE_VERTEND_FIXED - if (pipeline->vertend == COGL_PIPELINE_VERTEND_FIXED) - _cogl_pipeline_set_vertend (pipeline, COGL_PIPELINE_VERTEND_UNDEFINED); -#endif - - /* To simplify things for the backends we are careful about how - * we report STATE_LAYERS changes. - * - * All STATE_LAYERS changes with the exception of ->n_layers - * will also result in layer_pre_change_notifications. For - * backends that perform code generation for fragment processing - * they typically need to understand the details of how layers - * get changed to determine if they need to repeat codegen. It - * doesn't help them to report a pipeline STATE_LAYERS change - * for all layer changes since it's so broad, they really need - * to wait for the layer change to be notified. What does help - * though is to report a STATE_LAYERS change for a change in - * ->n_layers because they typically do need to repeat codegen - * in that case. - * - * This just ensures backends only get a single pipeline or - * layer pre-change notification for any particular change. - */ - if (pipeline->fragend != COGL_PIPELINE_FRAGEND_UNDEFINED && - _cogl_pipeline_fragends[pipeline->fragend]->pipeline_pre_change_notify) - { - const CoglPipelineFragend *fragend = - _cogl_pipeline_fragends[pipeline->fragend]; - - if (!from_layer_change) - fragend->pipeline_pre_change_notify (pipeline, change, new_color); - } - - if (pipeline->vertend != COGL_PIPELINE_VERTEND_UNDEFINED && - _cogl_pipeline_vertends[pipeline->vertend]->pipeline_pre_change_notify) - { - const CoglPipelineVertend *vertend = - _cogl_pipeline_vertends[pipeline->vertend]; - - /* To simplify things for the backends we are careful about how - * we report STATE_LAYERS changes. - * - * All STATE_LAYERS changes with the exception of ->n_layers - * will also result in layer_pre_change_notifications. For - * backends that perform code generation for fragment processing - * they typically need to understand the details of how layers - * get changed to determine if they need to repeat codegen. It - * doesn't help them to report a pipeline STATE_LAYERS change - * for all layer changes since it's so broad, they really need - * to wait for the layer change to be notified. What does help - * though is to report a STATE_LAYERS change for a change in - * ->n_layers because they typically do need to repeat codegen - * in that case. - * - * This just ensures backends only get a single pipeline or - * layer pre-change notification for any particular change. - */ - if (!from_layer_change) - vertend->pipeline_pre_change_notify (pipeline, change, new_color); - } - - /* Notify all of the progends */ - if (!from_layer_change) - for (i = 0; i < COGL_PIPELINE_N_PROGENDS; i++) - if (_cogl_pipeline_progends[i]->pipeline_pre_change_notify) - _cogl_pipeline_progends[i]->pipeline_pre_change_notify (pipeline, - change, - new_color); - - /* There may be an arbitrary tree of descendants of this pipeline; - * any of which may indirectly depend on this pipeline as the - * authority for some set of properties. (Meaning for example that - * one of its descendants derives its color or blending state from - * this pipeline.) - * - * We can't modify any property that this pipeline is the authority - * for unless we create another pipeline to take its place first and - * make sure descendants reference this new pipeline instead. - */ - - /* The simplest descendants to handle are weak pipelines; we simply - * destroy them if we are modifying a pipeline they depend on. This - * means weak pipelines never cause us to do a copy-on-write. */ - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - /* If there are still children remaining though we'll need to - * perform a copy-on-write and reparent the dependants as children - * of the copy. */ - if (COGL_PIPELINE_NODE (pipeline)->has_children) - { - CoglPipeline *new_authority; - - COGL_STATIC_COUNTER (pipeline_copy_on_write_counter, - "pipeline copy on write counter", - "Increments each time a pipeline " - "must be copied to allow modification", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, pipeline_copy_on_write_counter); - - new_authority = - cogl_pipeline_copy (_cogl_pipeline_get_parent (pipeline)); - _cogl_pipeline_set_static_breadcrumb (new_authority, - "pre_change_notify:copy-on-write"); - - /* We could explicitly walk the descendants, OR together the set - * of differences that we determine this pipeline is the - * authority on and only copy those differences copied across. - * - * Or, if we don't explicitly walk the descendants we at least - * know that pipeline->differences represents the largest set of - * differences that this pipeline could possibly be an authority - * on. - * - * We do the later just because it's simplest, but we might need - * to come back to this later... - */ - _cogl_pipeline_copy_differences (new_authority, pipeline, - pipeline->differences); - - /* Reparent the dependants of pipeline to be children of - * new_authority instead... */ - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (pipeline), - reparent_children_cb, - new_authority); - - /* The children will keep the new authority alive so drop the - * reference we got when copying... */ - cogl_object_unref (new_authority); - } - - /* At this point we know we have a pipeline with no strong - * dependants (though we may have some weak children) so we are now - * free to modify the pipeline. */ - - pipeline->age++; - - if (change & COGL_PIPELINE_STATE_NEEDS_BIG_STATE && - !pipeline->has_big_state) - { - pipeline->big_state = g_slice_new (CoglPipelineBigState); - pipeline->has_big_state = TRUE; - } - - /* Note: conceptually we have just been notified that a single - * property value is about to change, but since some state-groups - * contain multiple properties and 'pipeline' is about to take over - * being the authority for the property's corresponding state-group - * we need to maintain the integrity of the other property values - * too. - * - * To ensure this we handle multi-property state-groups by copying - * all the values from the old-authority to the new... - * - * We don't have to worry about non-sparse property groups since - * we never take over being an authority for such properties so - * they automatically maintain integrity. - */ - if (change & COGL_PIPELINE_STATE_ALL_SPARSE && - !(pipeline->differences & change)) - { - _cogl_pipeline_init_multi_property_sparse_state (pipeline, change); - pipeline->differences |= change; - } - - /* Each pipeline has a sorted cache of the layers it depends on - * which will need updating via _cogl_pipeline_update_layers_cache - * if a pipeline's layers are changed. */ - if (change == COGL_PIPELINE_STATE_LAYERS) - recursively_free_layer_caches (pipeline); - - /* If the pipeline being changed is the same as the last pipeline we - * flushed then we keep a track of the changes so we can try to - * minimize redundant OpenGL calls if the same pipeline is flushed - * again. - */ - if (ctx->current_pipeline == pipeline) - ctx->current_pipeline_changes_since_flush |= change; -} - - -static void -_cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean inc_n_layers) -{ - g_return_if_fail (layer->owner == NULL); - - layer->owner = pipeline; - cogl_object_ref (layer); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - FALSE); - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - - pipeline->layer_differences = - g_list_prepend (pipeline->layer_differences, layer); - - if (inc_n_layers) - pipeline->n_layers++; -} - -/* NB: If you are calling this it's your responsibility to have - * already called: - * _cogl_pipeline_pre_change_notify (m, _CHANGE_LAYERS, NULL); - */ -static void -_cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean dec_n_layers) -{ - g_return_if_fail (layer->owner == pipeline); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - FALSE); - - layer->owner = NULL; - cogl_object_unref (layer); - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - - pipeline->layer_differences = - g_list_remove (pipeline->layer_differences, layer); - - if (dec_n_layers) - pipeline->n_layers--; -} - -static void -_cogl_pipeline_try_reverting_layers_authority (CoglPipeline *authority, - CoglPipeline *old_authority) -{ - if (authority->layer_differences == NULL && - _cogl_pipeline_get_parent (authority)) - { - /* If the previous _STATE_LAYERS authority has the same - * ->n_layers then we can revert to that being the authority - * again. */ - if (!old_authority) - { - old_authority = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority), - COGL_PIPELINE_STATE_LAYERS); - } - - if (old_authority->n_layers == authority->n_layers) - authority->differences &= ~COGL_PIPELINE_STATE_LAYERS; - } -} - - -static void -handle_automatic_blend_enable (CoglPipeline *pipeline, - CoglPipelineState change) -{ - gboolean blend_enable = - _cogl_pipeline_needs_blending_enabled (pipeline, change, NULL); - - if (blend_enable != pipeline->real_blend_enable) - { - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be - * modified. - * - If the pipeline isn't currently an authority for the state - * being changed, then initialize that state from the current - * authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_REAL_BLEND_ENABLE, - NULL, - FALSE); - pipeline->real_blend_enable = blend_enable; - } -} - -typedef struct -{ - int keep_n; - int current_pos; - gboolean needs_pruning; - int first_index_to_prune; -} CoglPipelinePruneLayersInfo; - -static gboolean -update_prune_layers_info_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelinePruneLayersInfo *state = user_data; - - if (state->current_pos == state->keep_n) - { - state->needs_pruning = TRUE; - state->first_index_to_prune = layer->index; - return FALSE; - } - state->current_pos++; - return TRUE; -} - -void -_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n) -{ - CoglPipelinePruneLayersInfo state; - gboolean notified_change = TRUE; - GList *l; - GList *next; - - state.keep_n = n; - state.current_pos = 0; - state.needs_pruning = FALSE; - _cogl_pipeline_foreach_layer_internal (pipeline, - update_prune_layers_info_cb, - &state); - - pipeline->n_layers = n; - - if (!state.needs_pruning) - return; - - if (!(pipeline->differences & COGL_PIPELINE_STATE_LAYERS)) - return; - - /* It's possible that this pipeline owns some of the layers being - * discarded, so we'll need to unlink them... */ - for (l = pipeline->layer_differences; l; l = next) - { - CoglPipelineLayer *layer = l->data; - next = l->next; /* we're modifying the list we're iterating */ - - if (layer->index > state.first_index_to_prune) - { - if (!notified_change) - { - /* - Flush journal primitives referencing the current - * state. - * - Make sure the pipeline has no dependants so it may - * be modified. - * - If the pipeline isn't currently an authority for - * the state being changed, then initialize that state - * from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - FALSE); - notified_change = TRUE; - } - - pipeline->layer_differences = - g_list_delete_link (pipeline->layer_differences, l); - } - } -} - -static void -_cogl_pipeline_fragend_layer_change_notify (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - /* NB: Although layers can have private state associated with them - * by multiple backends we know that a layer can't be *changed* if - * it has multiple dependants so if we reach here we know we only - * have a single owner and can only be associated with a single - * backend that needs to be notified of the layer change... - */ - if (owner->fragend != COGL_PIPELINE_FRAGEND_UNDEFINED && - _cogl_pipeline_fragends[owner->fragend]->layer_pre_change_notify) - { - const CoglPipelineFragend *fragend = - _cogl_pipeline_fragends[owner->fragend]; - fragend->layer_pre_change_notify (owner, layer, change); - } -} - -static void -_cogl_pipeline_vertend_layer_change_notify (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - /* NB: The comment in fragend_layer_change_notify applies here too */ - if (owner->vertend != COGL_PIPELINE_VERTEND_UNDEFINED && - _cogl_pipeline_vertends[owner->vertend]->layer_pre_change_notify) - { - const CoglPipelineVertend *vertend = - _cogl_pipeline_vertends[owner->vertend]; - vertend->layer_pre_change_notify (owner, layer, change); - } -} - -static void -_cogl_pipeline_progend_layer_change_notify (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - int i; - - /* Give all of the progends a chance to notice that the layer has - changed */ - for (i = 0; i < COGL_PIPELINE_N_PROGENDS; i++) - if (_cogl_pipeline_progends[i]->layer_pre_change_notify) - _cogl_pipeline_progends[i]->layer_pre_change_notify (owner, - layer, - change); -} - -unsigned int -_cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func) -{ - switch (func) - { - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - return 1; - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - case COGL_PIPELINE_COMBINE_FUNC_ADD: - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - return 2; - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - return 3; - } - return 0; -} - -static void -_cogl_pipeline_layer_init_multi_property_sparse_state ( - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineLayer *authority; - - /* Nothing to initialize in these cases since they are all comprised - * of one member which we expect to immediately be overwritten. */ - if (!(change & COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY)) - return; - - authority = _cogl_pipeline_layer_get_authority (layer, change); - - switch (change) - { - /* XXX: avoid using a default: label so we get a warning if we - * don't explicitly handle a newly defined state-group here. */ - case COGL_PIPELINE_LAYER_STATE_UNIT: - case COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET: - case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA: - case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS: - case COGL_PIPELINE_LAYER_STATE_USER_MATRIX: - case COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT: - g_return_if_reached (); - - /* XXX: technically we could probably even consider these as - * single property state-groups from the pov that currently the - * corresponding property setters always update all of the values - * at the same time. */ - case COGL_PIPELINE_LAYER_STATE_FILTERS: - layer->min_filter = authority->min_filter; - layer->mag_filter = authority->mag_filter; - break; - case COGL_PIPELINE_LAYER_STATE_WRAP_MODES: - layer->wrap_mode_s = authority->wrap_mode_s; - layer->wrap_mode_t = authority->wrap_mode_t; - layer->wrap_mode_p = authority->wrap_mode_p; - break; - case COGL_PIPELINE_LAYER_STATE_COMBINE: - { - int n_args; - int i; - CoglPipelineLayerBigState *src_big_state = authority->big_state; - CoglPipelineLayerBigState *dest_big_state = layer->big_state; - GLint func = src_big_state->texture_combine_rgb_func; - - dest_big_state->texture_combine_rgb_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - dest_big_state->texture_combine_rgb_src[i] = - src_big_state->texture_combine_rgb_src[i]; - dest_big_state->texture_combine_rgb_op[i] = - src_big_state->texture_combine_rgb_op[i]; - } - - func = src_big_state->texture_combine_alpha_func; - dest_big_state->texture_combine_alpha_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - dest_big_state->texture_combine_alpha_src[i] = - src_big_state->texture_combine_alpha_src[i]; - dest_big_state->texture_combine_alpha_op[i] = - src_big_state->texture_combine_alpha_op[i]; - } - break; - } - } -} - -/* NB: This function will allocate a new derived layer if you are - * trying to change the state of a layer with dependants so you must - * always check the return value. - * - * If a new layer is returned it will be owned by required_owner. - * - * required_owner can only by NULL for new, currently unowned layers - * with no dependants. - */ -static CoglPipelineLayer * -_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglTextureUnit *unit; - - /* Identify the case where the layer is new with no owner or - * dependants and so we don't need to do anything. */ - if (COGL_PIPELINE_NODE (layer)->has_children == FALSE && - layer->owner == NULL) - goto init_layer_state; - - /* We only allow a NULL required_owner for new layers */ - g_return_val_if_fail (required_owner != NULL, layer); - - /* Chain up: - * A modification of a layer is indirectly also a modification of - * its owner so first make sure to flush the journal of any - * references to the current owner state and if necessary perform - * a copy-on-write for the required_owner if it has dependants. - */ - _cogl_pipeline_pre_change_notify (required_owner, - COGL_PIPELINE_STATE_LAYERS, - NULL, - TRUE); - - /* Unlike pipelines; layers are simply considered immutable once - * they have dependants - either direct children, or another - * pipeline as an owner. - */ - if (COGL_PIPELINE_NODE (layer)->has_children || - layer->owner != required_owner) - { - CoglPipelineLayer *new = _cogl_pipeline_layer_copy (layer); - if (layer->owner == required_owner) - _cogl_pipeline_remove_layer_difference (required_owner, layer, FALSE); - _cogl_pipeline_add_layer_difference (required_owner, new, FALSE); - cogl_object_unref (new); - layer = new; - goto init_layer_state; - } - - /* Note: At this point we know there is only one pipeline dependant on - * this layer (required_owner), and there are no other layers - * dependant on this layer so it's ok to modify it. */ - - _cogl_pipeline_fragend_layer_change_notify (required_owner, layer, change); - _cogl_pipeline_vertend_layer_change_notify (required_owner, layer, change); - _cogl_pipeline_progend_layer_change_notify (required_owner, layer, change); - - /* If the layer being changed is the same as the last layer we - * flushed to the corresponding texture unit then we keep a track of - * the changes so we can try to minimize redundant OpenGL calls if - * the same layer is flushed again. - */ - unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer)); - if (unit->layer == layer) - unit->layer_changes_since_flush |= change; - -init_layer_state: - - if (required_owner) - required_owner->age++; - - if (change & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE && - !layer->has_big_state) - { - layer->big_state = g_slice_new (CoglPipelineLayerBigState); - layer->has_big_state = TRUE; - } - - /* Note: conceptually we have just been notified that a single - * property value is about to change, but since some state-groups - * contain multiple properties and 'layer' is about to take over - * being the authority for the property's corresponding state-group - * we need to maintain the integrity of the other property values - * too. - * - * To ensure this we handle multi-property state-groups by copying - * all the values from the old-authority to the new... - * - * We don't have to worry about non-sparse property groups since - * we never take over being an authority for such properties so - * they automatically maintain integrity. - */ - if (change & COGL_PIPELINE_LAYER_STATE_ALL_SPARSE && - !(layer->differences & change)) - { - _cogl_pipeline_layer_init_multi_property_sparse_state (layer, change); - layer->differences |= change; - } - - return layer; -} - -static void -_cogl_pipeline_layer_unparent (CoglPipelineNode *layer) -{ - /* Chain up */ - _cogl_pipeline_node_unparent_real (layer); -} - -static void -_cogl_pipeline_layer_set_parent (CoglPipelineLayer *layer, - CoglPipelineLayer *parent) -{ - /* Chain up */ - _cogl_pipeline_node_set_parent_real (COGL_PIPELINE_NODE (layer), - COGL_PIPELINE_NODE (parent), - _cogl_pipeline_layer_unparent, - TRUE); -} - -/* XXX: This is duplicated logic; the same as for - * _cogl_pipeline_prune_redundant_ancestry it would be nice to find a - * way to consolidate these functions! */ -static void -_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *new_parent = _cogl_pipeline_layer_get_parent (layer); - - /* walk up past ancestors that are now redundant and potentially - * reparent the layer. */ - while (_cogl_pipeline_layer_get_parent (new_parent) && - (new_parent->differences | layer->differences) == - layer->differences) - new_parent = _cogl_pipeline_layer_get_parent (new_parent); - - _cogl_pipeline_layer_set_parent (layer, new_parent); -} - -/* - * XXX: consider special casing layer->unit_index so it's not a sparse - * property so instead we can assume it's valid for all layer - * instances. - * - We would need to initialize ->unit_index in - * _cogl_pipeline_layer_copy (). - * - * XXX: If you use this API you should consider that the given layer - * might not be writeable and so a new derived layer will be allocated - * and modified instead. The layer modified will be returned so you - * can identify when this happens. - */ -static CoglPipelineLayer * -_cogl_pipeline_set_layer_unit (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - int unit_index) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_UNIT; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, change); - CoglPipelineLayer *new; - - if (authority->unit_index == unit_index) - return layer; - - new = - _cogl_pipeline_layer_pre_change_notify (required_owner, - layer, - change); - if (new != layer) - layer = new; - else - { - /* If the layer we found is currently the authority on the state - * we are changing see if we can revert to one of our ancestors - * being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->unit_index == unit_index) - { - layer->differences &= ~change; - return layer; - } - } - } - - layer->unit_index = unit_index; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - - return layer; -} - -typedef struct -{ - /* The layer we are trying to find */ - int layer_index; - - /* The layer we find or untouched if not found */ - CoglPipelineLayer *layer; - - /* If the layer can't be found then a new layer should be - * inserted after this texture unit index... */ - int insert_after; - - /* When adding a layer we need the list of layers to shift up - * to a new texture unit. When removing we need the list of - * layers to shift down. - * - * Note: the list isn't sorted */ - CoglPipelineLayer **layers_to_shift; - int n_layers_to_shift; - - /* When adding a layer we don't need a complete list of - * layers_to_shift if we find a layer already corresponding to the - * layer_index. */ - gboolean ignore_shift_layers_if_found; - -} CoglPipelineLayerInfo; - -/* Returns TRUE once we know there is nothing more to update */ -static gboolean -update_layer_info (CoglPipelineLayer *layer, - CoglPipelineLayerInfo *layer_info) -{ - if (layer->index == layer_info->layer_index) - { - layer_info->layer = layer; - if (layer_info->ignore_shift_layers_if_found) - return TRUE; - } - else if (layer->index < layer_info->layer_index) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - layer_info->insert_after = unit_index; - } - else - layer_info->layers_to_shift[layer_info->n_layers_to_shift++] = - layer; - - return FALSE; -} - -/* Returns FALSE to break out of a _foreach_layer () iteration */ -static gboolean -update_layer_info_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineLayerInfo *layer_info = user_data; - - if (update_layer_info (layer, layer_info)) - return FALSE; /* break */ - else - return TRUE; /* continue */ -} - -static void -_cogl_pipeline_get_layer_info (CoglPipeline *pipeline, - CoglPipelineLayerInfo *layer_info) -{ - /* Note: we are assuming this pipeline is a _STATE_LAYERS authority */ - int n_layers = pipeline->n_layers; - int i; - - /* FIXME: _cogl_pipeline_foreach_layer_internal now calls - * _cogl_pipeline_update_layers_cache anyway so this codepath is - * pointless! */ - if (layer_info->ignore_shift_layers_if_found && - pipeline->layers_cache_dirty) - { - /* The expectation is that callers of - * _cogl_pipeline_get_layer_info are likely to be modifying the - * list of layers associated with a pipeline so in this case - * where we don't have a cache of the layers and we don't - * necessarily have to iterate all the layers of the pipeline we - * use a foreach_layer callback instead of updating the cache - * and iterating that as below. */ - _cogl_pipeline_foreach_layer_internal (pipeline, - update_layer_info_cb, - layer_info); - return; - } - - _cogl_pipeline_update_layers_cache (pipeline); - for (i = 0; i < n_layers; i++) - { - CoglPipelineLayer *layer = pipeline->layers_cache[i]; - - if (update_layer_info (layer, layer_info)) - return; - } -} - -static CoglPipelineLayer * -_cogl_pipeline_get_layer (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - CoglPipelineLayerInfo layer_info; - CoglPipelineLayer *layer; - int unit_index; - int i; - - _COGL_GET_CONTEXT (ctx, NULL); - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer_index; - - /* If a layer already exists with the given index this will be - * updated. */ - layer_info.layer = NULL; - - /* If a layer isn't found for the given index we'll need to know - * where to insert a new layer. */ - layer_info.insert_after = -1; - - /* If a layer can't be found then we'll need to insert a new layer - * and bump up the texture unit for all layers with an index - * > layer_index. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* If an exact match is found though we don't need a complete - * list of layers with indices > layer_index... */ - layer_info.ignore_shift_layers_if_found = TRUE; - - _cogl_pipeline_get_layer_info (authority, &layer_info); - - if (layer_info.layer) - return layer_info.layer; - - unit_index = layer_info.insert_after + 1; - if (unit_index == 0) - layer = _cogl_pipeline_layer_copy (ctx->default_layer_0); - else - { - CoglPipelineLayer *new; - layer = _cogl_pipeline_layer_copy (ctx->default_layer_n); - new = _cogl_pipeline_set_layer_unit (NULL, layer, unit_index); - /* Since we passed a newly allocated layer we wouldn't expect - * _set_layer_unit() to have to allocate *another* layer. */ - g_assert (new == layer); - } - layer->index = layer_index; - - for (i = 0; i < layer_info.n_layers_to_shift; i++) - { - CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i]; - - unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer); - _cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index + 1); - /* NB: shift_layer may not be writeable so _set_layer_unit() - * will allocate a derived layer internally which will become - * owned by pipeline. Check the return value if we need to do - * anything else with this layer. */ - } - - _cogl_pipeline_add_layer_difference (pipeline, layer, TRUE); - - cogl_object_unref (layer); - - return layer; -} - -CoglHandle -_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - - return authority->texture; -} - -CoglHandle -_cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayer *layer = - _cogl_pipeline_get_layer (pipeline, layer_index); - return _cogl_pipeline_layer_get_texture (layer); -} - -static void -_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority, - CoglPipelineLayer *layer) -{ - /* Find the GList link that references the empty layer */ - GList *link = g_list_find (layers_authority->layer_differences, layer); - /* No pipeline directly owns the root node layer so this is safe... */ - CoglPipelineLayer *layer_parent = _cogl_pipeline_layer_get_parent (layer); - CoglPipelineLayerInfo layer_info; - CoglPipeline *old_layers_authority; - - g_return_if_fail (link != NULL); - - /* If the layer's parent doesn't have an owner then we can simply - * take ownership ourselves and drop our reference on the empty - * layer. We don't want to take ownership of the root node layer so - * we also need to verify that the parent has a parent - */ - if (layer_parent->index == layer->index && layer_parent->owner == NULL && - _cogl_pipeline_layer_get_parent (layer_parent) != NULL) - { - cogl_object_ref (layer_parent); - layer_parent->owner = layers_authority; - link->data = layer_parent; - cogl_object_unref (layer); - recursively_free_layer_caches (layers_authority); - return; - } - - /* Now we want to find the layer that would become the authority for - * layer->index if we were to remove layer from - * layers_authority->layer_differences - */ - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer->index; - - /* If a layer already exists with the given index this will be - * updated. */ - layer_info.layer = NULL; - - /* If a layer can't be found then we'll need to insert a new layer - * and bump up the texture unit for all layers with an index - * > layer_index. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * layers_authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* If an exact match is found though we don't need a complete - * list of layers with indices > layer_index... */ - layer_info.ignore_shift_layers_if_found = TRUE; - - /* We know the default/root pipeline isn't a LAYERS authority so it's - * safe to use the result of _cogl_pipeline_get_parent (layers_authority) - * without checking it. - */ - old_layers_authority = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (layers_authority), - COGL_PIPELINE_STATE_LAYERS); - - _cogl_pipeline_get_layer_info (old_layers_authority, &layer_info); - - /* If layer is the defining layer for the corresponding ->index then - * we can't get rid of it. */ - if (!layer_info.layer) - return; - - /* If the layer that would become the authority for layer->index is - * _cogl_pipeline_layer_get_parent (layer) then we can simply remove the - * layer difference. */ - if (layer_info.layer == _cogl_pipeline_layer_get_parent (layer)) - { - _cogl_pipeline_remove_layer_difference (layers_authority, layer, FALSE); - _cogl_pipeline_try_reverting_layers_authority (layers_authority, - old_layers_authority); - } -} - -static void -_cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline, - int layer_index, - GLenum target) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (target == authority->target) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->target == target) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - layer->target = target; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - handle_automatic_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS); -} - -static void -_cogl_pipeline_set_layer_texture_data (CoglPipeline *pipeline, - int layer_index, - CoglHandle texture) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (authority->texture == texture) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->texture == texture) - { - layer->differences &= ~change; - - if (layer->texture != COGL_INVALID_HANDLE) - cogl_handle_unref (layer->texture); - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - if (texture != COGL_INVALID_HANDLE) - cogl_handle_ref (texture); - if (layer == authority && - layer->texture != COGL_INVALID_HANDLE) - cogl_handle_unref (layer->texture); - layer->texture = texture; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - handle_automatic_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS); -} - -/* A convenience for querying the target of a given texture that - * notably returns 0 for NULL textures - so we can say that a layer - * with no associated CoglTexture will have a texture target of 0. - */ -static GLenum -get_texture_target (CoglHandle texture) -{ - GLuint ignore_handle; - GLenum gl_target; - - if (texture) - cogl_texture_get_gl_texture (texture, &ignore_handle, &gl_target); - else - return 0;/* XXX: An invalid GL target enum */ - - return gl_target; -} - -void -cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, - int layer_index, - CoglHandle texture) -{ - /* For the convenience of fragend code we separate texture state - * into the "target" and the "data", and setting a layer texture - * updates both of these properties. - * - * One example for why this is helpful is that the fragends may - * cache programs they generate and want to re-use those programs - * with all pipelines having equivalent fragment processing state. - * For the sake of determining if pipelines have equivalent fragment - * processing state we don't need to compare that the same - * underlying texture objects are referenced by the pipelines but we - * do need to see if they use the same texture targets. Making this - * distinction is much simpler if they are in different state - * groups. - */ - _cogl_pipeline_set_layer_texture_target (pipeline, layer_index, - get_texture_target (texture)); - _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture); -} - -typedef struct -{ - int i; - CoglPipeline *pipeline; - unsigned long fallback_layers; -} CoglPipelineFallbackState; - -static gboolean -fallback_layer_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineFallbackState *state = user_data; - CoglPipeline *pipeline = state->pipeline; - CoglHandle texture = _cogl_pipeline_layer_get_texture (layer); - GLenum gl_target; - COGL_STATIC_COUNTER (layer_fallback_counter, - "layer fallback counter", - "Increments each time a layer's texture is " - "forced to a fallback texture", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!(state->fallback_layers & 1<i)) - return TRUE; - - COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter); - - if (G_LIKELY (texture != COGL_INVALID_HANDLE)) - cogl_texture_get_gl_texture (texture, NULL, &gl_target); - else - gl_target = GL_TEXTURE_2D; - - if (gl_target == GL_TEXTURE_2D) - texture = ctx->default_gl_texture_2d_tex; -#ifdef HAVE_COGL_GL - else if (gl_target == GL_TEXTURE_RECTANGLE_ARB) - texture = ctx->default_gl_texture_rect_tex; -#endif - else - { - g_warning ("We don't have a fallback texture we can use to fill " - "in for an invalid pipeline layer, since it was " - "using an unsupported texture target "); - /* might get away with this... */ - texture = ctx->default_gl_texture_2d_tex; - } - - cogl_pipeline_set_layer_texture (pipeline, layer->index, texture); - - state->i++; - - return TRUE; -} - -void -_cogl_pipeline_set_layer_wrap_modes (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - CoglPipelineLayer *authority, - CoglPipelineWrapModeInternal wrap_mode_s, - CoglPipelineWrapModeInternal wrap_mode_t, - CoglPipelineWrapModeInternal wrap_mode_p) -{ - CoglPipelineLayer *new; - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - - if (authority->wrap_mode_s == wrap_mode_s && - authority->wrap_mode_t == wrap_mode_t && - authority->wrap_mode_p == wrap_mode_p) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->wrap_mode_s == wrap_mode_s && - old_authority->wrap_mode_t == wrap_mode_t && - old_authority->wrap_mode_p == wrap_mode_p) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return; - } - } - } - - layer->wrap_mode_s = wrap_mode_s; - layer->wrap_mode_t = wrap_mode_t; - layer->wrap_mode_p = wrap_mode_p; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -static CoglPipelineWrapModeInternal -public_to_internal_wrap_mode (CoglPipelineWrapMode mode) -{ - return (CoglPipelineWrapModeInternal)mode; -} - -static CoglPipelineWrapMode -internal_to_public_wrap_mode (CoglPipelineWrapModeInternal internal_mode) -{ - g_return_val_if_fail (internal_mode != - COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC); - return (CoglPipelineWrapMode)internal_mode; -} - -void -cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineWrapModeInternal internal_mode = - public_to_internal_wrap_mode (mode); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - _cogl_pipeline_set_layer_wrap_modes (pipeline, layer, authority, - internal_mode, - authority->wrap_mode_t, - authority->wrap_mode_p); -} - -void -cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineWrapModeInternal internal_mode = - public_to_internal_wrap_mode (mode); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - _cogl_pipeline_set_layer_wrap_modes (pipeline, layer, authority, - authority->wrap_mode_s, - internal_mode, - authority->wrap_mode_p); -} - -/* The rationale for naming the third texture coordinate 'p' instead - of OpenGL's usual 'r' is that 'r' conflicts with the usual naming - of the 'red' component when treating a vector as a color. Under - GLSL this is awkward because the texture swizzling for a vector - uses a single letter for each component and the names for colors, - textures and positions are synonymous. GLSL works around this by - naming the components of the texture s, t, p and q. Cogl already - effectively already exposes this naming because it exposes GLSL so - it makes sense to use that naming consistently. Another alternative - could be u, v and w. This is what Blender and Direct3D use. However - the w component conflicts with the w component of a position - vertex. */ -void -cogl_pipeline_set_layer_wrap_mode_p (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineWrapModeInternal internal_mode = - public_to_internal_wrap_mode (mode); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - _cogl_pipeline_set_layer_wrap_modes (pipeline, layer, authority, - authority->wrap_mode_s, - authority->wrap_mode_t, - internal_mode); -} - -void -cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineWrapModeInternal internal_mode = - public_to_internal_wrap_mode (mode); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - _cogl_pipeline_set_layer_wrap_modes (pipeline, layer, authority, - internal_mode, - internal_mode, - internal_mode); - /* XXX: I wonder if we should really be duplicating the mode into - * the 'r' wrap mode too? */ -} - -/* FIXME: deprecate this API */ -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - CoglPipelineLayer *authority; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), FALSE); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - return internal_to_public_wrap_mode (authority->wrap_mode_s); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - return _cogl_pipeline_layer_get_wrap_mode_s (layer); -} - -/* FIXME: deprecate this API */ -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - CoglPipelineLayer *authority; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), FALSE); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - return internal_to_public_wrap_mode (authority->wrap_mode_t); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - return _cogl_pipeline_layer_get_wrap_mode_t (layer); -} - -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_p (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_WRAP_MODES; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, change); - - return internal_to_public_wrap_mode (authority->wrap_mode_p); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_p (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - return _cogl_pipeline_layer_get_wrap_mode_p (layer); -} - -void -_cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, - CoglPipelineWrapModeInternal *wrap_mode_s, - CoglPipelineWrapModeInternal *wrap_mode_t, - CoglPipelineWrapModeInternal *wrap_mode_p) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_WRAP_MODES); - - *wrap_mode_s = authority->wrap_mode_s; - *wrap_mode_t = authority->wrap_mode_t; - *wrap_mode_p = authority->wrap_mode_p; -} - -gboolean -cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index, - gboolean enable, - GError **error) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *layer; - CoglPipelineLayer *new; - CoglPipelineLayer *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Don't allow point sprite coordinates to be enabled if the driver - doesn't support it */ - if (enable && !cogl_features_available (COGL_FEATURE_POINT_SPRITE)) - { - if (error) - { - g_set_error (error, COGL_ERROR, COGL_ERROR_UNSUPPORTED, - "Point sprite texture coordinates are enabled " - "for a layer but the GL driver does not support it."); - } - else - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("Point sprite texture coordinates are enabled " - "for a layer but the GL driver does not support it."); - warning_seen = TRUE; - } - - return FALSE; - } - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (authority->big_state->point_sprite_coords == enable) - return TRUE; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->big_state->point_sprite_coords == enable) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return TRUE; - } - } - } - - layer->big_state->point_sprite_coords = enable; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - - return TRUE; -} - -gboolean -cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - authority = _cogl_pipeline_layer_get_authority (layer, change); - - return authority->big_state->point_sprite_coords; -} - -typedef struct -{ - CoglPipeline *pipeline; - CoglHandle texture; -} CoglPipelineOverrideLayerState; - -static gboolean -override_layer_texture_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineOverrideLayerState *state = user_data; - - cogl_pipeline_set_layer_texture (state->pipeline, - layer->index, - state->texture); - - return TRUE; -} - -void -_cogl_pipeline_apply_overrides (CoglPipeline *pipeline, - CoglPipelineFlushOptions *options) -{ - COGL_STATIC_COUNTER (apply_overrides_counter, - "pipeline overrides counter", - "Increments each time we have to apply " - "override options to a pipeline", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, apply_overrides_counter); - - if (options->flags & COGL_PIPELINE_FLUSH_DISABLE_MASK) - { - int i; - - /* NB: we can assume that once we see one bit to disable - * a layer, all subsequent layers are also disabled. */ - for (i = 0; i < 32 && options->disable_layers & (1<flags & COGL_PIPELINE_FLUSH_FALLBACK_MASK) - { - CoglPipelineFallbackState state; - - state.i = 0; - state.pipeline = pipeline; - state.fallback_layers = options->fallback_layers; - - _cogl_pipeline_foreach_layer_internal (pipeline, - fallback_layer_cb, - &state); - } - - if (options->flags & COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE) - { - CoglPipelineOverrideLayerState state; - - _cogl_pipeline_prune_to_n_layers (pipeline, 1); - - /* NB: we are overriding the first layer, but we don't know - * the user's given layer_index, which is why we use - * _cogl_pipeline_foreach_layer_internal() here even though we know - * there's only one layer. */ - state.pipeline = pipeline; - state.texture = options->layer0_override_texture; - _cogl_pipeline_foreach_layer_internal (pipeline, - override_layer_texture_cb, - &state); - } -} - -static gboolean -_cogl_pipeline_layer_texture_target_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1, - CoglPipelineEvalFlags flags) -{ - return authority0->target == authority1->target; -} - -static gboolean -_cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1, - CoglPipelineEvalFlags flags) -{ - GLuint gl_handle0, gl_handle1; - - cogl_texture_get_gl_texture (authority0->texture, &gl_handle0, NULL); - cogl_texture_get_gl_texture (authority1->texture, &gl_handle1, NULL); - - return gl_handle0 == gl_handle1; -} - -/* Determine the mask of differences between two layers. - * - * XXX: If layers and pipelines could both be cast to a common Tree - * type of some kind then we could have a unified - * compare_differences() function. - */ -unsigned long -_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1) -{ - CoglPipelineLayer *node0; - CoglPipelineLayer *node1; - int len0; - int len1; - int len0_index; - int len1_index; - int count; - int i; - CoglPipelineLayer *common_ancestor = NULL; - unsigned long layers_difference = 0; - - _COGL_GET_CONTEXT (ctx, 0); - - /* Algorithm: - * - * 1) Walk the ancestors of each layer to the root node, adding a - * pointer to each ancester node to two GArrays: - * ctx->pipeline0_nodes, and ctx->pipeline1_nodes. - * - * 2) Compare the arrays to find the nodes where they stop to - * differ. - * - * 3) For each array now iterate from index 0 to the first node of - * difference ORing that nodes ->difference mask into the final - * pipeline_differences mask. - */ - - g_array_set_size (ctx->pipeline0_nodes, 0); - g_array_set_size (ctx->pipeline1_nodes, 0); - for (node0 = layer0; node0; node0 = _cogl_pipeline_layer_get_parent (node0)) - g_array_append_vals (ctx->pipeline0_nodes, &node0, 1); - for (node1 = layer1; node1; node1 = _cogl_pipeline_layer_get_parent (node1)) - g_array_append_vals (ctx->pipeline1_nodes, &node1, 1); - - len0 = ctx->pipeline0_nodes->len; - len1 = ctx->pipeline1_nodes->len; - /* There's no point looking at the last entries since we know both - * layers must have the same default layer as their root node. */ - len0_index = len0 - 2; - len1_index = len1 - 2; - count = MIN (len0, len1) - 1; - for (i = 0; i < count; i++) - { - node0 = g_array_index (ctx->pipeline0_nodes, - CoglPipelineLayer *, len0_index--); - node1 = g_array_index (ctx->pipeline1_nodes, - CoglPipelineLayer *, len1_index--); - if (node0 != node1) - { - common_ancestor = _cogl_pipeline_layer_get_parent (node0); - break; - } - } - - /* If we didn't already find the first the common_ancestor ancestor - * that's because one pipeline is a direct descendant of the other - * and in this case the first common ancestor is the last node we - * looked at. */ - if (!common_ancestor) - common_ancestor = node0; - - count = len0 - 1; - for (i = 0; i < count; i++) - { - node0 = g_array_index (ctx->pipeline0_nodes, CoglPipelineLayer *, i); - if (node0 == common_ancestor) - break; - layers_difference |= node0->differences; - } - - count = len1 - 1; - for (i = 0; i < count; i++) - { - node1 = g_array_index (ctx->pipeline1_nodes, CoglPipelineLayer *, i); - if (node1 == common_ancestor) - break; - layers_difference |= node1->differences; - } - - return layers_difference; -} - -static gboolean -_cogl_pipeline_layer_combine_state_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - int n_args; - int i; - - if (big_state0->texture_combine_rgb_func != - big_state1->texture_combine_rgb_func) - return FALSE; - - if (big_state0->texture_combine_alpha_func != - big_state1->texture_combine_alpha_func) - return FALSE; - - n_args = - _cogl_get_n_args_for_combine_func (big_state0->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - if ((big_state0->texture_combine_rgb_src[i] != - big_state1->texture_combine_rgb_src[i]) || - (big_state0->texture_combine_rgb_op[i] != - big_state1->texture_combine_rgb_op[i])) - return FALSE; - } - - n_args = - _cogl_get_n_args_for_combine_func (big_state0->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - if ((big_state0->texture_combine_alpha_src[i] != - big_state1->texture_combine_alpha_src[i]) || - (big_state0->texture_combine_alpha_op[i] != - big_state1->texture_combine_alpha_op[i])) - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_pipeline_layer_combine_constant_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - return memcmp (authority0->big_state->texture_combine_constant, - authority1->big_state->texture_combine_constant, - sizeof (float) * 4) == 0 ? TRUE : FALSE; -} - -static gboolean -_cogl_pipeline_layer_filters_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - if (authority0->mag_filter != authority1->mag_filter) - return FALSE; - if (authority0->min_filter != authority1->min_filter) - return FALSE; - - return TRUE; -} - -static gboolean -compare_wrap_mode_equal (CoglPipelineWrapMode wrap_mode0, - CoglPipelineWrapMode wrap_mode1) -{ - /* We consider AUTOMATIC to be equivalent to CLAMP_TO_EDGE because - the primitives code is expected to override this to something - else if it wants it to be behave any other way */ - if (wrap_mode0 == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_mode0 = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - if (wrap_mode1 == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_mode1 = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - - return wrap_mode0 == wrap_mode1; -} - -static gboolean -_cogl_pipeline_layer_wrap_modes_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - if (!compare_wrap_mode_equal (authority0->wrap_mode_s, - authority1->wrap_mode_s) || - !compare_wrap_mode_equal (authority0->wrap_mode_t, - authority1->wrap_mode_t) || - !compare_wrap_mode_equal (authority0->wrap_mode_p, - authority1->wrap_mode_p)) - return FALSE; - - return TRUE; -} - -static gboolean -_cogl_pipeline_layer_user_matrix_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - - if (!cogl_matrix_equal (&big_state0->matrix, &big_state1->matrix)) - return FALSE; - - return TRUE; -} - -static gboolean -_cogl_pipeline_layer_point_sprite_coords_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - - return big_state0->point_sprite_coords == big_state1->point_sprite_coords; -} - -typedef gboolean -(*CoglPipelineLayerStateComparitor) (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -static gboolean -layer_state_equal (CoglPipelineLayerStateIndex state_index, - CoglPipelineLayer **authorities0, - CoglPipelineLayer **authorities1, - CoglPipelineLayerStateComparitor comparitor) -{ - return comparitor (authorities0[state_index], authorities1[state_index]); -} - -static void -_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer, - unsigned long differences, - CoglPipelineLayer **authorities) -{ - unsigned long remaining = differences; - CoglPipelineLayer *authority = layer; - - do - { - unsigned long found = authority->differences & remaining; - int i; - - if (found == 0) - continue; - - for (i = 0; TRUE; i++) - { - unsigned long state = (1L< found) - break; - } - - remaining &= ~found; - if (remaining == 0) - return; - } - while ((authority = _cogl_pipeline_layer_get_parent (authority))); - - g_assert (remaining == 0); -} - -static gboolean -_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1, - unsigned long differences_mask, - CoglPipelineEvalFlags flags) -{ - unsigned long layers_difference; - CoglPipelineLayer *authorities0[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - CoglPipelineLayer *authorities1[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - - if (layer0 == layer1) - return TRUE; - - layers_difference = - _cogl_pipeline_layer_compare_differences (layer0, layer1); - - /* Only compare the sparse state groups requested by the caller... */ - layers_difference &= differences_mask; - - _cogl_pipeline_layer_resolve_authorities (layer0, - layers_difference, - authorities0); - _cogl_pipeline_layer_resolve_authorities (layer1, - layers_difference, - authorities1); - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET) - { - CoglPipelineLayerStateIndex state_index = - COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX; - if (!_cogl_pipeline_layer_texture_target_equal (authorities0[state_index], - authorities1[state_index], - flags)) - return FALSE; - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - CoglPipelineLayerStateIndex state_index = - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX; - if (!_cogl_pipeline_layer_texture_data_equal (authorities0[state_index], - authorities1[state_index], - flags)) - return FALSE; - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_combine_state_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_combine_constant_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_FILTERS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_filters_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_WRAP_MODES && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_wrap_modes_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_user_matrix_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_point_sprite_coords_equal)) - return FALSE; - - return TRUE; -} - -static gboolean -_cogl_pipeline_color_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return cogl_color_equal (&authority0->color, &authority1->color); -} - -static gboolean -_cogl_pipeline_lighting_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineLightingState *state0 = &authority0->big_state->lighting_state; - CoglPipelineLightingState *state1 = &authority1->big_state->lighting_state; - - if (memcmp (state0->ambient, state1->ambient, sizeof (float) * 4) != 0) - return FALSE; - if (memcmp (state0->diffuse, state1->diffuse, sizeof (float) * 4) != 0) - return FALSE; - if (memcmp (state0->specular, state1->specular, sizeof (float) * 4) != 0) - return FALSE; - if (memcmp (state0->emission, state1->emission, sizeof (float) * 4) != 0) - return FALSE; - if (state0->shininess != state1->shininess) - return FALSE; - - return TRUE; -} - -static gboolean -_cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineAlphaFuncState *alpha_state0 = - &authority0->big_state->alpha_state; - CoglPipelineAlphaFuncState *alpha_state1 = - &authority1->big_state->alpha_state; - - return alpha_state0->alpha_func == alpha_state1->alpha_func; -} - -static gboolean -_cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineAlphaFuncState *alpha_state0 = - &authority0->big_state->alpha_state; - CoglPipelineAlphaFuncState *alpha_state1 = - &authority1->big_state->alpha_state; - - return (alpha_state0->alpha_func_reference == - alpha_state1->alpha_func_reference); -} - -static gboolean -_cogl_pipeline_blend_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineBlendState *blend_state0 = &authority0->big_state->blend_state; - CoglPipelineBlendState *blend_state1 = &authority1->big_state->blend_state; - -#ifndef HAVE_COGL_GLES - if (blend_state0->blend_equation_rgb != blend_state1->blend_equation_rgb) - return FALSE; - if (blend_state0->blend_equation_alpha != - blend_state1->blend_equation_alpha) - return FALSE; - if (blend_state0->blend_src_factor_alpha != - blend_state1->blend_src_factor_alpha) - return FALSE; - if (blend_state0->blend_dst_factor_alpha != - blend_state1->blend_dst_factor_alpha) - return FALSE; -#endif - if (blend_state0->blend_src_factor_rgb != - blend_state1->blend_src_factor_rgb) - return FALSE; - if (blend_state0->blend_dst_factor_rgb != - blend_state1->blend_dst_factor_rgb) - return FALSE; -#ifndef HAVE_COGL_GLES - if (blend_state0->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state0->blend_src_factor_rgb == GL_CONSTANT_COLOR || - blend_state0->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state0->blend_dst_factor_rgb == GL_CONSTANT_COLOR) - { - if (!cogl_color_equal (&blend_state0->blend_constant, - &blend_state1->blend_constant)) - return FALSE; - } -#endif - - return TRUE; -} - -static gboolean -_cogl_pipeline_depth_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - if (authority0->big_state->depth_state.depth_test_enabled == FALSE && - authority1->big_state->depth_state.depth_test_enabled == FALSE) - return TRUE; - else - return memcmp (&authority0->big_state->depth_state, - &authority1->big_state->depth_state, - sizeof (CoglPipelineDepthState)) == 0; -} - -static gboolean -_cogl_pipeline_fog_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineFogState *fog_state0 = &authority0->big_state->fog_state; - CoglPipelineFogState *fog_state1 = &authority1->big_state->fog_state; - - if (fog_state0->enabled == fog_state1->enabled && - cogl_color_equal (&fog_state0->color, &fog_state1->color) && - fog_state0->mode == fog_state1->mode && - fog_state0->density == fog_state1->density && - fog_state0->z_near == fog_state1->z_near && - fog_state0->z_far == fog_state1->z_far) - return TRUE; - else - return FALSE; -} - -static gboolean -_cogl_pipeline_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return authority0->big_state->point_size == authority1->big_state->point_size; -} - -static gboolean -_cogl_pipeline_user_shader_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return (authority0->big_state->user_program == - authority1->big_state->user_program); -} - -static gboolean -_cogl_pipeline_layers_equal (CoglPipeline *authority0, - CoglPipeline *authority1, - unsigned long differences, - CoglPipelineEvalFlags flags) -{ - int i; - - if (authority0->n_layers != authority1->n_layers) - return FALSE; - - _cogl_pipeline_update_layers_cache (authority0); - _cogl_pipeline_update_layers_cache (authority1); - - for (i = 0; i < authority0->n_layers; i++) - { - if (!_cogl_pipeline_layer_equal (authority0->layers_cache[i], - authority1->layers_cache[i], - differences, - flags)) - return FALSE; - } - return TRUE; -} - -/* Determine the mask of differences between two pipelines */ -unsigned long -_cogl_pipeline_compare_differences (CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - CoglPipeline *node0; - CoglPipeline *node1; - int len0; - int len1; - int len0_index; - int len1_index; - int count; - int i; - CoglPipeline *common_ancestor = NULL; - unsigned long pipelines_difference = 0; - - _COGL_GET_CONTEXT (ctx, 0); - - /* Algorithm: - * - * 1) Walk the ancestors of each layer to the root node, adding a - * pointer to each ancester node to two GArrays: - * ctx->pipeline0_nodes, and ctx->pipeline1_nodes. - * - * 2) Compare the arrays to find the nodes where they stop to - * differ. - * - * 3) For each array now iterate from index 0 to the first node of - * difference ORing that nodes ->difference mask into the final - * pipeline_differences mask. - */ - - g_array_set_size (ctx->pipeline0_nodes, 0); - g_array_set_size (ctx->pipeline1_nodes, 0); - for (node0 = pipeline0; node0; node0 = _cogl_pipeline_get_parent (node0)) - g_array_append_vals (ctx->pipeline0_nodes, &node0, 1); - for (node1 = pipeline1; node1; node1 = _cogl_pipeline_get_parent (node1)) - g_array_append_vals (ctx->pipeline1_nodes, &node1, 1); - - len0 = ctx->pipeline0_nodes->len; - len1 = ctx->pipeline1_nodes->len; - /* There's no point looking at the last entries since we know both - * layers must have the same default layer as their root node. */ - len0_index = len0 - 2; - len1_index = len1 - 2; - count = MIN (len0, len1) - 1; - for (i = 0; i < count; i++) - { - node0 = g_array_index (ctx->pipeline0_nodes, - CoglPipeline *, len0_index--); - node1 = g_array_index (ctx->pipeline1_nodes, - CoglPipeline *, len1_index--); - if (node0 != node1) - { - common_ancestor = _cogl_pipeline_get_parent (node0); - break; - } - } - - /* If we didn't already find the first the common_ancestor ancestor - * that's because one pipeline is a direct descendant of the other - * and in this case the first common ancestor is the last node we - * looked at. */ - if (!common_ancestor) - common_ancestor = node0; - - count = len0 - 1; - for (i = 0; i < count; i++) - { - node0 = g_array_index (ctx->pipeline0_nodes, CoglPipeline *, i); - if (node0 == common_ancestor) - break; - pipelines_difference |= node0->differences; - } - - count = len1 - 1; - for (i = 0; i < count; i++) - { - node1 = g_array_index (ctx->pipeline1_nodes, CoglPipeline *, i); - if (node1 == common_ancestor) - break; - pipelines_difference |= node1->differences; - } - - return pipelines_difference; - -} - -static gboolean -simple_property_equal (CoglPipeline **authorities0, - CoglPipeline **authorities1, - unsigned long pipelines_difference, - CoglPipelineStateIndex state_index, - CoglPipelineStateComparitor comparitor) -{ - if (pipelines_difference & (1L<differences & remaining; - int i; - - if (found == 0) - continue; - - for (i = 0; TRUE; i++) - { - unsigned long state = (1L< found) - break; - } - - remaining &= ~found; - if (remaining == 0) - return; - } - while ((authority = _cogl_pipeline_get_parent (authority))); - - g_assert (remaining == 0); -} - -/* Comparison of two arbitrary pipelines is done by: - * 1) walking up the parents of each pipeline until a common - * ancestor is found, and at each step ORing together the - * difference masks. - * - * 2) using the final difference mask to determine which state - * groups to compare. - * - * This is used, for example, by the Cogl journal to compare pipelines so that - * it can split up geometry that needs different OpenGL state. - * - * XXX: When comparing texture layers, _cogl_pipeline_equal will actually - * compare the underlying GL texture handle that the Cogl texture uses so that - * atlas textures and sub textures will be considered equal if they point to - * the same texture. This is useful for comparing pipelines in the journal but - * it means that _cogl_pipeline_equal doesn't strictly compare whether the - * pipelines are the same. If we needed those semantics we could perhaps add - * another function or some flags to control the behaviour. - * - * XXX: Similarly when comparing the wrap modes, - * COGL_PIPELINE_WRAP_MODE_AUTOMATIC is considered to be the same as - * COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE because once they get to the - * journal stage they act exactly the same. - */ -gboolean -_cogl_pipeline_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1, - unsigned long differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags) -{ - unsigned long pipelines_difference; - CoglPipeline *authorities0[COGL_PIPELINE_STATE_SPARSE_COUNT]; - CoglPipeline *authorities1[COGL_PIPELINE_STATE_SPARSE_COUNT]; - gboolean ret; - - COGL_STATIC_TIMER (pipeline_equal_timer, - "Mainloop", /* parent */ - "_cogl_pipeline_equal", - "The time spent comparing cogl pipelines", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, pipeline_equal_timer); - - if (pipeline0 == pipeline1) - { - ret = TRUE; - goto done; - } - - ret = FALSE; - - /* First check non-sparse properties */ - - if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE && - pipeline0->real_blend_enable != pipeline1->real_blend_enable) - goto done; - - /* Then check sparse properties */ - - pipelines_difference = - _cogl_pipeline_compare_differences (pipeline0, pipeline1); - - /* Only compare the sparse state groups requested by the caller... */ - pipelines_difference &= differences; - - _cogl_pipeline_resolve_authorities (pipeline0, - pipelines_difference, - authorities0); - _cogl_pipeline_resolve_authorities (pipeline1, - pipelines_difference, - authorities1); - - /* FIXME: we should resolve all the required authorities up front since - * that should reduce some repeat ancestor traversals. */ - - if (pipelines_difference & COGL_PIPELINE_STATE_COLOR) - { - CoglPipeline *authority0 = authorities0[COGL_PIPELINE_STATE_COLOR_INDEX]; - CoglPipeline *authority1 = authorities1[COGL_PIPELINE_STATE_COLOR_INDEX]; - - if (!cogl_color_equal (&authority0->color, &authority1->color)) - goto done; - } - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_LIGHTING_INDEX, - _cogl_pipeline_lighting_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX, - _cogl_pipeline_alpha_func_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX, - _cogl_pipeline_alpha_func_reference_state_equal)) - goto done; - - /* We don't need to compare the detailed blending state if we know - * blending is disabled for both pipelines. */ - if (pipeline0->real_blend_enable && - pipelines_difference & COGL_PIPELINE_STATE_BLEND) - { - CoglPipeline *authority0 = authorities0[COGL_PIPELINE_STATE_BLEND_INDEX]; - CoglPipeline *authority1 = authorities1[COGL_PIPELINE_STATE_BLEND_INDEX]; - - if (!_cogl_pipeline_blend_state_equal (authority0, authority1)) - goto done; - } - - /* XXX: we don't need to compare the BLEND_ENABLE state because it's - * already reflected in ->real_blend_enable */ -#if 0 - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_BLEND_INDEX, - _cogl_pipeline_blend_enable_equal)) - return FALSE; -#endif - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_DEPTH_INDEX, - _cogl_pipeline_depth_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_FOG_INDEX, - _cogl_pipeline_fog_state_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_POINT_SIZE_INDEX, - _cogl_pipeline_point_size_equal)) - goto done; - - if (!simple_property_equal (authorities0, authorities1, - pipelines_difference, - COGL_PIPELINE_STATE_USER_SHADER_INDEX, - _cogl_pipeline_user_shader_equal)) - goto done; - - if (pipelines_difference & COGL_PIPELINE_STATE_LAYERS) - { - CoglPipelineStateIndex state_index = COGL_PIPELINE_STATE_LAYERS_INDEX; - if (!_cogl_pipeline_layers_equal (authorities0[state_index], - authorities1[state_index], - layer_differences, - flags)) - goto done; - } - - ret = TRUE; -done: - COGL_TIMER_STOP (_cogl_uprof_context, pipeline_equal_timer); - return ret; -} - -void -cogl_pipeline_get_color (CoglPipeline *pipeline, - CoglColor *color) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - - *color = authority->color; -} - -/* This is used heavily by the cogl journal when logging quads */ -void -_cogl_pipeline_get_colorubv (CoglPipeline *pipeline, - guint8 *color) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - - _cogl_color_get_rgba_4ubv (&authority->color, color); -} - -static void -_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline) -{ - CoglPipeline *new_parent = _cogl_pipeline_get_parent (pipeline); - - /* Before considering pruning redundant ancestry we check if this - * pipeline is an authority for layer state and if so only consider - * reparenting if it *owns* all the layers it depends on. NB: A - * pipeline can be be a STATE_LAYERS authority but it may still - * defer to its ancestors to define the state for some of its - * layers. - * - * For example a pipeline that derives from a parent with 5 layers - * can become a STATE_LAYERS authority by simply changing it's - * ->n_layers count to 4 and in that case it can still defer to its - * ancestors to define the state of those 4 layers. - * - * If a pipeline depends on any ancestors for layer state then we - * immediatly bail out. - */ - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - if (pipeline->n_layers != g_list_length (pipeline->layer_differences)) - return; - } - - /* walk up past ancestors that are now redundant and potentially - * reparent the pipeline. */ - while (_cogl_pipeline_get_parent (new_parent) && - (new_parent->differences | pipeline->differences) == - pipeline->differences) - new_parent = _cogl_pipeline_get_parent (new_parent); - - if (new_parent != _cogl_pipeline_get_parent (pipeline)) - { - gboolean is_weak = _cogl_pipeline_is_weak (pipeline); - _cogl_pipeline_set_parent (pipeline, new_parent, is_weak ? FALSE : TRUE); - } -} - -static void -_cogl_pipeline_update_authority (CoglPipeline *pipeline, - CoglPipeline *authority, - CoglPipelineState state, - CoglPipelineStateComparitor comparitor) -{ - /* If we are the current authority see if we can revert to one of - * our ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (comparitor (authority, old_authority)) - pipeline->differences &= ~state; - } - else if (pipeline != authority) - { - /* If we weren't previously the authority on this state then we - * need to extended our differences mask and so it's possible - * that some of our ancestry will now become redundant, so we - * aim to reparent ourselves if that's true... */ - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } -} - -void -cogl_pipeline_set_color (CoglPipeline *pipeline, - const CoglColor *color) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_COLOR; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (cogl_color_equal (color, &authority->color)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, color, FALSE); - - pipeline->color = *color; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_color_equal); - - handle_automatic_blend_enable (pipeline, state); -} - -void -cogl_pipeline_set_color4ub (CoglPipeline *pipeline, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha) -{ - CoglColor color; - cogl_color_init_from_4ub (&color, red, green, blue, alpha); - cogl_pipeline_set_color (pipeline, &color); -} - -void -cogl_pipeline_set_color4f (CoglPipeline *pipeline, - float red, - float green, - float blue, - float alpha) -{ - CoglColor color; - cogl_color_init_from_4f (&color, red, green, blue, alpha); - cogl_pipeline_set_color (pipeline, &color); -} - -CoglPipelineBlendEnable -_cogl_pipeline_get_blend_enabled (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE); - return authority->blend_enable; -} - -static gboolean -_cogl_pipeline_blend_enable_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return authority0->blend_enable == authority1->blend_enable ? TRUE : FALSE; -} - -void -_cogl_pipeline_set_blend_enabled (CoglPipeline *pipeline, - CoglPipelineBlendEnable enable) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND_ENABLE; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - g_return_if_fail (enable > 1 && - "don't pass TRUE or FALSE to _set_blend_enabled!"); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->blend_enable == enable) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->blend_enable = enable; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_blend_enable_equal); - - handle_automatic_blend_enable (pipeline, state); -} - -void -cogl_pipeline_get_ambient (CoglPipeline *pipeline, - CoglColor *ambient) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (ambient, - authority->big_state->lighting_state.ambient); -} - -void -cogl_pipeline_set_ambient (CoglPipeline *pipeline, - const CoglColor *ambient) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipeline *authority; - CoglPipelineLightingState *lighting_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (ambient, &lighting_state->ambient)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->ambient[0] = cogl_color_get_red_float (ambient); - lighting_state->ambient[1] = cogl_color_get_green_float (ambient); - lighting_state->ambient[2] = cogl_color_get_blue_float (ambient); - lighting_state->ambient[3] = cogl_color_get_alpha_float (ambient); - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - handle_automatic_blend_enable (pipeline, state); -} - -void -cogl_pipeline_get_diffuse (CoglPipeline *pipeline, - CoglColor *diffuse) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (diffuse, - authority->big_state->lighting_state.diffuse); -} - -void -cogl_pipeline_set_diffuse (CoglPipeline *pipeline, - const CoglColor *diffuse) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipeline *authority; - CoglPipelineLightingState *lighting_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (diffuse, &lighting_state->diffuse)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->diffuse[0] = cogl_color_get_red_float (diffuse); - lighting_state->diffuse[1] = cogl_color_get_green_float (diffuse); - lighting_state->diffuse[2] = cogl_color_get_blue_float (diffuse); - lighting_state->diffuse[3] = cogl_color_get_alpha_float (diffuse); - - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - handle_automatic_blend_enable (pipeline, state); -} - -void -cogl_pipeline_set_ambient_and_diffuse (CoglPipeline *pipeline, - const CoglColor *color) -{ - cogl_pipeline_set_ambient (pipeline, color); - cogl_pipeline_set_diffuse (pipeline, color); -} - -void -cogl_pipeline_get_specular (CoglPipeline *pipeline, - CoglColor *specular) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (specular, - authority->big_state->lighting_state.specular); -} - -void -cogl_pipeline_set_specular (CoglPipeline *pipeline, const CoglColor *specular) -{ - CoglPipeline *authority; - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipelineLightingState *lighting_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (specular, &lighting_state->specular)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->specular[0] = cogl_color_get_red_float (specular); - lighting_state->specular[1] = cogl_color_get_green_float (specular); - lighting_state->specular[2] = cogl_color_get_blue_float (specular); - lighting_state->specular[3] = cogl_color_get_alpha_float (specular); - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - handle_automatic_blend_enable (pipeline, state); -} - -float -cogl_pipeline_get_shininess (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - return authority->big_state->lighting_state.shininess; -} - -void -cogl_pipeline_set_shininess (CoglPipeline *pipeline, - float shininess) -{ - CoglPipeline *authority; - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipelineLightingState *lighting_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - if (shininess < 0.0) - { - g_warning ("Out of range shininess %f supplied for pipeline\n", - shininess); - return; - } - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - - if (lighting_state->shininess == shininess) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->shininess = shininess; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); -} - -void -cogl_pipeline_get_emission (CoglPipeline *pipeline, - CoglColor *emission) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (emission, - authority->big_state->lighting_state.emission); -} - -void -cogl_pipeline_set_emission (CoglPipeline *pipeline, const CoglColor *emission) -{ - CoglPipeline *authority; - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipelineLightingState *lighting_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (emission, &lighting_state->emission)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->emission[0] = cogl_color_get_red_float (emission); - lighting_state->emission[1] = cogl_color_get_green_float (emission); - lighting_state->emission[2] = cogl_color_get_blue_float (emission); - lighting_state->emission[3] = cogl_color_get_alpha_float (emission); - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - handle_automatic_blend_enable (pipeline, state); -} - -static void -_cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC; - CoglPipeline *authority; - CoglPipelineAlphaFuncState *alpha_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - alpha_state = &authority->big_state->alpha_state; - if (alpha_state->alpha_func == alpha_func) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - alpha_state = &pipeline->big_state->alpha_state; - alpha_state->alpha_func = alpha_func; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_alpha_func_state_equal); -} - -static void -_cogl_pipeline_set_alpha_test_function_reference (CoglPipeline *pipeline, - float alpha_reference) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE; - CoglPipeline *authority; - CoglPipelineAlphaFuncState *alpha_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - alpha_state = &authority->big_state->alpha_state; - if (alpha_state->alpha_func_reference == alpha_reference) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - alpha_state = &pipeline->big_state->alpha_state; - alpha_state->alpha_func_reference = alpha_reference; - - _cogl_pipeline_update_authority - (pipeline, authority, state, - _cogl_pipeline_alpha_func_reference_state_equal); -} - -void -cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func, - float alpha_reference) -{ - _cogl_pipeline_set_alpha_test_function (pipeline, alpha_func); - _cogl_pipeline_set_alpha_test_function_reference (pipeline, alpha_reference); -} - -CoglPipelineAlphaFunc -cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC); - - return authority->big_state->alpha_state.alpha_func; -} - -float -cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0.0f); - - authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE); - - return authority->big_state->alpha_state.alpha_func_reference; -} - -GLenum -arg_to_gl_blend_factor (CoglBlendStringArgument *arg) -{ - if (arg->source.is_zero) - return GL_ZERO; - if (arg->factor.is_one) - return GL_ONE; - else if (arg->factor.is_src_alpha_saturate) - return GL_SRC_ALPHA_SATURATE; - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_SRC_COLOR; - else - return GL_SRC_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_SRC_ALPHA; - else - return GL_SRC_ALPHA; - } - } - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_DST_COLOR; - else - return GL_DST_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_DST_ALPHA; - else - return GL_DST_ALPHA; - } - } -#ifndef HAVE_COGL_GLES - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_CONSTANT_COLOR; - else - return GL_CONSTANT_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_CONSTANT_ALPHA; - else - return GL_CONSTANT_ALPHA; - } - } -#endif - - g_warning ("Unable to determine valid blend factor from blend string\n"); - return GL_ONE; -} - -void -setup_blend_state (CoglBlendStringStatement *statement, - GLenum *blend_equation, - GLint *blend_src_factor, - GLint *blend_dst_factor) -{ -#ifndef HAVE_COGL_GLES - switch (statement->function->type) - { - case COGL_BLEND_STRING_FUNCTION_ADD: - *blend_equation = GL_FUNC_ADD; - break; - /* TODO - add more */ - default: - g_warning ("Unsupported blend function given"); - *blend_equation = GL_FUNC_ADD; - } -#endif - - *blend_src_factor = arg_to_gl_blend_factor (&statement->args[0]); - *blend_dst_factor = arg_to_gl_blend_factor (&statement->args[1]); -} - -gboolean -cogl_pipeline_set_blend (CoglPipeline *pipeline, - const char *blend_description, - GError **error) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND; - CoglPipeline *authority; - CoglBlendStringStatement statements[2]; - CoglBlendStringStatement *rgb; - CoglBlendStringStatement *a; - GError *internal_error = NULL; - int count; - CoglPipelineBlendState *blend_state; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - count = - _cogl_blend_string_compile (blend_description, - COGL_BLEND_STRING_CONTEXT_BLENDING, - statements, - &internal_error); - if (!count) - { - if (error) - g_propagate_error (error, internal_error); - else - { - g_warning ("Cannot compile blend description: %s\n", - internal_error->message); - g_error_free (internal_error); - } - return FALSE; - } - - if (count == 1) - rgb = a = statements; - else - { - rgb = &statements[0]; - a = &statements[1]; - } - - authority = - _cogl_pipeline_get_authority (pipeline, state); - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - blend_state = &pipeline->big_state->blend_state; -#ifndef HAVE_COGL_GLES - setup_blend_state (rgb, - &blend_state->blend_equation_rgb, - &blend_state->blend_src_factor_rgb, - &blend_state->blend_dst_factor_rgb); - setup_blend_state (a, - &blend_state->blend_equation_alpha, - &blend_state->blend_src_factor_alpha, - &blend_state->blend_dst_factor_alpha); -#else - setup_blend_state (rgb, - NULL, - &blend_state->blend_src_factor_rgb, - &blend_state->blend_dst_factor_rgb); -#endif - - /* If we are the current authority see if we can revert to one of our - * ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (_cogl_pipeline_blend_state_equal (authority, old_authority)) - pipeline->differences &= ~state; - } - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (pipeline != authority) - { - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } - - handle_automatic_blend_enable (pipeline, state); - - return TRUE; -} - -void -cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, - const CoglColor *constant_color) -{ -#ifndef HAVE_COGL_GLES - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND; - CoglPipeline *authority; - CoglPipelineBlendState *blend_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - blend_state = &authority->big_state->blend_state; - if (cogl_color_equal (constant_color, &blend_state->blend_constant)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - blend_state = &pipeline->big_state->blend_state; - blend_state->blend_constant = *constant_color; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_blend_state_equal); - - handle_automatic_blend_enable (pipeline, state); -#endif -} - -CoglHandle -cogl_pipeline_get_user_program (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), COGL_INVALID_HANDLE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_USER_SHADER); - - return authority->big_state->user_program; -} - -/* XXX: for now we don't mind if the program has vertex shaders - * attached but if we ever make a similar API public we should only - * allow attaching of programs containing fragment shaders. Eventually - * we will have a CoglPipeline abstraction to also cover vertex - * processing. - */ -void -cogl_pipeline_set_user_program (CoglPipeline *pipeline, - CoglHandle program) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_USER_SHADER; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->big_state->user_program == program) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - if (program != COGL_INVALID_HANDLE) - { - _cogl_pipeline_set_fragend (pipeline, COGL_PIPELINE_FRAGEND_DEFAULT); - _cogl_pipeline_set_vertend (pipeline, COGL_PIPELINE_VERTEND_DEFAULT); - } - - /* If we are the current authority see if we can revert to one of our - * ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (old_authority->big_state->user_program == program) - pipeline->differences &= ~state; - } - else if (pipeline != authority) - { - /* If we weren't previously the authority on this state then we - * need to extended our differences mask and so it's possible - * that some of our ancestry will now become redundant, so we - * aim to reparent ourselves if that's true... */ - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } - - if (program != COGL_INVALID_HANDLE) - cogl_handle_ref (program); - if (authority == pipeline && - pipeline->big_state->user_program != COGL_INVALID_HANDLE) - cogl_handle_unref (pipeline->big_state->user_program); - pipeline->big_state->user_program = program; - - handle_automatic_blend_enable (pipeline, state); -} - -void -cogl_pipeline_set_depth_test_enabled (CoglPipeline *pipeline, - gboolean enable) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; - CoglPipeline *authority; - CoglPipelineDepthState *depth_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - depth_state = &authority->big_state->depth_state; - if (depth_state->depth_test_enabled == enable) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->depth_state.depth_test_enabled = enable; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_depth_state_equal); -} - -gboolean -cogl_pipeline_get_depth_test_enabled (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - - return authority->big_state->depth_state.depth_test_enabled; -} - -void -cogl_pipeline_set_depth_writing_enabled (CoglPipeline *pipeline, - gboolean enable) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; - CoglPipeline *authority; - CoglPipelineDepthState *depth_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - depth_state = &authority->big_state->depth_state; - if (depth_state->depth_writing_enabled == enable) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->depth_state.depth_writing_enabled = enable; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_depth_state_equal); -} - -gboolean -cogl_pipeline_get_depth_writing_enabled (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), TRUE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - - return authority->big_state->depth_state.depth_writing_enabled; -} - -void -cogl_pipeline_set_depth_test_function (CoglPipeline *pipeline, - CoglDepthTestFunction function) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; - CoglPipeline *authority; - CoglPipelineDepthState *depth_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - depth_state = &authority->big_state->depth_state; - if (depth_state->depth_test_function == function) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->depth_state.depth_test_function = function; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_depth_state_equal); -} - -CoglDepthTestFunction -cogl_pipeline_get_depth_test_function (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), - COGL_DEPTH_TEST_FUNCTION_LESS); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - - return authority->big_state->depth_state.depth_test_function; -} - - -gboolean -cogl_pipeline_set_depth_range (CoglPipeline *pipeline, - float near_val, - float far_val, - GError **error) -{ -#ifndef COGL_HAS_GLES - CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; - CoglPipeline *authority; - CoglPipelineDepthState *depth_state; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - depth_state = &authority->big_state->depth_state; - if (depth_state->depth_range_near == near_val && - depth_state->depth_range_far == far_val) - return TRUE; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->depth_state.depth_range_near = near_val; - pipeline->big_state->depth_state.depth_range_far = far_val; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_depth_state_equal); - return TRUE; -#else - g_set_error (error, - COGL_ERROR, - COGL_ERROR_UNSUPPORTED, - "glDepthRange not available on GLES 1"); - return FALSE; -#endif -} - -void -cogl_pipeline_get_depth_range (CoglPipeline *pipeline, - float *near_val, - float *far_val) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - - *near_val = authority->big_state->depth_state.depth_range_near; - *far_val = authority->big_state->depth_state.depth_range_far; -} - -static void -_cogl_pipeline_set_fog_state (CoglPipeline *pipeline, - const CoglPipelineFogState *fog_state) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_FOG; - CoglPipeline *authority; - CoglPipelineFogState *current_fog_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - current_fog_state = &authority->big_state->fog_state; - - if (current_fog_state->enabled == fog_state->enabled && - cogl_color_equal (¤t_fog_state->color, &fog_state->color) && - current_fog_state->mode == fog_state->mode && - current_fog_state->density == fog_state->density && - current_fog_state->z_near == fog_state->z_near && - current_fog_state->z_far == fog_state->z_far) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->fog_state = *fog_state; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_fog_state_equal); -} - -unsigned long -_cogl_pipeline_get_age (CoglPipeline *pipeline) -{ - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); - - return pipeline->age; -} - -static CoglPipelineLayer * -_cogl_pipeline_layer_copy (CoglPipelineLayer *src) -{ - CoglPipelineLayer *layer = g_slice_new (CoglPipelineLayer); - - _cogl_pipeline_node_init (COGL_PIPELINE_NODE (layer)); - - layer->owner = NULL; - layer->index = src->index; - layer->differences = 0; - layer->has_big_state = FALSE; - - _cogl_pipeline_layer_set_parent (layer, src); - - return _cogl_pipeline_layer_object_new (layer); -} - -static void -_cogl_pipeline_layer_free (CoglPipelineLayer *layer) -{ - _cogl_pipeline_layer_unparent (COGL_PIPELINE_NODE (layer)); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA && - layer->texture != COGL_INVALID_HANDLE) - cogl_handle_unref (layer->texture); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE) - g_slice_free (CoglPipelineLayerBigState, layer->big_state); - - g_slice_free (CoglPipelineLayer, layer); -} - - /* If a layer has descendants we can't modify it freely - * - * If the layer is owned and the owner has descendants we can't - * modify it freely. - * - * In both cases when we can't freely modify a layer we can either: - * - create a new layer; splice it in to replace the layer so it can - * be directly modified. - * XXX: disadvantage is that we have to invalidate the layers_cache - * for the owner and its descendants. - * - create a new derived layer and modify that. - */ - - /* XXX: how is the caller expected to deal with ref-counting? - * - * If the layer can't be freely modified and we return a new layer - * then that will effectively make the caller own a new reference - * which doesn't happen if we simply modify the given layer. - * - * We could make it consistent by taking a reference on the layer if - * we don't create a new one. At least this way the caller could - * deal with it consistently, though the semantics are a bit - * strange. - * - * Alternatively we could leave it to the caller to check - * ...? - */ - -void -_cogl_pipeline_init_default_layers (void) -{ - CoglPipelineLayer *layer = g_slice_new0 (CoglPipelineLayer); - CoglPipelineLayerBigState *big_state = - g_slice_new0 (CoglPipelineLayerBigState); - CoglPipelineLayer *new; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_pipeline_node_init (COGL_PIPELINE_NODE (layer)); - - layer->index = 0; - - layer->differences = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - - layer->unit_index = 0; - - layer->texture = COGL_INVALID_HANDLE; - layer->target = 0; - - layer->mag_filter = COGL_PIPELINE_FILTER_LINEAR; - layer->min_filter = COGL_PIPELINE_FILTER_LINEAR; - - layer->wrap_mode_s = COGL_PIPELINE_WRAP_MODE_AUTOMATIC; - layer->wrap_mode_t = COGL_PIPELINE_WRAP_MODE_AUTOMATIC; - layer->wrap_mode_p = COGL_PIPELINE_WRAP_MODE_AUTOMATIC; - - layer->big_state = big_state; - layer->has_big_state = TRUE; - - /* Choose the same default combine mode as OpenGL: - * RGBA = MODULATE(PREVIOUS[RGBA],TEXTURE[RGBA]) */ - big_state->texture_combine_rgb_func = - COGL_PIPELINE_COMBINE_FUNC_MODULATE; - big_state->texture_combine_rgb_src[0] = - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - big_state->texture_combine_rgb_src[1] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - big_state->texture_combine_rgb_op[0] = - COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - big_state->texture_combine_rgb_op[1] = - COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - big_state->texture_combine_alpha_func = - COGL_PIPELINE_COMBINE_FUNC_MODULATE; - big_state->texture_combine_alpha_src[0] = - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - big_state->texture_combine_alpha_src[1] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - big_state->texture_combine_alpha_op[0] = - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - big_state->texture_combine_alpha_op[1] = - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - - big_state->point_sprite_coords = FALSE; - - cogl_matrix_init_identity (&big_state->matrix); - - ctx->default_layer_0 = _cogl_pipeline_layer_object_new (layer); - - /* TODO: we should make default_layer_n comprise of two - * descendants of default_layer_0: - * - the first descendant should change the texture combine - * to what we expect is most commonly used for multitexturing - * - the second should revert the above change. - * - * why? the documentation for how a new layer is initialized - * doesn't say that layers > 0 have different defaults so unless - * we change the documentation we can't use different defaults, - * but if the user does what we expect and changes the - * texture combine then we can revert the authority to the - * first descendant which means we can maximize the number - * of layers with a common ancestor. - * - * The main problem will be that we'll need to disable the - * optimizations for flattening the ancestry when we make - * the second descendant which reverts the state. - */ - ctx->default_layer_n = _cogl_pipeline_layer_copy (layer); - new = _cogl_pipeline_set_layer_unit (NULL, ctx->default_layer_n, 1); - g_assert (new == ctx->default_layer_n); - /* Since we passed a newly allocated layer we don't expect that - * _set_layer_unit() will have to allocate *another* layer. */ - - /* Finally we create a dummy dependant for ->default_layer_n which - * effectively ensures that ->default_layer_n and ->default_layer_0 - * remain immutable. - */ - ctx->dummy_layer_dependant = - _cogl_pipeline_layer_copy (ctx->default_layer_n); -} - -static void -setup_texture_combine_state (CoglBlendStringStatement *statement, - CoglPipelineCombineFunc *texture_combine_func, - CoglPipelineCombineSource *texture_combine_src, - CoglPipelineCombineOp *texture_combine_op) -{ - int i; - - switch (statement->function->type) - { - case COGL_BLEND_STRING_FUNCTION_REPLACE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_REPLACE; - break; - case COGL_BLEND_STRING_FUNCTION_MODULATE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_MODULATE; - break; - case COGL_BLEND_STRING_FUNCTION_ADD: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_ADD; - break; - case COGL_BLEND_STRING_FUNCTION_ADD_SIGNED: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED; - break; - case COGL_BLEND_STRING_FUNCTION_INTERPOLATE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE; - break; - case COGL_BLEND_STRING_FUNCTION_SUBTRACT: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_SUBTRACT; - break; - case COGL_BLEND_STRING_FUNCTION_DOT3_RGB: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB; - break; - case COGL_BLEND_STRING_FUNCTION_DOT3_RGBA: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA; - break; - } - - for (i = 0; i < statement->function->argc; i++) - { - CoglBlendStringArgument *arg = &statement->args[i]; - - switch (arg->source.info->type) - { - case COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_CONSTANT; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N: - texture_combine_src[i] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + arg->source.texture; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - break; - default: - g_warning ("Unexpected texture combine source"); - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - } - - if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB) - { - if (statement->args[i].source.one_minus) - texture_combine_op[i] = - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR; - else - texture_combine_op[i] = COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - } - else - { - if (statement->args[i].source.one_minus) - texture_combine_op[i] = - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA; - else - texture_combine_op[i] = COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - } - } -} - -gboolean -cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, - int layer_index, - const char *combine_description, - GError **error) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_COMBINE; - CoglPipelineLayer *authority; - CoglPipelineLayer *layer; - CoglBlendStringStatement statements[2]; - CoglBlendStringStatement split[2]; - CoglBlendStringStatement *rgb; - CoglBlendStringStatement *a; - GError *internal_error = NULL; - int count; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - count = - _cogl_blend_string_compile (combine_description, - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE, - statements, - &internal_error); - if (!count) - { - if (error) - g_propagate_error (error, internal_error); - else - { - g_warning ("Cannot compile combine description: %s\n", - internal_error->message); - g_error_free (internal_error); - } - return FALSE; - } - - if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - _cogl_blend_string_split_rgba_statement (statements, - &split[0], &split[1]); - rgb = &split[0]; - a = &split[1]; - } - else - { - rgb = &statements[0]; - a = &statements[1]; - } - - /* FIXME: compare the new state with the current state! */ - - /* possibly flush primitives referencing the current state... */ - layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - - setup_texture_combine_state (rgb, - &layer->big_state->texture_combine_rgb_func, - layer->big_state->texture_combine_rgb_src, - layer->big_state->texture_combine_rgb_op); - - setup_texture_combine_state (a, - &layer->big_state->texture_combine_alpha_func, - layer->big_state->texture_combine_alpha_src, - layer->big_state->texture_combine_alpha_op); - - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - - if (_cogl_pipeline_layer_combine_state_equal (authority, - old_authority)) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - handle_automatic_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS); - return TRUE; -} - -void -cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - const CoglColor *constant_color) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - float color_as_floats[4]; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - color_as_floats[0] = cogl_color_get_red_float (constant_color); - color_as_floats[1] = cogl_color_get_green_float (constant_color); - color_as_floats[2] = cogl_color_get_blue_float (constant_color); - color_as_floats[3] = cogl_color_get_alpha_float (constant_color); - - if (memcmp (authority->big_state->texture_combine_constant, - color_as_floats, sizeof (float) * 4) == 0) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - CoglPipelineLayerBigState *old_big_state = old_authority->big_state; - - if (memcmp (old_big_state->texture_combine_constant, - color_as_floats, sizeof (float) * 4) == 0) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - memcpy (layer->big_state->texture_combine_constant, - color_as_floats, - sizeof (color_as_floats)); - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - handle_automatic_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS); -} - -void -_cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - float *constant) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - authority = _cogl_pipeline_layer_get_authority (layer, change); - memcpy (constant, authority->big_state->texture_combine_constant, - sizeof (float) * 4); -} - -/* We should probably make a public API version of this that has a - matrix out-param. For an internal API it's good to be able to avoid - copying the matrix */ -const CoglMatrix * -_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = _cogl_pipeline_layer_get_authority (layer, change); - return &authority->big_state->matrix; -} - -void -cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, - int layer_index, - const CoglMatrix *matrix) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - if (cogl_matrix_equal (matrix, &authority->big_state->matrix)) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - - if (cogl_matrix_equal (matrix, &old_authority->big_state->matrix)) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return; - } - } - } - - layer->big_state->matrix = *matrix; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -void -cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index) -{ - CoglPipeline *authority; - CoglPipelineLayerInfo layer_info; - int i; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer_index; - - /* This will be updated with a reference to the layer being removed - * if it can be found. */ - layer_info.layer = NULL; - - /* This will be filled in with a list of layers that need to be - * dropped down to a lower texture unit to fill the gap of the - * removed layer. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* Unlike when we query layer info when adding a layer we must - * always have a complete layers_to_shift list... */ - layer_info.ignore_shift_layers_if_found = FALSE; - - _cogl_pipeline_get_layer_info (authority, &layer_info); - - if (layer_info.layer == NULL) - return; - - for (i = 0; i < layer_info.n_layers_to_shift; i++) - { - CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i]; - int unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer); - _cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index - 1); - /* NB: shift_layer may not be writeable so _set_layer_unit() - * will allocate a derived layer internally which will become - * owned by pipeline. Check the return value if we need to do - * anything else with this layer. */ - } - - _cogl_pipeline_remove_layer_difference (pipeline, layer_info.layer, TRUE); - _cogl_pipeline_try_reverting_layers_authority (pipeline, NULL); - - handle_automatic_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS); -} - -static gboolean -prepend_layer_to_list_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GList **layers = user_data; - - *layers = g_list_prepend (*layers, layer); - return TRUE; -} - -/* TODO: deprecate this API and replace it with - * cogl_pipeline_foreach_layer - * TODO: update the docs to note that if the user modifies any layers - * then the list may become invalid. - */ -const GList * -_cogl_pipeline_get_layers (CoglPipeline *pipeline) -{ - g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); - - if (!pipeline->deprecated_get_layers_list_dirty) - g_list_free (pipeline->deprecated_get_layers_list); - - pipeline->deprecated_get_layers_list = NULL; - - _cogl_pipeline_foreach_layer_internal (pipeline, - prepend_layer_to_list_cb, - &pipeline->deprecated_get_layers_list); - pipeline->deprecated_get_layers_list = - g_list_reverse (pipeline->deprecated_get_layers_list); - - pipeline->deprecated_get_layers_list_dirty = 0; - - return pipeline->deprecated_get_layers_list; -} - -int -cogl_pipeline_get_n_layers (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - - return authority->n_layers; -} - -/* FIXME: deprecate and replace with - * cogl_pipeline_get_layer_texture() instead. */ -CoglHandle -_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer) -{ - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), - COGL_INVALID_HANDLE); - - return _cogl_pipeline_layer_get_texture_real (layer); -} - -gboolean -_cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_USER_MATRIX); - - /* If the authority is the default pipeline then no, otherwise yes */ - return _cogl_pipeline_layer_get_parent (authority) ? TRUE : FALSE; -} - -void -_cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_FILTERS); - - *min_filter = authority->min_filter; - *mag_filter = authority->mag_filter; -} - -void -_cogl_pipeline_get_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter) -{ - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_FILTERS); - - *min_filter = authority->min_filter; - *mag_filter = authority->mag_filter; -} - -CoglPipelineFilter -_cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineFilter min_filter; - CoglPipelineFilter mag_filter; - - _cogl_pipeline_get_layer_filters (pipeline, layer_index, - &min_filter, &mag_filter); - return min_filter; -} - -CoglPipelineFilter -_cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineFilter min_filter; - CoglPipelineFilter mag_filter; - - _cogl_pipeline_get_layer_filters (pipeline, layer_index, - &min_filter, &mag_filter); - return mag_filter; -} - -void -_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *texture_authority; - - texture_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - - if (texture_authority->texture != COGL_INVALID_HANDLE) - { - CoglTexturePrePaintFlags flags = 0; - CoglPipelineFilter min_filter; - CoglPipelineFilter mag_filter; - - _cogl_pipeline_layer_get_filters (layer, &min_filter, &mag_filter); - - if (min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST - || min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST - || min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR - || min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR) - flags |= COGL_TEXTURE_NEEDS_MIPMAP; - - _cogl_texture_pre_paint (texture_authority->texture, flags); - } -} - -void -_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline, - int layer_id) -{ - CoglPipelineLayer *layer = _cogl_pipeline_get_layer (pipeline, layer_id); - _cogl_pipeline_layer_pre_paint (layer); -} - -CoglPipelineFilter -_cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), 0); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_FILTERS); - - return authority->min_filter; -} - -CoglPipelineFilter -_cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), 0); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_FILTERS); - - return authority->mag_filter; -} - -void -cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter min_filter, - CoglPipelineFilter mag_filter) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_FILTERS; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - if (authority->min_filter == min_filter && - authority->mag_filter == mag_filter) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - - if (old_authority->min_filter == min_filter && - old_authority->mag_filter == mag_filter) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return; - } - } - } - - layer->min_filter = min_filter; - layer->mag_filter = mag_filter; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -float -cogl_pipeline_get_point_size (CoglHandle handle) -{ - CoglPipeline *pipeline = COGL_PIPELINE (handle); - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (handle), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); - - return authority->big_state->point_size; -} - -void -cogl_pipeline_set_point_size (CoglHandle handle, - float point_size) -{ - CoglPipeline *pipeline = COGL_PIPELINE (handle); - CoglPipelineState state = COGL_PIPELINE_STATE_POINT_SIZE; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (handle)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->big_state->point_size == point_size) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->point_size = point_size; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_point_size_equal); -} - -/* While a pipeline is referenced by the Cogl journal we can not allow - * modifications, so this gives us a mechanism to track journal - * references separately */ -CoglPipeline * -_cogl_pipeline_journal_ref (CoglPipeline *pipeline) -{ - pipeline->journal_ref_count++; - return cogl_object_ref (pipeline); -} - -void -_cogl_pipeline_journal_unref (CoglPipeline *pipeline) -{ - pipeline->journal_ref_count--; - cogl_object_unref (pipeline); -} - -void -_cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* It was a mistake that we ever copied the OpenGL style API for - * associating these things directly with the context when we - * originally wrote Cogl. Until the corresponding deprecated APIs - * can be removed though we now shoehorn the state changes through - * the cogl_pipeline API instead. - */ - - /* A program explicitly set on the pipeline has higher precedence than - * one associated with the context using cogl_program_use() */ - if (ctx->current_program && - cogl_pipeline_get_user_program (pipeline) == COGL_INVALID_HANDLE) - cogl_pipeline_set_user_program (pipeline, ctx->current_program); - - if (ctx->legacy_depth_test_enabled) - cogl_pipeline_set_depth_test_enabled (pipeline, TRUE); - - if (ctx->legacy_fog_state.enabled) - _cogl_pipeline_set_fog_state (pipeline, &ctx->legacy_fog_state); -} - -void -_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, - const char *breadcrumb) -{ - pipeline->has_static_breadcrumb = TRUE; - pipeline->static_breadcrumb = breadcrumb; -} - -typedef struct _HashState -{ - unsigned long layer_differences; - CoglPipelineEvalFlags flags; - unsigned int hash; -} HashState; - -static void -_cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - int unit = authority->unit_index; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &unit, sizeof (unit)); -} - -static void -_cogl_pipeline_layer_hash_texture_target_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - GLenum gl_target = authority->target; - - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &gl_target, sizeof (gl_target)); -} - -static void -_cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - GLuint gl_handle; - - cogl_texture_get_gl_texture (authority->texture, &gl_handle, NULL); - - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &gl_handle, sizeof (gl_handle)); -} - -static void -_cogl_pipeline_layer_hash_filters_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - unsigned int hash = state->hash; - hash = _cogl_util_one_at_a_time_hash (hash, &authority->mag_filter, - sizeof (authority->mag_filter)); - hash = _cogl_util_one_at_a_time_hash (hash, &authority->min_filter, - sizeof (authority->min_filter)); - state->hash = hash; -} - -static void -_cogl_pipeline_layer_hash_wrap_modes_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - unsigned int hash = state->hash; - hash = _cogl_util_one_at_a_time_hash (hash, &authority->wrap_mode_s, - sizeof (authority->wrap_mode_s)); - hash = _cogl_util_one_at_a_time_hash (hash, &authority->wrap_mode_t, - sizeof (authority->wrap_mode_t)); - hash = _cogl_util_one_at_a_time_hash (hash, &authority->wrap_mode_p, - sizeof (authority->wrap_mode_p)); - state->hash = hash; -} - -static void -_cogl_pipeline_layer_hash_combine_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - unsigned int hash = state->hash; - CoglPipelineLayerBigState *b = authority->big_state; - int n_args; - int i; - - hash = _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_func, - sizeof (b->texture_combine_rgb_func)); - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_src[i], - sizeof (b->texture_combine_rgb_src[i])); - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_op[i], - sizeof (b->texture_combine_rgb_op[i])); - } - - hash = _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_func, - sizeof (b->texture_combine_alpha_func)); - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_src[i], - sizeof (b->texture_combine_alpha_src[i])); - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_op[i], - sizeof (b->texture_combine_alpha_op[i])); - } - - state->hash = hash; -} - -static void -_cogl_pipeline_layer_hash_combine_constant_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - CoglPipelineLayerBigState *b = authority->big_state; - gboolean need_hash = FALSE; - int n_args; - int i; - - /* XXX: If the user also asked to hash the ALPHA_FUNC_STATE then it - * would be nice if we could combine the n_args loops in this - * function and _cogl_pipeline_layer_hash_combine_state. - */ - - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - if (b->texture_combine_rgb_src[i] == - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT) - { - /* XXX: should we be careful to only hash the alpha - * component in the COGL_PIPELINE_COMBINE_OP_SRC_ALPHA case? */ - need_hash = TRUE; - goto done; - } - } - - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - if (b->texture_combine_alpha_src[i] == - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT) - { - /* XXX: should we be careful to only hash the alpha - * component in the COGL_PIPELINE_COMBINE_OP_SRC_ALPHA case? */ - need_hash = TRUE; - goto done; - } - } - -done: - if (need_hash) - { - float *constant = b->texture_combine_constant; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, constant, - sizeof (float) * 4); - } -} - -static void -_cogl_pipeline_layer_hash_user_matrix_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - CoglPipelineLayerBigState *big_state = authority->big_state; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &big_state->matrix, - sizeof (float) * 16); -} - -static void -_cogl_pipeline_layer_hash_point_sprite_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state) -{ - CoglPipelineLayerBigState *big_state = authority->big_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &big_state->point_sprite_coords, - sizeof (big_state->point_sprite_coords)); -} - -typedef void (*LayerStateHashFunction) (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - HashState *state); - -static LayerStateHashFunction -layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - -/* XXX: We don't statically initialize the array of hash functions, so - * we won't get caught out by later re-indexing the groups for some - * reason. */ -void -_cogl_pipeline_init_layer_state_hash_functions (void) -{ - CoglPipelineLayerStateIndex _index; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] = - _cogl_pipeline_layer_hash_unit_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX] = - _cogl_pipeline_layer_hash_texture_target_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] = - _cogl_pipeline_layer_hash_texture_data_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX] = - _cogl_pipeline_layer_hash_filters_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX] = - _cogl_pipeline_layer_hash_wrap_modes_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX] = - _cogl_pipeline_layer_hash_combine_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX] = - _cogl_pipeline_layer_hash_combine_constant_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX] = - _cogl_pipeline_layer_hash_user_matrix_state; - _index = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX; - layer_state_hash_functions[_index] = - _cogl_pipeline_layer_hash_point_sprite_state; - - /* So we get a big error if we forget to update this code! */ - g_assert (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 9); -} - -static gboolean -_cogl_pipeline_hash_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - HashState *state = user_data; - unsigned long differences = state->layer_differences; - CoglPipelineLayer *authorities[COGL_PIPELINE_LAYER_STATE_COUNT]; - unsigned long mask; - int i; - - /* Theoretically we would hash non-sparse layer state here but - * currently layers don't have any. */ - - /* XXX: we resolve all the authorities here - not just those - * corresponding to hash_state->layer_differences - because - * the hashing of some state groups actually depends on the values - * in other groups. For example we don't hash layer combine - * constants if they are aren't referenced by the current layer - * combine function. - */ - mask = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - _cogl_pipeline_layer_resolve_authorities (layer, - mask, - authorities); - - /* So we go right ahead and hash the sparse state... */ - for (i = 0; i < COGL_PIPELINE_LAYER_STATE_COUNT; i++) - { - unsigned long current_state = (1L< differences) - break; - } - - return TRUE; -} - -static void -_cogl_pipeline_hash_color_state (CoglPipeline *authority, - HashState *state) -{ - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &authority->color, - _COGL_COLOR_DATA_SIZE); -} - -static void -_cogl_pipeline_hash_blend_enable_state (CoglPipeline *authority, - HashState *state) -{ - guint8 blend_enable = authority->blend_enable; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &blend_enable, 1); -} - -static void -_cogl_pipeline_hash_layers_state (CoglPipeline *authority, - HashState *state) -{ - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &authority->n_layers, - sizeof (authority->n_layers)); - _cogl_pipeline_foreach_layer_internal (authority, - _cogl_pipeline_hash_layer_cb, - state); -} - -static void -_cogl_pipeline_hash_lighting_state (CoglPipeline *authority, - HashState *state) -{ - CoglPipelineLightingState *lighting_state = - &authority->big_state->lighting_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, lighting_state, - sizeof (CoglPipelineLightingState)); -} - -static void -_cogl_pipeline_hash_alpha_func_state (CoglPipeline *authority, - HashState *state) -{ - CoglPipelineAlphaFuncState *alpha_state = &authority->big_state->alpha_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &alpha_state->alpha_func, - sizeof (alpha_state->alpha_func)); -} - -static void -_cogl_pipeline_hash_alpha_func_reference_state (CoglPipeline *authority, - HashState *state) -{ - CoglPipelineAlphaFuncState *alpha_state = &authority->big_state->alpha_state; - float ref = alpha_state->alpha_func_reference; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &ref, sizeof (float)); -} - -static void -_cogl_pipeline_hash_blend_state (CoglPipeline *authority, - HashState *state) -{ - CoglPipelineBlendState *blend_state = &authority->big_state->blend_state; - unsigned int hash; - - if (!authority->real_blend_enable) - return; - - hash = state->hash; - -#ifndef HAVE_COGL_GLES - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_rgb, - sizeof (blend_state->blend_equation_rgb)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_alpha, - sizeof (blend_state->blend_equation_alpha)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_alpha, - sizeof (blend_state->blend_src_factor_alpha)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_alpha, - sizeof (blend_state->blend_dst_factor_alpha)); - - if (blend_state->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state->blend_src_factor_rgb == GL_CONSTANT_COLOR || - blend_state->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state->blend_dst_factor_rgb == GL_CONSTANT_COLOR) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_constant, - sizeof (blend_state->blend_constant)); - } -#endif - - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_rgb, - sizeof (blend_state->blend_src_factor_rgb)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_rgb, - sizeof (blend_state->blend_dst_factor_rgb)); - - state->hash = hash; -} - -static void -_cogl_pipeline_hash_user_shader_state (CoglPipeline *authority, - HashState *state) -{ - CoglHandle user_program = authority->big_state->user_program; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &user_program, - sizeof (user_program)); -} - -static void -_cogl_pipeline_hash_depth_state (CoglPipeline *authority, - HashState *state) -{ - CoglPipelineDepthState *depth_state = &authority->big_state->depth_state; - unsigned int hash = state->hash; - - if (depth_state->depth_test_enabled) - { - guint8 enabled = depth_state->depth_test_enabled; - CoglDepthTestFunction function = depth_state->depth_test_function; - hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled)); - hash = _cogl_util_one_at_a_time_hash (hash, &function, sizeof (function)); - } - - if (depth_state->depth_writing_enabled) - { - guint8 enabled = depth_state->depth_writing_enabled; - float near_val = depth_state->depth_range_near; - float far_val = depth_state->depth_range_far; - hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled)); - hash = _cogl_util_one_at_a_time_hash (hash, &near_val, sizeof (near_val)); - hash = _cogl_util_one_at_a_time_hash (hash, &far_val, sizeof (far_val)); - } - - state->hash = hash; -} - -static void -_cogl_pipeline_hash_fog_state (CoglPipeline *authority, - HashState *state) -{ - CoglPipelineFogState *fog_state = &authority->big_state->fog_state; - unsigned long hash = state->hash; - - if (!fog_state->enabled) - hash = _cogl_util_one_at_a_time_hash (hash, &fog_state->enabled, - sizeof (fog_state->enabled)); - else - hash = _cogl_util_one_at_a_time_hash (hash, &fog_state, - sizeof (CoglPipelineFogState)); - - state->hash = hash; -} - -static void -_cogl_pipeline_hash_point_size_state (CoglPipeline *authority, - HashState *state) -{ - float point_size = authority->big_state->point_size; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &point_size, - sizeof (point_size)); -} - -typedef void (*StateHashFunction) (CoglPipeline *authority, HashState *state); - -static StateHashFunction -state_hash_functions[COGL_PIPELINE_STATE_SPARSE_COUNT]; - -/* We don't statically initialize the array of hash functions - * so we won't get caught out by later re-indexing the groups for - * some reason. */ -void -_cogl_pipeline_init_state_hash_functions (void) -{ - state_hash_functions[COGL_PIPELINE_STATE_COLOR_INDEX] = - _cogl_pipeline_hash_color_state; - state_hash_functions[COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX] = - _cogl_pipeline_hash_blend_enable_state; - state_hash_functions[COGL_PIPELINE_STATE_LAYERS_INDEX] = - _cogl_pipeline_hash_layers_state; - state_hash_functions[COGL_PIPELINE_STATE_LIGHTING_INDEX] = - _cogl_pipeline_hash_lighting_state; - state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX] = - _cogl_pipeline_hash_alpha_func_state; - state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX] = - _cogl_pipeline_hash_alpha_func_reference_state; - state_hash_functions[COGL_PIPELINE_STATE_BLEND_INDEX] = - _cogl_pipeline_hash_blend_state; - state_hash_functions[COGL_PIPELINE_STATE_USER_SHADER_INDEX] = - _cogl_pipeline_hash_user_shader_state; - state_hash_functions[COGL_PIPELINE_STATE_DEPTH_INDEX] = - _cogl_pipeline_hash_depth_state; - state_hash_functions[COGL_PIPELINE_STATE_FOG_INDEX] = - _cogl_pipeline_hash_fog_state; - state_hash_functions[COGL_PIPELINE_STATE_POINT_SIZE_INDEX] = - _cogl_pipeline_hash_point_size_state; - - /* So we get a big error if we forget to update this code! */ - g_assert (COGL_PIPELINE_STATE_SPARSE_COUNT == 11); -} - -unsigned int -_cogl_pipeline_hash (CoglPipeline *pipeline, - unsigned long differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags) -{ - CoglPipeline *authorities[COGL_PIPELINE_STATE_SPARSE_COUNT]; - unsigned long mask; - int i; - HashState state; - unsigned int final_hash = 0; - - state.hash = 0; - state.layer_differences = layer_differences; - state.flags = flags; - - /* hash non-sparse state */ - - if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE) - { - gboolean enable = pipeline->real_blend_enable; - state.hash = - _cogl_util_one_at_a_time_hash (state.hash, &enable, sizeof (enable)); - } - - /* hash sparse state */ - - mask = differences & COGL_PIPELINE_STATE_ALL_SPARSE; - _cogl_pipeline_resolve_authorities (pipeline, mask, authorities); - - for (i = 0; i < COGL_PIPELINE_STATE_SPARSE_COUNT; i++) - { - unsigned long current_state = (1L< differences) - break; - } - - return _cogl_util_one_at_a_time_mix (final_hash); -} - -typedef struct -{ - int parent_id; - int *node_id_ptr; - GString *graph; - int indent; -} PrintDebugState; - -static gboolean -dump_layer_cb (CoglPipelineNode *node, void *user_data) -{ - CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (node); - PrintDebugState *state = user_data; - int layer_id = *state->node_id_ptr; - PrintDebugState state_out; - GString *changes_label; - gboolean changes = FALSE; - - if (state->parent_id >= 0) - g_string_append_printf (state->graph, "%*slayer%p -> layer%p;\n", - state->indent, "", - layer->_parent.parent, - layer); - - g_string_append_printf (state->graph, - "%*slayer%p [label=\"layer=0x%p\\n" - "ref count=%d\" " - "color=\"blue\"];\n", - state->indent, "", - layer, - layer, - COGL_OBJECT (layer)->ref_count); - - changes_label = g_string_new (""); - g_string_append_printf (changes_label, - "%*slayer%p -> layer_state%d [weight=100];\n" - "%*slayer_state%d [shape=box label=\"", - state->indent, "", - layer, - layer_id, - state->indent, "", - layer_id); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_UNIT) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lunit=%u\\n", - layer->unit_index); - } - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\ltexture=%p\\n", - layer->texture); - } - - if (changes) - { - g_string_append_printf (changes_label, "\"];\n"); - g_string_append (state->graph, changes_label->str); - g_string_free (changes_label, TRUE); - } - - state_out.parent_id = layer_id; - - state_out.node_id_ptr = state->node_id_ptr; - (*state_out.node_id_ptr)++; - - state_out.graph = state->graph; - state_out.indent = state->indent + 2; - - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (layer), - dump_layer_cb, - &state_out); - - return TRUE; -} - -static gboolean -dump_layer_ref_cb (CoglPipelineLayer *layer, void *data) -{ - PrintDebugState *state = data; - int pipeline_id = *state->node_id_ptr; - - g_string_append_printf (state->graph, - "%*spipeline_state%d -> layer%p;\n", - state->indent, "", - pipeline_id, - layer); - - return TRUE; -} - -static gboolean -dump_pipeline_cb (CoglPipelineNode *node, void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - PrintDebugState *state = user_data; - int pipeline_id = *state->node_id_ptr; - PrintDebugState state_out; - GString *changes_label; - gboolean changes = FALSE; - gboolean layers = FALSE; - - if (state->parent_id >= 0) - g_string_append_printf (state->graph, "%*spipeline%d -> pipeline%d;\n", - state->indent, "", - state->parent_id, - pipeline_id); - - g_string_append_printf (state->graph, - "%*spipeline%d [label=\"pipeline=0x%p\\n" - "ref count=%d\\n" - "breadcrumb=\\\"%s\\\"\" color=\"red\"];\n", - state->indent, "", - pipeline_id, - pipeline, - COGL_OBJECT (pipeline)->ref_count, - pipeline->has_static_breadcrumb ? - pipeline->static_breadcrumb : "NULL"); - - changes_label = g_string_new (""); - g_string_append_printf (changes_label, - "%*spipeline%d -> pipeline_state%d [weight=100];\n" - "%*spipeline_state%d [shape=box label=\"", - state->indent, "", - pipeline_id, - pipeline_id, - state->indent, "", - pipeline_id); - - - if (pipeline->differences & COGL_PIPELINE_STATE_COLOR) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lcolor=0x%02X%02X%02X%02X\\n", - cogl_color_get_red_byte (&pipeline->color), - cogl_color_get_green_byte (&pipeline->color), - cogl_color_get_blue_byte (&pipeline->color), - cogl_color_get_alpha_byte (&pipeline->color)); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_BLEND) - { - const char *blend_enable_name; - - changes = TRUE; - - switch (pipeline->blend_enable) - { - case COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC: - blend_enable_name = "AUTO"; - break; - case COGL_PIPELINE_BLEND_ENABLE_ENABLED: - blend_enable_name = "ENABLED"; - break; - case COGL_PIPELINE_BLEND_ENABLE_DISABLED: - blend_enable_name = "DISABLED"; - break; - default: - blend_enable_name = "UNKNOWN"; - } - g_string_append_printf (changes_label, - "\\lblend=%s\\n", - blend_enable_name); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - changes = TRUE; - layers = TRUE; - g_string_append_printf (changes_label, "\\ln_layers=%d\\n", - pipeline->n_layers); - } - - if (changes) - { - g_string_append_printf (changes_label, "\"];\n"); - g_string_append (state->graph, changes_label->str); - g_string_free (changes_label, TRUE); - } - - if (layers) - { - g_list_foreach (pipeline->layer_differences, - (GFunc)dump_layer_ref_cb, - state); - } - - state_out.parent_id = pipeline_id; - - state_out.node_id_ptr = state->node_id_ptr; - (*state_out.node_id_ptr)++; - - state_out.graph = state->graph; - state_out.indent = state->indent + 2; - - _cogl_pipeline_node_foreach_child (COGL_PIPELINE_NODE (pipeline), - dump_pipeline_cb, - &state_out); - - return TRUE; -} - -void -_cogl_debug_dump_pipelines_dot_file (const char *filename) -{ - GString *graph; - PrintDebugState layer_state; - PrintDebugState pipeline_state; - int layer_id = 0; - int pipeline_id = 0; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!ctx->default_pipeline) - return; - - graph = g_string_new (""); - g_string_append_printf (graph, "digraph {\n"); - - layer_state.graph = graph; - layer_state.parent_id = -1; - layer_state.node_id_ptr = &layer_id; - layer_state.indent = 0; - dump_layer_cb (ctx->default_layer_0, &layer_state); - - pipeline_state.graph = graph; - pipeline_state.parent_id = -1; - pipeline_state.node_id_ptr = &pipeline_id; - pipeline_state.indent = 0; - dump_pipeline_cb (ctx->default_pipeline, &pipeline_state); - - g_string_append_printf (graph, "}\n"); - - if (filename) - g_file_set_contents (filename, graph->str, -1, NULL); - else - g_print ("%s", graph->str); - - g_string_free (graph, TRUE); -} - -typedef struct -{ - int i; - CoglPipelineLayer **layers; -} AddLayersToArrayState; - -static gboolean -add_layer_to_array_cb (CoglPipelineLayer *layer, - void *user_data) -{ - AddLayersToArrayState *state = user_data; - state->layers[state->i++] = layer; - return TRUE; -} - -/* Determines if we need to handle the RGB and A texture combining - * separately or is the same function used for both channel masks and - * with the same arguments... - */ -gboolean -_cogl_pipeline_need_texture_combine_separate - (CoglPipelineLayer *combine_authority) -{ - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - int n_args; - int i; - - if (big_state->texture_combine_rgb_func != - big_state->texture_combine_alpha_func) - return TRUE; - - n_args = _cogl_get_n_args_for_combine_func (big_state->texture_combine_rgb_func); - - for (i = 0; i < n_args; i++) - { - if (big_state->texture_combine_rgb_src[i] != - big_state->texture_combine_alpha_src[i]) - return TRUE; - - /* - * We can allow some variation of the source operands without - * needing a separation... - * - * "A = REPLACE (CONSTANT[A])" + either of the following... - * "RGB = REPLACE (CONSTANT[RGB])" - * "RGB = REPLACE (CONSTANT[A])" - * - * can be combined as: - * "RGBA = REPLACE (CONSTANT)" or - * "RGBA = REPLACE (CONSTANT[A])" or - * - * And "A = REPLACE (1-CONSTANT[A])" + either of the following... - * "RGB = REPLACE (1-CONSTANT)" or - * "RGB = REPLACE (1-CONSTANT[A])" - * - * can be combined as: - * "RGBA = REPLACE (1-CONSTANT)" or - * "RGBA = REPLACE (1-CONSTANT[A])" - */ - switch (big_state->texture_combine_alpha_op[i]) - { - case GL_SRC_ALPHA: - switch (big_state->texture_combine_rgb_op[i]) - { - case GL_SRC_COLOR: - case GL_SRC_ALPHA: - break; - default: - return FALSE; - } - break; - case GL_ONE_MINUS_SRC_ALPHA: - switch (big_state->texture_combine_rgb_op[i]) - { - case GL_ONE_MINUS_SRC_COLOR: - case GL_ONE_MINUS_SRC_ALPHA: - break; - default: - return FALSE; - } - break; - default: - return FALSE; /* impossible */ - } - } - - return FALSE; -} - -/* This tries to find the oldest ancestor whose pipeline and layer - state matches the given flags. This is mostly used to detect code - gen authorities so that we can reduce the numer of programs - generated */ -CoglPipeline * -_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline, - CoglPipelineState pipeline_state, - CoglPipelineLayerState layer_state) -{ - CoglPipeline *authority0; - CoglPipeline *authority1; - int n_layers; - CoglPipelineLayer **authority0_layers; - CoglPipelineLayer **authority1_layers; - - /* Find the first pipeline that modifies state that affects the - * state or any layer state... */ - authority0 = _cogl_pipeline_get_authority (pipeline, - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - - /* Find the next ancestor after that, that also modifies the - * state... */ - if (_cogl_pipeline_get_parent (authority0)) - { - authority1 = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0), - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - } - else - return authority0; - - n_layers = cogl_pipeline_get_n_layers (authority0); - - for (;;) - { - AddLayersToArrayState state; - int i; - - if (n_layers != cogl_pipeline_get_n_layers (authority1)) - return authority0; - - /* If the programs differ by anything that isn't part of the - layer state then we can't continue */ - if (pipeline_state && - (_cogl_pipeline_compare_differences (authority0, authority1) & - pipeline_state)) - return authority0; - - authority0_layers = - g_alloca (sizeof (CoglPipelineLayer *) * n_layers); - state.i = 0; - state.layers = authority0_layers; - _cogl_pipeline_foreach_layer_internal (authority0, - add_layer_to_array_cb, - &state); - - authority1_layers = - g_alloca (sizeof (CoglPipelineLayer *) * n_layers); - state.i = 0; - state.layers = authority1_layers; - _cogl_pipeline_foreach_layer_internal (authority1, - add_layer_to_array_cb, - &state); - - for (i = 0; i < n_layers; i++) - { - unsigned long layer_differences; - - if (authority0_layers[i] == authority1_layers[i]) - continue; - - layer_differences = - _cogl_pipeline_layer_compare_differences (authority0_layers[i], - authority1_layers[i]); - - if (layer_differences & layer_state) - return authority0; - } - - /* Find the next ancestor after that, that also modifies state - * affecting codegen... */ - - if (!_cogl_pipeline_get_parent (authority1)) - break; - - authority0 = authority1; - authority1 = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1), - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - if (authority1 == authority0) - break; - } - - return authority1; -} diff --git a/clutter/cogl/cogl/cogl-pipeline.h b/clutter/cogl/cogl/cogl-pipeline.h deleted file mode 100644 index 52c323d..0000000 --- a/clutter/cogl/cogl/cogl-pipeline.h +++ /dev/null @@ -1,1256 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_PIPELINE_H__ -#define __COGL_PIPELINE_H__ - -G_BEGIN_DECLS - -#include -#include - -/** - * SECTION:cogl-pipeline - * @short_description: Functions for creating and manipulating the GPU - * pipeline - * - * Cogl allows creating and manipulating objects representing the full - * configuration of the GPU pipeline. In simplified terms the GPU - * pipeline takes primitive geometry as the input, it first performs - * vertex processing, allowing you to deform your geometry, then - * rasterizes that (turning it from pure geometry into fragments) then - * performs fragment processing including depth testing and texture - * mapping. Finally it blends the result with the framebuffer. - */ - -typedef struct _CoglPipeline CoglPipeline; - -#define COGL_PIPELINE(OBJECT) ((CoglPipeline *)OBJECT) - -/** - * CoglPipelineFilter: - * @COGL_PIPELINE_FILTER_NEAREST: Measuring in manhatten distance from the, - * current pixel center, use the nearest texture texel - * @COGL_PIPELINE_FILTER_LINEAR: Use the weighted average of the 4 texels - * nearest the current pixel center - * @COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_PIPELINE_FILTER_NEAREST criterion - * @COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_PIPELINE_FILTER_LINEAR criterion - * @COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_PIPELINE_FILTER_NEAREST criterion on each one and take - * their weighted average - * @COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_PIPELINE_FILTER_LINEAR criterion on each one and take - * their weighted average - * - * Texture filtering is used whenever the current pixel maps either to more - * than one texture element (texel) or less than one. These filter enums - * correspond to different strategies used to come up with a pixel color, by - * possibly referring to multiple neighbouring texels and taking a weighted - * average or simply using the nearest texel. - */ -typedef enum { - COGL_PIPELINE_FILTER_NEAREST = 0x2600, - COGL_PIPELINE_FILTER_LINEAR = 0x2601, - COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST = 0x2701, - COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR = 0x2702, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR = 0x2703 -} CoglPipelineFilter; -/* NB: these values come from the equivalents in gl.h */ - -/** - * CoglPipelineWrapMode: - * @COGL_PIPELINE_WRAP_MODE_REPEAT: The texture will be repeated. This - * is useful for example to draw a tiled background. - * @COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE: The coordinates outside the - * range 0→1 will sample copies of the edge pixels of the - * texture. This is useful to avoid artifacts if only one copy of - * the texture is being rendered. - * @COGL_PIPELINE_WRAP_MODE_AUTOMATIC: Cogl will try to automatically - * decide which of the above two to use. For cogl_rectangle(), it - * will use repeat mode if any of the texture coordinates are - * outside the range 0→1, otherwise it will use clamp to edge. For - * cogl_polygon() it will always use repeat mode. For - * cogl_vertex_buffer_draw() it will use repeat mode except for - * layers that have point sprite coordinate generation enabled. This - * is the default value. - * - * The wrap mode specifies what happens when texture coordinates - * outside the range 0→1 are used. Note that if the filter mode is - * anything but %COGL_PIPELINE_FILTER_NEAREST then texels outside the - * range 0→1 might be used even when the coordinate is exactly 0 or 1 - * because OpenGL will try to sample neighbouring pixels. For example - * if you are trying to render the full texture then you may get - * artifacts around the edges when the pixels from the other side are - * merged in if the wrap mode is set to repeat. - * - * Since: 2.0 - */ -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes - * - * XXX: keep the values in sync with the CoglPipelineWrapModeInternal - * enum so no conversion is actually needed. - */ -typedef enum { - COGL_PIPELINE_WRAP_MODE_REPEAT = 0x2901, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC = 0x0207 -} CoglPipelineWrapMode; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_pipeline_new: - * - * Allocates and initializes a default simple pipeline that will color - * a primitive white. - * - * Return value: a pointer to a new #CoglPipeline - */ -CoglPipeline * -cogl_pipeline_new (void); - -/** - * cogl_pipeline_copy: - * @source: a #CoglPipeline object to copy - * - * Creates a new pipeline with the configuration copied from the - * source pipeline. - * - * We would strongly advise developers to always aim to use - * cogl_pipeline_copy() instead of cogl_pipeline_new() whenever there will - * be any similarity between two pipelines. Copying a pipeline helps Cogl - * keep track of a pipelines ancestry which we may use to help minimize GPU - * state changes. - * - * Returns: a pointer to the newly allocated #CoglPipeline - * - * Since: 2.0 - */ -CoglPipeline * -cogl_pipeline_copy (CoglPipeline *source); - -/** - * cogl_is_pipeline: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing pipeline object. - * - * Return value: %TRUE if the handle references a #CoglPipeline, - * %FALSE otherwise - */ -gboolean -cogl_is_pipeline (CoglHandle handle); - -/** - * cogl_pipeline_set_color: - * @pipeline: A #CoglPipeline object - * @color: The components of the color - * - * Sets the basic color of the pipeline, used when no lighting is enabled. - * - * Note that if you don't add any layers to the pipeline then the color - * will be blended unmodified with the destination; the default blend - * expects premultiplied colors: for example, use (0.5, 0.0, 0.0, 0.5) for - * semi-transparent red. See cogl_color_premultiply(). - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_color (CoglPipeline *pipeline, - const CoglColor *color); - -/** - * cogl_pipeline_set_color4ub: - * @pipeline: A #CoglPipeline object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the pipeline, used when no lighting is enabled. - * - * The default value is (0xff, 0xff, 0xff, 0xff) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_color4ub (CoglPipeline *pipeline, - guint8 red, - guint8 green, - guint8 blue, - guint8 alpha); - -/** - * cogl_pipeline_set_color4f: - * @pipeline: A #CoglPipeline object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the pipeline, used when no lighting is enabled. - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_color4f (CoglPipeline *pipeline, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_pipeline_get_color: - * @pipeline: A #CoglPipeline object - * @color: (out): The location to store the color - * - * Retrieves the current pipeline color. - * - * Since: 2.0 - */ -void -cogl_pipeline_get_color (CoglPipeline *pipeline, - CoglColor *color); - -/** - * cogl_pipeline_set_ambient: - * @pipeline: A #CoglPipeline object - * @ambient: The components of the desired ambient color - * - * Sets the pipeline's ambient color, in the standard OpenGL lighting - * model. The ambient color affects the overall color of the object. - * - * Since the diffuse color will be intense when the light hits the surface - * directly, the ambient will be most apparent where the light hits at a - * slant. - * - * The default value is (0.2, 0.2, 0.2, 1.0) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_ambient (CoglPipeline *pipeline, - const CoglColor *ambient); - -/** - * cogl_pipeline_get_ambient: - * @pipeline: A #CoglPipeline object - * @ambient: The location to store the ambient color - * - * Retrieves the current ambient color for @pipeline - * - * Since: 2.0 - */ -void -cogl_pipeline_get_ambient (CoglPipeline *pipeline, - CoglColor *ambient); - -/** - * cogl_pipeline_set_diffuse: - * @pipeline: A #CoglPipeline object - * @diffuse: The components of the desired diffuse color - * - * Sets the pipeline's diffuse color, in the standard OpenGL lighting - * model. The diffuse color is most intense where the light hits the - * surface directly - perpendicular to the surface. - * - * The default value is (0.8, 0.8, 0.8, 1.0) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_diffuse (CoglPipeline *pipeline, - const CoglColor *diffuse); - -/** - * cogl_pipeline_get_diffuse: - * @pipeline: A #CoglPipeline object - * @diffuse: The location to store the diffuse color - * - * Retrieves the current diffuse color for @pipeline - * - * Since: 2.0 - */ -void -cogl_pipeline_get_diffuse (CoglPipeline *pipeline, - CoglColor *diffuse); - -/** - * cogl_pipeline_set_ambient_and_diffuse: - * @pipeline: A #CoglPipeline object - * @color: The components of the desired ambient and diffuse colors - * - * Conveniently sets the diffuse and ambient color of @pipeline at the same - * time. See cogl_pipeline_set_ambient() and cogl_pipeline_set_diffuse(). - * - * The default ambient color is (0.2, 0.2, 0.2, 1.0) - * - * The default diffuse color is (0.8, 0.8, 0.8, 1.0) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_ambient_and_diffuse (CoglPipeline *pipeline, - const CoglColor *color); - -/** - * cogl_pipeline_set_specular: - * @pipeline: A #CoglPipeline object - * @specular: The components of the desired specular color - * - * Sets the pipeline's specular color, in the standard OpenGL lighting - * model. The intensity of the specular color depends on the viewport - * position, and is brightest along the lines of reflection. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_specular (CoglPipeline *pipeline, - const CoglColor *specular); - -/** - * cogl_pipeline_get_specular: - * @pipeline: A #CoglPipeline object - * @specular: The location to store the specular color - * - * Retrieves the pipelines current specular color. - * - * Since: 2.0 - */ -void -cogl_pipeline_get_specular (CoglPipeline *pipeline, - CoglColor *specular); - -/** - * cogl_pipeline_set_shininess: - * @pipeline: A #CoglPipeline object - * @shininess: The desired shininess; must be >= 0.0 - * - * Sets the shininess of the pipeline, in the standard OpenGL lighting - * model, which determines the size of the specular highlights. A - * higher @shininess will produce smaller highlights which makes the - * object appear more shiny. - * - * The default value is 0.0 - * - * Since: 2.0 - */ -void -cogl_pipeline_set_shininess (CoglPipeline *pipeline, - float shininess); - -/** - * cogl_pipeline_get_shininess: - * @pipeline: A #CoglPipeline object - * - * Retrieves the pipelines current emission color. - * - * Return value: The pipelines current shininess value - * - * Since: 2.0 - */ -float -cogl_pipeline_get_shininess (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_emission: - * @pipeline: A #CoglPipeline object - * @emission: The components of the desired emissive color - * - * Sets the pipeline's emissive color, in the standard OpenGL lighting - * model. It will look like the surface is a light source emitting this - * color. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 2.0 - */ -void -cogl_pipeline_set_emission (CoglPipeline *pipeline, - const CoglColor *emission); - -/** - * cogl_pipeline_get_emission: - * @pipeline: A #CoglPipeline object - * @emission: The location to store the emission color - * - * Retrieves the pipelines current emission color. - * - * Since: 2.0 - */ -void -cogl_pipeline_get_emission (CoglPipeline *pipeline, - CoglColor *emission); - -/** - * CoglPipelineAlphaFunc: - * @COGL_PIPELINE_ALPHA_FUNC_NEVER: Never let the fragment through. - * @COGL_PIPELINE_ALPHA_FUNC_LESS: Let the fragment through if the incoming - * alpha value is less than the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_EQUAL: Let the fragment through if the incoming - * alpha value equals the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_LEQUAL: Let the fragment through if the incoming - * alpha value is less than or equal to the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_GREATER: Let the fragment through if the incoming - * alpha value is greater than the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL: Let the fragment through if the incoming - * alpha value does not equal the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_GEQUAL: Let the fragment through if the incoming - * alpha value is greater than or equal to the reference alpha value. - * @COGL_PIPELINE_ALPHA_FUNC_ALWAYS: Always let the fragment through. - * - * Alpha testing happens before blending primitives with the framebuffer and - * gives an opportunity to discard fragments based on a comparison with the - * incoming alpha value and a reference alpha value. The #CoglPipelineAlphaFunc - * determines how the comparison is done. - */ -typedef enum { - COGL_PIPELINE_ALPHA_FUNC_NEVER = 0x0200, - COGL_PIPELINE_ALPHA_FUNC_LESS = 0x0201, - COGL_PIPELINE_ALPHA_FUNC_EQUAL = 0x0202, - COGL_PIPELINE_ALPHA_FUNC_LEQUAL = 0x0203, - COGL_PIPELINE_ALPHA_FUNC_GREATER = 0x0204, - COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL = 0x0205, - COGL_PIPELINE_ALPHA_FUNC_GEQUAL = 0x0206, - COGL_PIPELINE_ALPHA_FUNC_ALWAYS = 0x0207 -} CoglPipelineAlphaFunc; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_pipeline_set_alpha_test_function: - * @pipeline: A #CoglPipeline object - * @alpha_func: A @CoglPipelineAlphaFunc constant - * @alpha_reference: A reference point that the chosen alpha function uses - * to compare incoming fragments to. - * - * Before a primitive is blended with the framebuffer, it goes through an - * alpha test stage which lets you discard fragments based on the current - * alpha value. This function lets you change the function used to evaluate - * the alpha channel, and thus determine which fragments are discarded - * and which continue on to the blending stage. - * - * The default is %COGL_PIPELINE_ALPHA_FUNC_ALWAYS - * - * Since: 2.0 - */ -void -cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func, - float alpha_reference); - -/** - * cogl_pipeline_get_alpha_test_function: - * @pipeline: A #CoglPipeline object - * - * Return value: The alpha test function of @pipeline. - * - * Since: 2.0 - */ -CoglPipelineAlphaFunc -cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline); - -/** - * cogl_pipeline_get_alpha_test_reference: - * @pipeline: A #CoglPipeline object - * - * Return value: The alpha test reference value of @pipeline. - * - * Since: 2.0 - */ -float -cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_blend: - * @pipeline: A #CoglPipeline object - * @blend_string: A Cogl blend string - * describing the desired blend function. - * @error: return location for a #GError that may report lack of driver - * support if you give separate blend string statements for the alpha - * channel and RGB channels since some drivers, or backends such as - * GLES 1.1, don't support this feature. May be %NULL, in which case a - * warning will be printed out using GLib's logging facilities if an - * error is encountered. - * - * If not already familiar; please refer here - * for an overview of what blend strings are, and their syntax. - * - * Blending occurs after the alpha test function, and combines fragments with - * the framebuffer. - - * Currently the only blend function Cogl exposes is ADD(). So any valid - * blend statements will be of the form: - * - * |[ - * <channel-mask>=ADD(SRC_COLOR*(<factor>), DST_COLOR*(<factor>)) - * ]| - * - * The brackets around blend factors are currently not - * optional! - * - * This is the list of source-names usable as blend factors: - * - * SRC_COLOR: The color of the in comming fragment - * DST_COLOR: The color of the framebuffer - * CONSTANT: The constant set via cogl_pipeline_set_blend_constant() - * - * - * The source names can be used according to the - * color-source and factor syntax, - * so for example "(1-SRC_COLOR[A])" would be a valid factor, as would - * "(CONSTANT[RGB])" - * - * These can also be used as factors: - * - * 0: (0, 0, 0, 0) - * 1: (1, 1, 1, 1) - * SRC_ALPHA_SATURATE_FACTOR: (f,f,f,1) where f = MIN(SRC_COLOR[A],1-DST_COLOR[A]) - * - * - * Remember; all color components are normalized to the range [0, 1] - * before computing the result of blending. - * - * - * Blend Strings/1 - * Blend a non-premultiplied source over a destination with - * premultiplied alpha: - * - * "RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))" - * "A = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * - * - * - * - * Blend Strings/2 - * Blend a premultiplied source over a destination with - * premultiplied alpha - * - * "RGBA = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * - * - * - * The default blend string is: - * |[ - * RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A])) - * ]| - * - * That gives normal alpha-blending when the calculated color for the pipeline - * is in premultiplied form. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described blending is supported by the underlying driver/hardware. If - * there was an error, %FALSE is returned and @error is set accordingly (if - * present). - * - * Since: 2.0 - */ -gboolean -cogl_pipeline_set_blend (CoglPipeline *pipeline, - const char *blend_string, - GError **error); - -/** - * cogl_pipeline_set_blend_constant: - * @pipeline: A #CoglPipeline object - * @constant_color: The constant color you want - * - * When blending is setup to reference a CONSTANT blend factor then - * blending will depend on the constant set with this function. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, - const CoglColor *constant_color); - -/** - * cogl_pipeline_set_point_size: - * @pipeline: a #CoglHandle to a pipeline. - * @point_size: the new point size. - * - * Changes the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. Note that typically the GPU will - * only support a limited minimum and maximum range of point sizes. If - * the chosen point size is outside that range then the nearest value - * within that range will be used instead. The size of a point is in - * screen space so it will be the same regardless of any - * transformations. The default point size is 1.0. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_point_size (CoglHandle pipeline, - float point_size); - -/** - * cogl_pipeline_get_point_size: - * @pipeline: a #CoglHandle to a pipeline. - * - * Get the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. - * - * Return value: the point size of the pipeline. - * - * Since: 2.0 - */ -float -cogl_pipeline_get_point_size (CoglHandle pipeline); - -/** - * cogl_pipeline_get_user_program: - * @pipeline: a #CoglPipeline object. - * - * Queries what user program has been associated with the given - * @pipeline using cogl_pipeline_set_user_program(). - * - * Return value: The current user program or %COGL_INVALID_HANDLE. - * - * Since: 2.0 - */ -CoglHandle -cogl_pipeline_get_user_program (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_user_program: - * @pipeline: a #CoglPipeline object. - * @program: A #CoglHandle to a linked CoglProgram - * - * Associates a linked CoglProgram with the given pipeline so that the - * program can take full control of vertex and/or fragment processing. - * - * This is an example of how it can be used to associate an ARBfp - * program with a #CoglPipeline: - * |[ - * CoglHandle shader; - * CoglHandle program; - * CoglPipeline *pipeline; - * - * shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - * cogl_shader_source (shader, - * "!!ARBfp1.0\n" - * "MOV result.color,fragment.color;\n" - * "END\n"); - * cogl_shader_compile (shader); - * - * program = cogl_create_program (); - * cogl_program_attach_shader (program, shader); - * cogl_program_link (program); - * - * pipeline = cogl_pipeline_new (); - * cogl_pipeline_set_user_program (pipeline, program); - * - * cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - * cogl_rectangle (0, 0, 100, 100); - * ]| - * - * It is possibly worth keeping in mind that this API is not part of - * the long term design for how we want to expose shaders to Cogl - * developers (We are planning on deprecating the cogl_program and - * cogl_shader APIs in favour of a "snippet" framework) but in the - * meantime we hope this will handle most practical GLSL and ARBfp - * requirements. - * - * Also remember you need to check for either the - * %COGL_FEATURE_SHADERS_GLSL or %COGL_FEATURE_SHADERS_ARBFP before - * using the cogl_program or cogl_shader API. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_user_program (CoglPipeline *pipeline, - CoglHandle program); - -/** - * cogl_pipeline_set_layer: - * @pipeline: A #CoglPipeline object - * @layer_index: the index of the layer - * @texture: a #CoglHandle for the layer object - * - * In addition to the standard OpenGL lighting model a Cogl pipeline may have - * one or more layers comprised of textures that can be blended together in - * order, with a number of different texture combine modes. This function - * defines a new texture layer. - * - * The index values of multiple layers do not have to be consecutive; it is - * only their relative order that is important. - * - * In the future, we may define other types of pipeline layers, such - * as purely GLSL based layers. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, - int layer_index, - CoglHandle texture); - -/** - * cogl_pipeline_remove_layer: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want to remove - * - * This function removes a layer from your pipeline - */ -void -cogl_pipeline_remove_layer (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_combine: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want define a combine function for - * @blend_string: A Cogl blend string - * describing the desired texture combine function. - * @error: A #GError that may report parse errors or lack of GPU/driver - * support. May be %NULL, in which case a warning will be printed out if an - * error is encountered. - * - * If not already familiar; you can refer - * here for an overview of what blend - * strings are and there syntax. - * - * These are all the functions available for texture combining: - * - * REPLACE(arg0) = arg0 - * MODULATE(arg0, arg1) = arg0 x arg1 - * ADD(arg0, arg1) = arg0 + arg1 - * ADD_SIGNED(arg0, arg1) = arg0 + arg1 - 0.5 - * INTERPOLATE(arg0, arg1, arg2) = arg0 x arg2 + arg1 x (1 - arg2) - * SUBTRACT(arg0, arg1) = arg0 - arg1 - * - * - * DOT3_RGB(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * - * - * - * - * DOT3_RGBA(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * - * - * - * - * Refer to the - * color-source syntax for - * describing the arguments. The valid source names for texture combining - * are: - * - * - * TEXTURE - * Use the color from the current texture layer - * - * - * TEXTURE_0, TEXTURE_1, etc - * Use the color from the specified texture layer - * - * - * CONSTANT - * Use the color from the constant given with - * cogl_pipeline_set_layer_constant() - * - * - * PRIMARY - * Use the color of the pipeline as set with - * cogl_pipeline_set_color() - * - * - * PREVIOUS - * Either use the texture color from the previous layer, or - * if this is layer 0, use the color of the pipeline as set with - * cogl_pipeline_set_color() - * - * - * - * - * Layer Combine Examples - * This is effectively what the default blending is: - * - * RGBA = MODULATE (PREVIOUS, TEXTURE) - * - * This could be used to cross-fade between two images, using - * the alpha component of a constant as the interpolator. The constant - * color is given by calling cogl_pipeline_set_layer_constant. - * - * RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A]) - * - * - * - * You can't give a multiplication factor for arguments as you can - * with blending. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described texture combining is supported by the underlying driver and - * or hardware. On failure, %FALSE is returned and @error is set - * - * Since: 2.0 - */ -gboolean -cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, - int layer_index, - const char *blend_string, - GError **error); - -/** - * cogl_pipeline_set_layer_combine_constant: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want to specify a constant used - * for texture combining - * @constant: The constant color you want - * - * When you are using the 'CONSTANT' color source in a layer combine - * description then you can use this function to define its value. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - const CoglColor *constant); - -/** - * cogl_pipeline_set_layer_matrix: - * @pipeline: A #CoglPipeline object - * @layer_index: the index for the layer inside @pipeline - * @matrix: the transformation matrix for the layer - * - * This function lets you set a matrix that can be used to e.g. translate - * and rotate a single layer of a pipeline used to fill your geometry. - */ -void -cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, - int layer_index, - const CoglMatrix *matrix); - -/** - * cogl_pipeline_get_n_layers: - * @pipeline: A #CoglPipeline object - * - * Retrieves the number of layers defined for the given @pipeline - * - * Return value: the number of layers - * - * Since: 2.0 - */ -int -cogl_pipeline_get_n_layers (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_layer_filters: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @min_filter: the filter used when scaling a texture down. - * @mag_filter: the filter used when magnifying a texture. - * - * Changes the decimation and interpolation filters used when a texture is - * drawn at other scales than 100%. - */ -void -cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter min_filter, - CoglPipelineFilter mag_filter); - -/** - * cogl_pipeline_set_layer_point_sprite_coords_enabled: - * @pipeline: a #CoglHandle to a pipeline. - * @layer_index: the layer number to change. - * @enable: whether to enable point sprite coord generation. - * @error: A return location for a GError, or NULL to ignore errors. - * - * When rendering points, if @enable is %TRUE then the texture - * coordinates for this layer will be replaced with coordinates that - * vary from 0.0 to 1.0 across the primitive. The top left of the - * point will have the coordinates 0.0,0.0 and the bottom right will - * have 1.0,1.0. If @enable is %FALSE then the coordinates will be - * fixed for the entire point. - * - * This function will only work if %COGL_FEATURE_POINT_SPRITE is - * available. If the feature is not available then the function will - * return %FALSE and set @error. - * - * Return value: %TRUE if the function succeeds, %FALSE otherwise. - * Since: 2.0 - */ -gboolean -cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index, - gboolean enable, - GError **error); - -/** - * cogl_pipeline_get_layer_point_sprite_coords_enabled: - * @pipeline: a #CoglHandle to a pipeline. - * @layer_index: the layer number to check. - * - * Gets whether point sprite coordinate generation is enabled for this - * texture layer. - * - * Return value: whether the texture coordinates will be replaced with - * point sprite coordinates. - * - * Since: 2.0 - */ -gboolean -cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_get_layer_wrap_mode_s: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 's' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 's' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - */ -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_wrap_mode_s: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 's' coordinate of texture lookups on this layer. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_get_layer_wrap_mode_t: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 't' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 't' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - */ -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index); - - -/** - * cogl_pipeline_set_layer_wrap_mode_t: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 't' coordinate of texture lookups on this layer. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_get_layer_wrap_mode_p: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 'p' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 'p' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - */ -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_p (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_wrap_mode_p: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 'p' coordinate of texture lookups on - * this layer. 'p' is the third coordinate. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_layer_wrap_mode_p (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_set_layer_wrap_mode: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for all three coordinates of texture lookups on - * this layer. This is equivalent to calling - * cogl_pipeline_set_layer_wrap_mode_s(), - * cogl_pipeline_set_layer_wrap_mode_t() and - * cogl_pipeline_set_layer_wrap_mode_p() separately. - * - * Since: 2.0 - */ -void -cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -#ifdef COGL_ENABLE_EXPERIMENTAL_API - -/** - * cogl_pipeline_set_depth_test_enabled: - * @pipeline: A #CoglPipeline object - * @enable: The enable state you want - * - * Enables or disables depth testing according to the value of - * @enable. - * - * If depth testing is enable then the #CoglDepthTestFunction set - * using cogl_pipeline_set_depth_test_function() us used to evaluate - * the depth value of incoming fragments against the corresponding - * value stored in the current depth buffer, and if the test passes - * then the fragments depth value is used to update the depth buffer. - * (unless you have disabled depth writing via - * cogl_pipeline_set_depth_writing_enabled ()) - * - * By default depth testing is disabled. - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_depth_test_enabled (CoglPipeline *pipeline, - gboolean enable); - -/** - * cogl_pipeline_get_depth_test_enabled: - * @pipeline: A #CoglPipeline object - * - * Gets the current depth test enabled state as previously set by - * cogl_pipeline_set_depth_test_enabled(). - * - * Returns: The pipeline's current depth test enabled state. - * Since: 2.0 - * Stability: Unstable - */ -gboolean -cogl_pipeline_get_depth_test_enabled (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_depth_writing_enabled: - * @pipeline: A #CoglPipeline object - * @enable: The enable state you want - * - * Enables or disables depth buffer writing according to the value of - * @enable. Normally when depth testing is enabled and the comparison - * between a fragment's depth value and the corresponding depth buffer - * value passes then the fragment's depth is written to the depth - * buffer unless writing is disabled here. - * - * By default depth writing is enabled - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_depth_writing_enabled (CoglPipeline *pipeline, - gboolean enable); - -/** - * cogl_pipeline_get_depth_writing_enabled: - * @pipeline: A #CoglPipeline object - * - * Gets the depth writing enable state as set by the corresponding - * cogl_pipeline_set_depth_writing_enabled. - * - * Returns: The current depth writing enable state - * Since: 2.0 - * Stability: Unstable - */ -gboolean -cogl_pipeline_get_depth_writing_enabled (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_depth_test_function: - * @pipeline: A #CoglPipeline object - * @function: The #CoglDepthTestFunction to set - * - * Sets the #CoglDepthTestFunction used to compare the depth value of - * an incoming fragment against the corresponding value in the current - * depth buffer. - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_depth_test_function (CoglPipeline *pipeline, - CoglDepthTestFunction function); - -/** - * cogl_pipeline_get_depth_test_function: - * @pipeline: A #CoglPipeline object - * - * Gets the current depth test enable state as previously set via - * cogl_pipeline_set_depth_test_enabled(). - * - * Returns: The current depth test enable state. - * Since: 2.0 - * Stability: Unstable - */ -CoglDepthTestFunction -cogl_pipeline_get_depth_test_function (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_depth_range: - * @pipeline: A #CoglPipeline object - * @near_val: The near component of the desired depth range which will be - * clamped to the range [0, 1] - * @far_val: The far component of the desired depth range which will be - * clamped to the range [0, 1] - * @error: location to store an error of type #CoglError - * - * Sets the range to map depth values in normalized device coordinates - * to before writing out to a depth buffer. - * - * After your geometry has be transformed, clipped and had perspective - * division applied placing it in normalized device - * coordinates all depth values between the near and far z clipping - * planes are in the range -1 to 1. Before writing any depth value to - * the depth buffer though the value is mapped into the range [0, 1]. - * - * With this function you can change the range which depth values are - * mapped too although the range must still lye within the range [0, - * 1]. - * - * If your driver does not support this feature (for example you are - * using GLES 1 drivers) then this will return %FALSE and set an error - * if @error isn't NULL. You can check ahead of time for the - * %COGL_FEATURE_DEPTH_RANGE feature with cogl_features_available() to - * know if this function will succeed. - * - * By default normalized device coordinate depth values are mapped to - * the full range of depth buffer values, [0, 1]. - * - * Returns: %TRUE if driver support is available else %FALSE. - * - * Since: 2.0 - * Stability: Unstable - */ -gboolean -cogl_pipeline_set_depth_range (CoglPipeline *pipeline, - float near_val, - float far_val, - GError **error); - -/** - * cogl_pipeline_get_depth_range_mapping: - * @pipeline: A #CoglPipeline object - * @near_val: A pointer to store the near component of the depth range - * @far_val: A pointer to store the far component of the depth range - * - * Gets the current range to which normalized depth values are mapped - * before writing to the depth buffer. This corresponds to the range - * set with cogl_pipeline_set_depth_range(). - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_get_depth_range (CoglPipeline *pipeline, - float *near_val, - float *far_val); - -/** - * CoglPipelineLayerCallback: - * @pipeline: The #CoglPipeline whos layers are being iterated - * @layer_index: The current layer index - * @user_data: The private data passed to cogl_pipeline_foreach_layer() - * - * The callback prototype used with cogl_pipeline_foreach_layer() for - * iterating all the layers of a @pipeline. - * - * Since: 2.0 - * Stability: Unstable - */ -typedef gboolean (*CoglPipelineLayerCallback) (CoglPipeline *pipeline, - int layer_index, - void *user_data); - -/** - * cogl_pipeline_foreach_layer: - * @pipeline: A #CoglPipeline object - * @callback: A #CoglPipelineLayerCallback to be called for each layer - * index - * @user_data: Private data that will be passed to the callback - * - * Iterates all the layer indices of the given @pipeline. - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_foreach_layer (CoglPipeline *pipeline, - CoglPipelineLayerCallback callback, - void *user_data); - -#endif /* COGL_ENABLE_EXPERIMENTAL_API */ - -G_END_DECLS - -#endif /* __COGL_PIPELINE_H__ */ diff --git a/clutter/cogl/cogl/cogl-pixel-array-private.h b/clutter/cogl/cogl/cogl-pixel-array-private.h deleted file mode 100644 index d613f45..0000000 --- a/clutter/cogl/cogl/cogl-pixel-array-private.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#ifndef __COGL_PIXEL_ARRAY_PRIVATE_H__ -#define __COGL_PIXEL_ARRAY_PRIVATE_H__ - -#include "cogl-handle.h" -#include "cogl-buffer-private.h" - -#include - -G_BEGIN_DECLS - -#define COGL_PIXEL_ARRAY(array) ((CoglPixelArray *)(array)) - -struct _CoglPixelArray -{ - CoglBuffer _parent; - - CoglPixelFormat format; - unsigned int width; - unsigned int height; - unsigned int stride; -}; - -GQuark -_cogl_handle_pixel_array_get_type (void); - -G_END_DECLS - -#endif /* __COGL_PIXEL_ARRAY_PRIVATE_H__ */ diff --git a/clutter/cogl/cogl/cogl-pixel-array.c b/clutter/cogl/cogl/cogl-pixel-array.c deleted file mode 100644 index fce42f1..0000000 --- a/clutter/cogl/cogl/cogl-pixel-array.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -/* For an overview of the functionality implemented here, please see - * cogl-pixel-array.h, which contains the gtk-doc section overview for the - * Pixel Buffers API. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-object.h" -#include "cogl-pixel-array-private.h" -#include "cogl-pixel-array.h" - -/* - * GL/GLES compatibility defines for the buffer API: - */ - -#if defined (HAVE_COGL_GL) - -#define glGenBuffers ctx->drv.pf_glGenBuffers -#define glBindBuffer ctx->drv.pf_glBindBuffer -#define glBufferData ctx->drv.pf_glBufferData -#define glBufferSubData ctx->drv.pf_glBufferSubData -#define glGetBufferSubData ctx->drv.pf_glGetBufferSubData -#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers -#define glMapBuffer ctx->drv.pf_glMapBuffer -#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer - -#ifndef GL_PIXEL_UNPACK_BUFFER -#define GL_PIXEL_UNPACK_BUFFER GL_PIXEL_UNPACK_BUFFER_ARB -#endif - -#ifndef GL_PIXEL_PACK_BUFFER -#define GL_PIXEL_PACK_BUFFER GL_PIXEL_PACK_BUFFER_ARB -#endif - -#endif - -static void -_cogl_pixel_array_free (CoglPixelArray *buffer); - -COGL_BUFFER_DEFINE (PixelArray, pixel_array) - -static CoglPixelArray * -_cogl_pixel_array_new (unsigned int size) -{ - CoglPixelArray *pixel_array = g_slice_new0 (CoglPixelArray); - CoglBuffer *buffer = COGL_BUFFER (pixel_array); - gboolean use_malloc; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - if (!cogl_features_available (COGL_FEATURE_PBOS)) - use_malloc = TRUE; - else - use_malloc = FALSE; - - /* parent's constructor */ - _cogl_buffer_initialize (buffer, - size, - use_malloc, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - COGL_BUFFER_USAGE_HINT_TEXTURE, - COGL_BUFFER_UPDATE_HINT_STATIC); - - /* return COGL_INVALID_HANDLE; */ - return _cogl_pixel_array_object_new (pixel_array); -} - -CoglPixelArray * -cogl_pixel_array_new_with_size (unsigned int width, - unsigned int height, - CoglPixelFormat format, - unsigned int *rowstride) -{ - CoglPixelArray *buffer; - CoglPixelArray *pixel_array; - unsigned int stride; - - /* creating a buffer to store "any" format does not make sense */ - if (G_UNLIKELY (format == COGL_PIXEL_FORMAT_ANY)) - return COGL_INVALID_HANDLE; - - /* for now we fallback to cogl_pixel_array_new, later, we could ask - * libdrm a tiled buffer for instance */ - stride = width * _cogl_get_format_bpp (format); - if (rowstride) - *rowstride = stride; - - buffer = _cogl_pixel_array_new (height * stride); - if (G_UNLIKELY (buffer == COGL_INVALID_HANDLE)) - return COGL_INVALID_HANDLE; - - pixel_array = COGL_PIXEL_ARRAY (buffer); - pixel_array->width = width; - pixel_array->height = height; - pixel_array->format = format; - pixel_array->stride = stride; - - return buffer; -} - -static void -_cogl_pixel_array_free (CoglPixelArray *buffer) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* parent's destructor */ - _cogl_buffer_fini (COGL_BUFFER (buffer)); - - g_slice_free (CoglPixelArray, buffer); -} - diff --git a/clutter/cogl/cogl/cogl-pixel-array.h b/clutter/cogl/cogl/cogl-pixel-array.h deleted file mode 100644 index 870ed9c..0000000 --- a/clutter/cogl/cogl/cogl-pixel-array.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Damien Lespiau - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_PIXEL_ARRAY_H__ -#define __COGL_PIXEL_ARRAY_H__ - -#include -#include - -G_BEGIN_DECLS - -/* All of the cogl-pixel-array API is currently experimental so we - * suffix the actual symbols with _EXP so if somone is monitoring for - * ABI changes it will hopefully be clearer to them what's going on if - * any of the symbols dissapear at a later date. - */ - -#define cogl_pixel_array_new cogl_pixel_array_new_EXP -#define cogl_pixel_array_new_with_size cogl_pixel_array_new_with_size_EXP -#define cogl_is_pixel_array cogl_is_pixel_array_EXP -#if 0 -#define cogl_pixel_array_set_region cogl_pixel_array_set_region_EXP -#endif - -typedef struct _CoglPixelArray CoglPixelArray; - -/** - * cogl_pixel_array_new_with_size: - * @width: width of the pixel array in pixels - * @height: height of the pixel array in pixels - * @format: the format of the pixels the array will store - * @stride: if not %NULL the function will return the stride of the array - * in bytes - * - * Creates a new array to store pixel data. - * - * COGL will try its best to provide a hardware array you can map, - * write into and effectively do a zero copy upload when creating a texture - * from it with cogl_texture_new_from_buffer(). For various reasons, such - * arrays are likely to have a stride larger than width * bytes_per_pixel. The - * user must take the stride into account when writing into it. - * - * Return value: a #CoglPixelArray representing the newly created array or - * %NULL on failure - * - * Since: 1.2 - * Stability: Unstable - */ -CoglPixelArray * -cogl_pixel_array_new_with_size (unsigned int width, - unsigned int height, - CoglPixelFormat format, - unsigned int *stride); - -/** - * cogl_is_pixel_array: - * @object: a #CoglObject to test - * - * Checks whether @handle is a pixel array. - * - * Return value: %TRUE if the @handle is a pixel array, and %FALSE - * otherwise - * - * Since: 1.2 - * Stability: Unstable - */ -gboolean -cogl_is_pixel_array (void *object); - -#if 0 -/* - * cogl_pixel_array_set_region: - * @array: the #CoglHandle of a pixel array - * @data: pixel data to upload to @array - * @src_width: width in pixels of the region to update - * @src_height: height in pixels of the region to update - * @src_rowstride: row stride in bytes of the source array - * @dst_x: upper left destination horizontal coordinate - * @dst_y: upper left destination vertical coordinate - * - * Uploads new data into a pixel array. The source data pointed by @data can - * have a different stride than @array in which case the function will do the - * right thing for you. For performance reasons, it is recommended for the - * source data to have the same stride than @array. - * - * Return value: %TRUE if the upload succeeded, %FALSE otherwise - * - * Since: 1.2 - * Stability: Unstable - */ -gboolean -cogl_pixel_array_set_region (CoglHandle array, - guint8 *data, - unsigned int src_width, - unsigned int src_height, - unsigned int src_rowstride, - unsigned int dst_x, - unsigned int dst_y); -#endif - -G_END_DECLS - -#endif /* __COGL_PIXEL_ARRAY_H__ */ diff --git a/clutter/cogl/cogl/cogl-point-in-poly-private.h b/clutter/cogl/cogl/cogl-point-in-poly-private.h deleted file mode 100644 index 6b534b6..0000000 --- a/clutter/cogl/cogl/cogl-point-in-poly-private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#ifndef __COGL_POINT_INT_POLYGON_PRIVATE_H -#define __COGL_POINT_INT_POLYGON_PRIVATE_H - -#include - -G_BEGIN_DECLS - -int -_cogl_util_point_in_screen_poly (float point_x, - float point_y, - void *vertices, - size_t stride, - int n_vertices); - -G_END_DECLS - -#endif /* __COGL_POINT_INT_POLYGON_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-point-in-poly.c b/clutter/cogl/cogl/cogl-point-in-poly.c deleted file mode 100644 index 87e090e..0000000 --- a/clutter/cogl/cogl/cogl-point-in-poly.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Point Inclusion in Polygon Test - * - * Copyright (c) 1970-2003, Wm. Randolph Franklin - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimers. - * 2. Redistributions in binary form must reproduce the above - * copyright notice in the documentation and/or other materials - * provided with the distribution. - * 3. The name of W. Randolph Franklin may not be used to endorse or - * promote products derived from this Software without specific - * prior written permission. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Note: - * The algorithm for this point_in_poly() function was learnt from: - * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-util.h" - -#include - -/* We've made a notable change to the original algorithm referenced - * above to make sure we have reliable results for screen aligned - * rectangles even though there may be some numerical in-precision in - * how the vertices of the polygon were calculated. - * - * We've avoided introducing an epsilon factor to the comparisons - * since we feel there's a risk of changing some semantics in ways that - * might not be desirable. One of those is that if you transform two - * polygons which share an edge and test a point close to that edge - * then this algorithm will currently give a positive result for only - * one polygon. - * - * Another concern is the way this algorithm resolves the corner case - * where the horizontal ray being cast to count edge crossings may - * cross directly through a vertex. The solution is based on the "idea - * of Simulation of Simplicity" and "pretends to shift the ray - * infinitesimally down so that it either clearly intersects, or - * clearly doesn't touch". I'm not familiar with the idea myself so I - * expect a misplaced epsilon is likely to break that aspect of the - * algorithm. - * - * The simple solution we've gone for is to pixel align the polygon - * vertices which should eradicate most noise due to in-precision. - */ -int -_cogl_util_point_in_screen_poly (float point_x, - float point_y, - void *vertices, - size_t stride, - int n_vertices) -{ - int i, j, c = 0; - - for (i = 0, j = n_vertices - 1; i < n_vertices; j = i++) - { - float vert_xi = *(float *)((guint8 *)vertices + i * stride); - float vert_xj = *(float *)((guint8 *)vertices + j * stride); - float vert_yi = *(float *)((guint8 *)vertices + i * stride + - sizeof (float)); - float vert_yj = *(float *)((guint8 *)vertices + j * stride + - sizeof (float)); - - vert_xi = COGL_UTIL_NEARBYINT (vert_xi); - vert_xj = COGL_UTIL_NEARBYINT (vert_xj); - vert_yi = COGL_UTIL_NEARBYINT (vert_yi); - vert_yj = COGL_UTIL_NEARBYINT (vert_yj); - - if (((vert_yi > point_y) != (vert_yj > point_y)) && - (point_x < (vert_xj - vert_xi) * (point_y - vert_yi) / - (vert_yj - vert_yi) + vert_xi) ) - c = !c; - } - - return c; -} - diff --git a/clutter/cogl/cogl/cogl-primitive-private.h b/clutter/cogl/cogl/cogl-primitive-private.h deleted file mode 100644 index 1569489..0000000 --- a/clutter/cogl/cogl/cogl-primitive-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PRIMITIVE_PRIVATE_H -#define __COGL_PRIMITIVE_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-vertex-array-private.h" - -struct _CoglPrimitive -{ - CoglObject _parent; - - CoglVerticesMode mode; - int first_vertex; - int n_vertices; - CoglIndices *indices; - GArray *attributes; - - int immutable_ref; -}; - -CoglPrimitive * -_cogl_primitive_immutable_ref (CoglPrimitive *primitive); - -void -_cogl_primitive_immutable_unref (CoglPrimitive *primitive); - -#endif /* __COGL_PRIMITIVE_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-primitive.c b/clutter/cogl/cogl/cogl-primitive.c deleted file mode 100644 index 9b76241..0000000 --- a/clutter/cogl/cogl/cogl-primitive.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-object-private.h" -#include "cogl-primitive.h" -#include "cogl-primitive-private.h" -#include "cogl-attribute-private.h" - -#include - -static void _cogl_primitive_free (CoglPrimitive *primitive); - -COGL_OBJECT_DEFINE (Primitive, primitive); - -/* XXX: should we have an n_attributes arg instead of NULL terminating? */ -CoglPrimitive * -cogl_primitive_new_with_attributes_array (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes) -{ - CoglPrimitive *primitive = g_slice_new (CoglPrimitive); - int i; - - primitive->mode = mode; - primitive->first_vertex = 0; - primitive->n_vertices = n_vertices; - primitive->indices = NULL; - primitive->attributes = - g_array_new (TRUE, FALSE, sizeof (CoglAttribute *)); - primitive->immutable_ref = 0; - - for (i = 0; attributes[i]; i++) - { - CoglAttribute *attribute = attributes[i]; - cogl_object_ref (attribute); - - g_return_val_if_fail (cogl_is_attribute (attribute), NULL); - - g_array_append_val (primitive->attributes, attribute); - } - - return _cogl_primitive_object_new (primitive); -} - -/* This is just an internal convenience wrapper around - new_with_attributes that also unrefs the attributes. It is just - used for the builtin struct constructors */ -static CoglPrimitive * -_cogl_primitive_new_with_attributes_array_unref (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes) -{ - CoglPrimitive *primitive; - int i; - - primitive = cogl_primitive_new_with_attributes_array (mode, - n_vertices, - attributes); - - for (i = 0; attributes[i]; i++) - cogl_object_unref (attributes[i]); - - return primitive; -} - -CoglPrimitive * -cogl_primitive_new (CoglVerticesMode mode, - int n_vertices, - ...) -{ - va_list ap; - int n_attributes; - CoglAttribute **attributes; - int i; - CoglAttribute *attribute; - - va_start (ap, n_vertices); - for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++) - ; - va_end (ap); - - attributes = g_alloca (sizeof (CoglAttribute *) * (n_attributes + 1)); - attributes[n_attributes] = NULL; - - va_start (ap, n_vertices); - for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++) - attributes[i] = attribute; - va_end (ap); - - return cogl_primitive_new_with_attributes_array (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p2 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP2), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP2), - offsetof (CoglVertexP2, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p3 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP3), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP3), - offsetof (CoglVertexP3, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p2c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2C4 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP2C4), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP2C4), - offsetof (CoglVertexP2C4, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (array, - "cogl_color_in", - sizeof (CoglVertexP2C4), - offsetof (CoglVertexP2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - attributes[2] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p3c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3C4 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP3C4), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP3C4), - offsetof (CoglVertexP3C4, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (array, - "cogl_color_in", - sizeof (CoglVertexP3C4), - offsetof (CoglVertexP3C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - attributes[2] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p2t2 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP2T2), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP2T2), - offsetof (CoglVertexP2T2, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (array, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2T2), - offsetof (CoglVertexP2T2, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p3t2 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP3T2), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP3T2), - offsetof (CoglVertexP3T2, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (array, - "cogl_tex_coord0_in", - sizeof (CoglVertexP3T2), - offsetof (CoglVertexP3T2, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p2t2c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2C4 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP2T2C4), data); - CoglAttribute *attributes[4]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (array, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = cogl_attribute_new (array, - "cogl_color_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - attributes[3] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -CoglPrimitive * -cogl_primitive_new_p3t2c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2C4 *data) -{ - CoglVertexArray *array = - cogl_vertex_array_new (n_vertices * sizeof (CoglVertexP3T2C4), data); - CoglAttribute *attributes[4]; - - attributes[0] = cogl_attribute_new (array, - "cogl_position_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (array, - "cogl_tex_coord0_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = cogl_attribute_new (array, - "cogl_color_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - attributes[3] = NULL; - - cogl_object_unref (array); - - return _cogl_primitive_new_with_attributes_array_unref (mode, n_vertices, - attributes); -} - -static void -free_attributes_list (CoglPrimitive *primitive) -{ - int i; - - for (i = 0; i < primitive->attributes->len; i++) - { - CoglAttribute *attribute = - g_array_index (primitive->attributes, CoglAttribute *, i); - cogl_object_unref (attribute); - } - g_array_set_size (primitive->attributes, 0); -} - -static void -_cogl_primitive_free (CoglPrimitive *primitive) -{ - free_attributes_list (primitive); - - g_array_free (primitive->attributes, TRUE); - - g_slice_free (CoglPrimitive, primitive); -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of buffers has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_primitive_set_attributes (CoglPrimitive *primitive, - CoglAttribute **attributes) -{ - int i; - - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - free_attributes_list (primitive); - - g_array_set_size (primitive->attributes, 0); - for (i = 0; attributes[i]; i++) - { - cogl_object_ref (attributes[i]); - g_return_if_fail (cogl_is_attribute (attributes[i])); - g_array_append_val (primitive->attributes, attributes[i]); - } -} - -int -cogl_primitive_get_first_vertex (CoglPrimitive *primitive) -{ - g_return_val_if_fail (cogl_is_primitive (primitive), 0); - - return primitive->first_vertex; -} - -void -cogl_primitive_set_first_vertex (CoglPrimitive *primitive, - int first_vertex) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - primitive->first_vertex = first_vertex; -} - -int -cogl_primitive_get_n_vertices (CoglPrimitive *primitive) -{ - g_return_val_if_fail (cogl_is_primitive (primitive), 0); - - return primitive->n_vertices; -} - -void -cogl_primitive_set_n_vertices (CoglPrimitive *primitive, - int n_vertices) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - primitive->n_vertices = n_vertices; -} - -CoglVerticesMode -cogl_primitive_get_mode (CoglPrimitive *primitive) -{ - g_return_val_if_fail (cogl_is_primitive (primitive), 0); - - return primitive->mode; -} - -void -cogl_primitive_set_mode (CoglPrimitive *primitive, - CoglVerticesMode mode) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - primitive->mode = mode; -} - -void -cogl_primitive_set_indices (CoglPrimitive *primitive, - CoglIndices *indices) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - if (indices) - cogl_object_ref (indices); - if (primitive->indices) - cogl_object_unref (primitive->indices); - primitive->indices = indices; -} - -CoglPrimitive * -_cogl_primitive_immutable_ref (CoglPrimitive *primitive) -{ - int i; - - g_return_val_if_fail (cogl_is_primitive (primitive), NULL); - - primitive->immutable_ref++; - - for (i = 0; i < primitive->attributes->len; i++) - { - CoglAttribute *attribute = - g_array_index (primitive->attributes, CoglAttribute *, i); - _cogl_attribute_immutable_ref (attribute); - } - - return primitive; -} - -void -_cogl_primitive_immutable_unref (CoglPrimitive *primitive) -{ - int i; - - g_return_if_fail (cogl_is_primitive (primitive)); - g_return_if_fail (primitive->immutable_ref > 0); - - primitive->immutable_ref--; - - for (i = 0; i < primitive->attributes->len; i++) - { - CoglAttribute *attribute = - g_array_index (primitive->attributes, CoglAttribute *, i); - _cogl_attribute_immutable_unref (attribute); - } -} - -/* XXX: cogl_draw_primitive() ? */ -void -cogl_primitive_draw (CoglPrimitive *primitive) -{ - CoglAttribute **attributes = - (CoglAttribute **)primitive->attributes->data; - - if (primitive->indices) - cogl_draw_indexed_attributes_array (primitive->mode, - primitive->first_vertex, - primitive->n_vertices, - primitive->indices, - attributes); - else - cogl_draw_attributes_array (primitive->mode, - primitive->first_vertex, - primitive->n_vertices, - attributes); -} - diff --git a/clutter/cogl/cogl/cogl-primitive.h b/clutter/cogl/cogl/cogl-primitive.h deleted file mode 100644 index d286841..0000000 --- a/clutter/cogl/cogl/cogl-primitive.h +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_PRIMITIVE_H__ -#define __COGL_PRIMITIVE_H__ - -#include /* for CoglVerticesMode */ -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-primitive - * @short_description: Functions for creating, manipulating and drawing - * primitives - * - * FIXME - */ - -typedef struct _CoglPrimitive CoglPrimitive; - -/** - * CoglVertexP2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v2_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y; -} CoglVertexP2; - -/** - * CoglVertexP3: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v3_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y, z; -} CoglVertexP3; - -/** - * CoglVertexP2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v2c4_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y; - guint8 r, g, b, a; -} CoglVertexP2C4; - -/** - * CoglVertexP3C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v3c4_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y, z; - guint8 r, g, b, a; -} CoglVertexP3C4; - -/** - * CoglVertexP2T2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v2t2_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y; - float s, t; -} CoglVertexP2T2; - -/** - * CoglVertexP3T2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v3t2_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y, z; - float s, t; -} CoglVertexP3T2; - - -/** - * CoglVertexP2T2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v3t2c4_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y; - float s, t; - guint8 r, g, b, a; -} CoglVertexP2T2C4; - -/** - * CoglVertexP3T2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_with_v3t2c4_attributes(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct -{ - float x, y, z; - float s, t; - guint8 r, g, b, a; -} CoglVertexP3T2C4; - -/** - * cogl_primitive_new: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @Varargs: A %NULL terminated list of attributes - * - * Combines a set of #CoglAttributes with a specific draw @mode - * and defines a vertex count so a #CoglPrimitive object can be retained and - * drawn later with no addition information required. - * - * Returns: A newly allocated #CoglPrimitive object - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new (CoglVerticesMode mode, - int n_vertices, - ...); - -/* XXX: how about just: cogl_primitive_new_with_attributes () ? */ -CoglPrimitive * -cogl_primitive_new_with_attributes_array (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes); - -/** - * cogl_primitive_new_p2: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position - * attribute with a #CoglAttribute and upload your data. - * - * For example to draw a convex polygon you can do: - * |[ - * CoglVertexP2 triangle[] = - * { - * { 0, 300 }, - * { 150, 0, }, - * { 300, 300 } - * }; - * prim = cogl_primitive_new_p2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p2 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2 *data); - -/** - * cogl_primitive_new_p3: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP3 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position - * attribute with a #CoglAttribute and upload your data. - * - * For example to draw a convex polygon you can do: - * |[ - * CoglVertexP3 triangle[] = - * { - * { 0, 300, 0 }, - * { 150, 0, 0 }, - * { 300, 300, 0 } - * }; - * prim = cogl_primitive_new_p3 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p3 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3 *data); - -/** - * cogl_primitive_new_p2c4: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position - * and color attributes with #CoglAttributes and upload - * your data. - * - * For example to draw a convex polygon with a linear gradient you - * can do: - * |[ - * CoglVertexP2C4 triangle[] = - * { - * { 0, 300, 0xff, 0x00, 0x00, 0xff }, - * { 150, 0, 0x00, 0xff, 0x00, 0xff }, - * { 300, 300, 0xff, 0x00, 0x00, 0xff } - * }; - * prim = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p2c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2C4 *data); - -/** - * cogl_primitive_new_p3c4: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP3C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position - * and color attributes with #CoglAttributes and upload - * your data. - * - * For example to draw a convex polygon with a linear gradient you - * can do: - * |[ - * CoglVertexP3C4 triangle[] = - * { - * { 0, 300, 0, 0xff, 0x00, 0x00, 0xff }, - * { 150, 0, 0, 0x00, 0xff, 0x00, 0xff }, - * { 300, 300, 0, 0xff, 0x00, 0x00, 0xff } - * }; - * prim = cogl_primitive_new_p3c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p3c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3C4 *data); - -/** - * cogl_primitive_new_p2t2: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP2T2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position and - * texture coordinate attributes with #CoglAttributes and - * upload your data. - * - * For example to draw a convex polygon with texture mapping you can - * do: - * |[ - * CoglVertexP2T2 triangle[] = - * { - * { 0, 300, 0.0, 1.0}, - * { 150, 0, 0.5, 0.0}, - * { 300, 300, 1.0, 1.0} - * }; - * prim = cogl_primitive_new_p2t2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p2t2 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2 *data); - -/** - * cogl_primitive_new_p3t2: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP3T2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position and - * texture coordinate attributes with #CoglAttributes and - * upload your data. - * - * For example to draw a convex polygon with texture mapping you can - * do: - * |[ - * CoglVertexP3T2 triangle[] = - * { - * { 0, 300, 0, 0.0, 1.0}, - * { 150, 0, 0, 0.5, 0.0}, - * { 300, 300, 0, 1.0, 1.0} - * }; - * prim = cogl_primitive_new_p3t2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p3t2 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2 *data); - -/** - * cogl_primitive_new_p2t2c4: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP2T2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position, texture - * coordinate and color attributes with #CoglAttributes and - * upload your data. - * - * For example to draw a convex polygon with texture mapping and a - * linear gradient you can do: - * |[ - * CoglVertexP2T2C4 triangle[] = - * { - * { 0, 300, 0.0, 1.0, 0xff, 0x00, 0x00, 0xff}, - * { 150, 0, 0.5, 0.0, 0x00, 0xff, 0x00, 0xff}, - * { 300, 300, 1.0, 1.0, 0xff, 0x00, 0x00, 0xff} - * }; - * prim = cogl_primitive_new_p2t2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p2t2c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2C4 *data); - -/** - * cogl_primitive_new_p3t2c4: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @data: An array of #CoglVertexP3T2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglVertexArray storage, describe the position, texture - * coordinate and color attributes with #CoglAttributes and - * upload your data. - * - * For example to draw a convex polygon with texture mapping and a - * linear gradient you can do: - * |[ - * CoglVertexP3T2C4 triangle[] = - * { - * { 0, 300, 0, 0.0, 1.0, 0xff, 0x00, 0x00, 0xff}, - * { 150, 0, 0, 0.5, 0.0, 0x00, 0xff, 0x00, 0xff}, - * { 300, 300, 0, 1.0, 1.0, 0xff, 0x00, 0x00, 0xff} - * }; - * prim = cogl_primitive_new_p3t2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square) - * - * Return value: A newly allocated #CoglPrimitive with a reference of - * 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -CoglPrimitive * -cogl_primitive_new_p3t2c4 (CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2C4 *data); -int -cogl_primitive_get_first_vertex (CoglPrimitive *primitive); - -void -cogl_primitive_set_first_vertex (CoglPrimitive *primitive, - int first_vertex); - -int -cogl_primitive_get_n_vertices (CoglPrimitive *primitive); - -void -cogl_primitive_set_n_vertices (CoglPrimitive *primitive, - int n_vertices); - -CoglVerticesMode -cogl_primitive_get_mode (CoglPrimitive *primitive); - -void -cogl_primitive_set_mode (CoglPrimitive *primitive, - CoglVerticesMode mode); - -/** - * cogl_primitive_set_attributes: - * @primitive: A #CoglPrimitive object - * @attributes: A %NULL terminated array of #CoglAttribute - * pointers - * - * Replaces all the attributes of the given #CoglPrimitive object. - * - * Since: 1.6 - * Stability: Unstable - */ -void -cogl_primitive_set_attributes (CoglPrimitive *primitive, - CoglAttribute **attributes); - - -void -cogl_primitive_set_indices (CoglPrimitive *primitive, - CoglIndices *indices); - -/** - * cogl_primitive_draw: - * @primitive: A #CoglPrimitive object - * - * Draw the given @primitive with the current source material. - * - * Since: 1.6 - * Stability: Unstable - */ -void -cogl_primitive_draw (CoglPrimitive *primitive); - -/** - * cogl_is_primitive: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglPrimitive. - * - * Returns: %TRUE if the handle references a #CoglPrimitive, - * %FALSE otherwise - * - * Since: 1.6 - * Stability: Unstable - */ -gboolean -cogl_is_primitive (void *object); - -G_END_DECLS - -#endif /* __COGL_PRIMITIVE_H__ */ - diff --git a/clutter/cogl/cogl/cogl-primitives-private.h b/clutter/cogl/cogl/cogl-primitives-private.h deleted file mode 100644 index debd90c..0000000 --- a/clutter/cogl/cogl/cogl-primitives-private.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_PRIMITIVES_PRIVATE_H -#define __COGL_PRIMITIVES_PRIVATE_H - -#include - -G_BEGIN_DECLS - -/* Draws a rectangle without going through the journal so that it will - be flushed immediately. This should only be used in situations - where the code may be called while the journal is already being - flushed. In that case using the journal would go wrong */ -void -_cogl_rectangle_immediate (float x_1, - float y_1, - float x_2, - float y_2); - -G_END_DECLS - -#endif /* __COGL_PRIMITIVES_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-primitives.c b/clutter/cogl/cogl/cogl-primitives.c deleted file mode 100644 index 2931126..0000000 --- a/clutter/cogl/cogl/cogl-primitives.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-journal-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-vertex-buffer-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-attribute-private.h" - -#include -#include - -#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 - -#ifdef HAVE_COGL_GL -#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture -#endif - - -typedef struct _TextureSlicedQuadState -{ - CoglPipeline *pipeline; - CoglHandle main_texture; - float tex_virtual_origin_x; - float tex_virtual_origin_y; - float quad_origin_x; - float quad_origin_y; - float v_to_q_scale_x; - float v_to_q_scale_y; - float quad_len_x; - float quad_len_y; - gboolean flipped_x; - gboolean flipped_y; -} TextureSlicedQuadState; - -typedef struct _TextureSlicedPolygonState -{ - const CoglTextureVertex *vertices; - int n_vertices; - int stride; - CoglAttribute **attributes; -} TextureSlicedPolygonState; - -static void -log_quad_sub_textures_cb (CoglHandle texture_handle, - const float *subtexture_coords, - const float *virtual_coords, - void *user_data) -{ - TextureSlicedQuadState *state = user_data; - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - CoglHandle texture_override; - float quad_coords[4]; - -#define TEX_VIRTUAL_TO_QUAD(V, Q, AXIS) \ - do { \ - Q = V - state->tex_virtual_origin_##AXIS; \ - Q *= state->v_to_q_scale_##AXIS; \ - if (state->flipped_##AXIS) \ - Q = state->quad_len_##AXIS - Q; \ - Q += state->quad_origin_##AXIS; \ - } while (0); - - TEX_VIRTUAL_TO_QUAD (virtual_coords[0], quad_coords[0], x); - TEX_VIRTUAL_TO_QUAD (virtual_coords[1], quad_coords[1], y); - - TEX_VIRTUAL_TO_QUAD (virtual_coords[2], quad_coords[2], x); - TEX_VIRTUAL_TO_QUAD (virtual_coords[3], quad_coords[3], y); - -#undef TEX_VIRTUAL_TO_QUAD - - COGL_NOTE (DRAW, - "~~~~~ slice\n" - "qx1: %f\t" - "qy1: %f\n" - "qx2: %f\t" - "qy2: %f\n" - "tx1: %f\t" - "ty1: %f\n" - "tx2: %f\t" - "ty2: %f\n", - quad_coords[0], quad_coords[1], - quad_coords[2], quad_coords[3], - subtexture_coords[0], subtexture_coords[1], - subtexture_coords[2], subtexture_coords[3]); - - /* We only need to override the texture if it's different from the - main texture */ - if (texture_handle == state->main_texture) - texture_override = COGL_INVALID_HANDLE; - else - texture_override = texture_handle; - - _cogl_journal_log_quad (framebuffer->journal, - quad_coords, - state->pipeline, - 1, /* one layer */ - texture_override, /* replace the layer0 texture */ - subtexture_coords, - 4); -} - -typedef struct _ValidateFirstLayerState -{ - CoglPipeline *override_pipeline; -} ValidateFirstLayerState; - -static gboolean -validate_first_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateFirstLayerState *state = user_data; - CoglPipelineWrapMode clamp_to_edge = - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - - /* We can't use hardware repeat so we need to set clamp to edge - * otherwise it might pull in edge pixels from the other side. By - * default WRAP_MODE_AUTOMATIC becomes CLAMP_TO_EDGE so we only need - * to override if the wrap mode is repeat. - */ - if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_REPEAT) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_s (pipeline, layer_index, - clamp_to_edge); - } - if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_REPEAT) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_t (pipeline, layer_index, - clamp_to_edge); - } - - return FALSE; -} - -/* This path doesn't currently support multitexturing but is used for - * CoglTextures that don't support repeating using the GPU so we need to - * manually emit extra geometry to fake the repeating. This includes: - * - * - CoglTexture2DSliced: when made of > 1 slice or if the users given - * texture coordinates require repeating, - * - CoglTexture2DAtlas: if the users given texture coordinates require - * repeating, - * - CoglTextureRectangle: if the users given texture coordinates require - * repeating, - * - CoglTexturePixmap: if the users given texture coordinates require - * repeating - */ -/* TODO: support multitexturing */ -static void -_cogl_texture_quad_multiple_primitives (CoglHandle tex_handle, - CoglPipeline *pipeline, - gboolean clamp_s, - gboolean clamp_t, - const float *position, - float tx_1, - float ty_1, - float tx_2, - float ty_2) -{ - TextureSlicedQuadState state; - gboolean tex_virtual_flipped_x; - gboolean tex_virtual_flipped_y; - gboolean quad_flipped_x; - gboolean quad_flipped_y; - ValidateFirstLayerState validate_first_layer_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If the wrap mode is clamp to edge then we'll recursively draw the - stretched part and replace the coordinates */ - if (clamp_s && tx_1 != tx_2) - { - float *replacement_position = g_newa (float, 4); - float old_tx_1 = tx_1, old_tx_2 = tx_2; - - memcpy (replacement_position, position, sizeof (float) * 4); - - tx_1 = CLAMP (tx_1, 0.0f, 1.0f); - tx_2 = CLAMP (tx_2, 0.0f, 1.0f); - - if (old_tx_1 != tx_1) - { - /* Draw the left part of the quad as a stretched copy of tx_1 */ - float tmp_position[] = - { position[0], position[1], - (position[0] + - (position[2] - position[0]) * - (tx_1 - old_tx_1) / (old_tx_2 - old_tx_1)), - position[3] }; - _cogl_texture_quad_multiple_primitives (tex_handle, pipeline, - FALSE, clamp_t, - tmp_position, - tx_1, ty_1, tx_1, ty_2); - replacement_position[0] = tmp_position[2]; - } - - if (old_tx_2 != tx_2) - { - /* Draw the right part of the quad as a stretched copy of tx_2 */ - float tmp_position[] = - { (position[0] + - (position[2] - position[0]) * - (tx_2 - old_tx_1) / (old_tx_2 - old_tx_1)), - position[1], position[2], position[3] }; - _cogl_texture_quad_multiple_primitives (tex_handle, pipeline, - FALSE, clamp_t, - tmp_position, - tx_2, ty_1, tx_2, ty_2); - replacement_position[2] = tmp_position[0]; - } - - /* If there's no main part left then we don't need to continue */ - if (tx_1 == tx_2) - return; - - position = replacement_position; - } - - if (clamp_t && ty_1 != ty_2) - { - float *replacement_position = g_newa (float, 4); - float old_ty_1 = ty_1, old_ty_2 = ty_2; - - memcpy (replacement_position, position, sizeof (float) * 4); - - ty_1 = CLAMP (ty_1, 0.0f, 1.0f); - ty_2 = CLAMP (ty_2, 0.0f, 1.0f); - - if (old_ty_1 != ty_1) - { - /* Draw the top part of the quad as a stretched copy of ty_1 */ - float tmp_position[] = - { position[0], position[1], position[2], - (position[1] + - (position[3] - position[1]) * - (ty_1 - old_ty_1) / (old_ty_2 - old_ty_1)) }; - _cogl_texture_quad_multiple_primitives (tex_handle, pipeline, - clamp_s, FALSE, - tmp_position, - tx_1, ty_1, tx_2, ty_1); - replacement_position[1] = tmp_position[3]; - } - - if (old_ty_2 != ty_2) - { - /* Draw the bottom part of the quad as a stretched copy of ty_2 */ - float tmp_position[] = - { position[0], - (position[1] + - (position[3] - position[1]) * - (ty_2 - old_ty_1) / (old_ty_2 - old_ty_1)), - position[2], position[3] }; - _cogl_texture_quad_multiple_primitives (tex_handle, pipeline, - clamp_s, FALSE, - tmp_position, - tx_1, ty_2, tx_2, ty_2); - replacement_position[3] = tmp_position[1]; - } - - /* If there's no main part left then we don't need to continue */ - if (ty_1 == ty_2) - return; - - position = replacement_position; - } - - validate_first_layer_state.override_pipeline = NULL; - cogl_pipeline_foreach_layer (pipeline, - validate_first_layer_cb, - &validate_first_layer_state); - - state.main_texture = tex_handle; - - if (validate_first_layer_state.override_pipeline) - state.pipeline = validate_first_layer_state.override_pipeline; - else - state.pipeline = pipeline; - - /* Get together the data we need to transform the virtual texture - * coordinates of each slice into quad coordinates... - * - * NB: We need to consider that the quad coordinates and the texture - * coordinates may be inverted along the x or y axis, and must preserve the - * inversions when we emit the final geometry. - */ - -#define X0 0 -#define Y0 1 -#define X1 2 -#define Y1 3 - - tex_virtual_flipped_x = (tx_1 > tx_2) ? TRUE : FALSE; - tex_virtual_flipped_y = (ty_1 > ty_2) ? TRUE : FALSE; - state.tex_virtual_origin_x = tex_virtual_flipped_x ? tx_2 : tx_1; - state.tex_virtual_origin_y = tex_virtual_flipped_y ? ty_2 : ty_1; - - quad_flipped_x = (position[X0] > position[X1]) ? TRUE : FALSE; - quad_flipped_y = (position[Y0] > position[Y1]) ? TRUE : FALSE; - state.quad_origin_x = quad_flipped_x ? position[X1] : position[X0]; - state.quad_origin_y = quad_flipped_y ? position[Y1] : position[Y0]; - - /* flatten the two forms of coordinate inversion into one... */ - state.flipped_x = tex_virtual_flipped_x ^ quad_flipped_x; - state.flipped_y = tex_virtual_flipped_y ^ quad_flipped_y; - - /* We use the _len_AXIS naming here instead of _width and _height because - * log_quad_slice_cb uses a macro with symbol concatenation to handle both - * axis, so this is more convenient... */ - state.quad_len_x = fabs (position[X1] - position[X0]); - state.quad_len_y = fabs (position[Y1] - position[Y0]); - -#undef X0 -#undef Y0 -#undef X1 -#undef Y1 - - state.v_to_q_scale_x = fabs (state.quad_len_x / (tx_2 - tx_1)); - state.v_to_q_scale_y = fabs (state.quad_len_y / (ty_2 - ty_1)); - - _cogl_texture_foreach_sub_texture_in_region (tex_handle, - tx_1, ty_1, tx_2, ty_2, - log_quad_sub_textures_cb, - &state); - - if (validate_first_layer_state.override_pipeline) - cogl_object_unref (validate_first_layer_state.override_pipeline); -} - -typedef struct _ValidateTexCoordsState -{ - int i; - int n_layers; - const float *user_tex_coords; - int user_tex_coords_len; - float *final_tex_coords; - CoglPipeline *override_pipeline; - gboolean needs_multiple_primitives; -} ValidateTexCoordsState; - -/* - * Validate the texture coordinates for this rectangle. - */ -static gboolean -validate_tex_coords_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateTexCoordsState *state = user_data; - CoglHandle texture; - const float *in_tex_coords; - float *out_tex_coords; - float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0}; - CoglTransformResult transform_result; - - state->i++; - - texture = _cogl_pipeline_get_layer_texture (pipeline, layer_index); - - /* NB: NULL textures are handled by _cogl_pipeline_flush_gl_state */ - if (!texture) - return TRUE; - - /* FIXME: we should be able to avoid this copying when no - * transform is required by the texture backend and the user - * has supplied enough coordinates for all the layers. - */ - - /* If the user didn't supply texture coordinates for this layer - then use the default coords */ - if (state->i >= state->user_tex_coords_len / 4) - in_tex_coords = default_tex_coords; - else - in_tex_coords = &state->user_tex_coords[state->i * 4]; - - out_tex_coords = &state->final_tex_coords[state->i * 4]; - - memcpy (out_tex_coords, in_tex_coords, sizeof (float) * 4); - - /* Convert the texture coordinates to GL. - */ - transform_result = - _cogl_texture_transform_quad_coords_to_gl (texture, - out_tex_coords); - /* If the texture has waste or we are using GL_TEXTURE_RECT we - * can't handle texture repeating so we can't use the layer if - * repeating is required. - * - * NB: We already know that no texture matrix is being used if the - * texture doesn't support hardware repeat. - */ - if (transform_result == COGL_TRANSFORM_SOFTWARE_REPEAT) - { - if (state->i == 0) - { - if (state->n_layers > 1) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("Skipping layers 1..n of your material since " - "the first layer doesn't support hardware " - "repeat (e.g. because of waste or use of " - "GL_TEXTURE_RECTANGLE_ARB) and you supplied " - "texture coordinates outside the range [0,1]." - "Falling back to software repeat assuming " - "layer 0 is the most important one keep"); - warning_seen = TRUE; - } - - if (state->override_pipeline) - cogl_object_unref (state->override_pipeline); - state->needs_multiple_primitives = TRUE; - return FALSE; - } - else - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("Skipping layer %d of your material " - "since you have supplied texture coords " - "outside the range [0,1] but the texture " - "doesn't support hardware repeat (e.g. " - "because of waste or use of " - "GL_TEXTURE_RECTANGLE_ARB). This isn't " - "supported with multi-texturing.", state->i); - warning_seen = TRUE; - - cogl_pipeline_set_layer_texture (texture, layer_index, NULL); - } - } - - /* By default WRAP_MODE_AUTOMATIC becomes to CLAMP_TO_EDGE. If - the texture coordinates need repeating then we'll override - this to GL_REPEAT. Otherwise we'll leave it at CLAMP_TO_EDGE - so that it won't blend in pixels from the opposite side when - the full texture is drawn with GL_LINEAR filter mode */ - if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT) - { - if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_s (state->override_pipeline, - layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_t (state->override_pipeline, - layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - } - - return TRUE; -} - -/* This path supports multitexturing but only when each of the layers is - * handled with a single GL texture. Also if repeating is necessary then - * _cogl_texture_can_hardware_repeat() must return TRUE. - * This includes layers made from: - * - * - CoglTexture2DSliced: if only comprised of a single slice with optional - * waste, assuming the users given texture coordinates don't require - * repeating. - * - CoglTexture{1D,2D,3D}: always. - * - CoglTexture2DAtlas: assuming the users given texture coordinates don't - * require repeating. - * - CoglTextureRectangle: assuming the users given texture coordinates don't - * require repeating. - * - CoglTexturePixmap: assuming the users given texture coordinates don't - * require repeating. - */ -static gboolean -_cogl_multitexture_quad_single_primitive (const float *position, - CoglPipeline *pipeline, - const float *user_tex_coords, - int user_tex_coords_len) -{ - int n_layers = cogl_pipeline_get_n_layers (pipeline); - ValidateTexCoordsState state; - float *final_tex_coords = alloca (sizeof (float) * 4 * n_layers); - CoglFramebuffer *framebuffer; - - _COGL_GET_CONTEXT (ctx, FALSE); - - state.i = -1; - state.n_layers = n_layers; - state.user_tex_coords = user_tex_coords; - state.user_tex_coords_len = user_tex_coords_len; - state.final_tex_coords = final_tex_coords; - state.override_pipeline = NULL; - state.needs_multiple_primitives = FALSE; - - cogl_pipeline_foreach_layer (pipeline, - validate_tex_coords_cb, - &state); - - if (state.needs_multiple_primitives) - return FALSE; - - if (state.override_pipeline) - pipeline = state.override_pipeline; - - framebuffer = cogl_get_draw_framebuffer (); - _cogl_journal_log_quad (framebuffer->journal, - position, - pipeline, - n_layers, - COGL_INVALID_HANDLE, /* no texture override */ - final_tex_coords, - n_layers * 4); - - if (state.override_pipeline) - cogl_object_unref (state.override_pipeline); - - return TRUE; -} - -typedef struct _ValidateLayerState -{ - int i; - int first_layer; - CoglPipeline *override_source; - gboolean all_use_sliced_quad_fallback; -} ValidateLayerState; - -static gboolean -_cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateLayerState *state = user_data; - CoglHandle texture; - - state->i++; - - /* We need to ensure the mipmaps are ready before deciding - * anything else about the texture because the texture storage - * could completely change if it needs to be migrated out of the - * atlas and will affect how we validate the layer. - * - * FIXME: this needs to be generalized. There could be any - * number of things that might require a shuffling of the - * underlying texture storage. We could add two mechanisms to - * generalize this a bit... - * - * 1) add a _cogl_pipeline_layer_update_storage() function that - * would for instance consider if mipmapping is necessary and - * potentially migrate the texture from an atlas. - * - * 2) allow setting of transient primitive-flags on a pipeline - * that may affect the outcome of _update_storage(). One flag - * could indicate that we expect to sample beyond the bounds of - * the texture border. - * - * flags = COGL_PIPELINE_PRIMITIVE_FLAG_VALID_BORDERS; - * _cogl_pipeline_layer_assert_primitive_flags (layer, flags) - * _cogl_pipeline_layer_update_storage (layer) - * enqueue primitive in journal - * - * when the primitive is dequeued and drawn we should: - * _cogl_pipeline_flush_gl_state (pipeline) - * draw primitive - * _cogl_pipeline_unassert_primitive_flags (layer, flags); - * - * _cogl_pipeline_layer_update_storage should take into - * consideration all the asserted primitive requirements. (E.g. - * there could be multiple primitives in the journal - or in a - * renderlist in the future - that need mipmaps or that need - * valid contents beyond their borders (for cogl_polygon) - * meaning they can't work with textures in an atas, so - * _cogl_pipeline_layer_update_storage would pass on these - * requirements to the texture atlas backend which would make - * sure the referenced texture is migrated out of the atlas and - * mipmaps are generated.) - */ - _cogl_pipeline_pre_paint_for_layer (pipeline, layer_index); - - texture = _cogl_pipeline_get_layer_texture (pipeline, layer_index); - - /* COGL_INVALID_HANDLE textures are handled by - * _cogl_pipeline_flush_gl_state */ - if (texture == COGL_INVALID_HANDLE) - return TRUE; - - if (state->i == 0) - state->first_layer = layer_index; - - /* XXX: - * For now, if the first layer is sliced then all other layers are - * ignored since we currently don't support multi-texturing with - * sliced textures. If the first layer is not sliced then any other - * layers found to be sliced will be skipped. (with a warning) - * - * TODO: Add support for multi-texturing rectangles with sliced - * textures if no texture matrices are in use. - */ - if (cogl_texture_is_sliced (texture)) - { - if (state->i == 0) - { - static gboolean warning_seen = FALSE; - - if (!state->override_source) - state->override_source = cogl_pipeline_copy (pipeline); - _cogl_pipeline_prune_to_n_layers (state->override_source, 1); - state->all_use_sliced_quad_fallback = TRUE; - - if (!warning_seen) - g_warning ("Skipping layers 1..n of your pipeline since " - "the first layer is sliced. We don't currently " - "support any multi-texturing with sliced " - "textures but assume layer 0 is the most " - "important to keep"); - warning_seen = TRUE; - - return FALSE; - } - else - { - static gboolean warning_seen = FALSE; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!warning_seen) - g_warning ("Skipping layer %d of your pipeline consisting of " - "a sliced texture (unsuported for multi texturing)", - state->i); - warning_seen = TRUE; - - /* Note: currently only 2D textures can be sliced. */ - cogl_pipeline_set_layer_texture (pipeline, layer_index, - ctx->default_gl_texture_2d_tex); - return TRUE; - } - } - -#ifdef COGL_ENABLE_DEBUG - /* If the texture can't be repeated with the GPU (e.g. because it has - * waste or if using GL_TEXTURE_RECTANGLE_ARB) then if a texture matrix - * is also in use we don't know if the result will end up trying - * to texture from the waste area. - * - * Note: we check can_hardware_repeat() first since it's cheaper. - * - * Note: cases where the texture coordinates will require repeating - * will be caught by later validation. - */ - if (!_cogl_texture_can_hardware_repeat (texture) && - _cogl_pipeline_layer_has_user_matrix (pipeline, layer_index)) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("layer %d of your pipeline uses a custom " - "texture matrix but because the texture doesn't " - "support hardware repeating you may see artefacts " - "due to sampling beyond the texture's bounds.", - state->i); - warning_seen = TRUE; - } -#endif - - return TRUE; -} - -struct _CoglMutiTexturedRect -{ - const float *position; /* x0,y0,x1,y1 */ - const float *tex_coords; /* (tx0,ty0,tx1,ty1)(tx0,ty0,tx1,ty1)(... */ - int tex_coords_len; /* number of floats in tex_coords? */ -}; - -static void -_cogl_rectangles_with_multitexture_coords ( - struct _CoglMutiTexturedRect *rects, - int n_rects) -{ - CoglPipeline *pipeline; - ValidateLayerState state; - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - pipeline = cogl_get_source (); - - /* - * Validate all the layers of the current source pipeline... - */ - state.i = -1; - state.first_layer = 0; - state.override_source = NULL; - state.all_use_sliced_quad_fallback = FALSE; - cogl_pipeline_foreach_layer (pipeline, - _cogl_rectangles_validate_layer_cb, - &state); - - if (state.override_source) - pipeline = state.override_source; - - /* - * Emit geometry for each of the rectangles... - */ - - for (i = 0; i < n_rects; i++) - { - CoglHandle texture; - const float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0}; - const float *tex_coords; - gboolean clamp_s, clamp_t; - - if (!state.all_use_sliced_quad_fallback) - { - gboolean success = - _cogl_multitexture_quad_single_primitive (rects[i].position, - pipeline, - rects[i].tex_coords, - rects[i].tex_coords_len); - - /* NB: If _cogl_multitexture_quad_single_primitive fails then it - * means the user tried to use texture repeat with a texture that - * can't be repeated by the GPU (e.g. due to waste or use of - * GL_TEXTURE_RECTANGLE_ARB) */ - if (success) - continue; - } - - /* If multitexturing failed or we are drawing with a sliced texture - * then we only support a single layer so we pluck out the texture - * from the first pipeline layer... */ - texture = _cogl_pipeline_get_layer_texture (pipeline, state.first_layer); - - if (rects[i].tex_coords) - tex_coords = rects[i].tex_coords; - else - tex_coords = default_tex_coords; - - clamp_s = (cogl_pipeline_get_layer_wrap_mode_s (pipeline, - state.first_layer) == - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - clamp_t = (cogl_pipeline_get_layer_wrap_mode_t (pipeline, - state.first_layer) == - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - - COGL_NOTE (DRAW, "Drawing Tex Quad (Multi-Prim Mode)"); - - _cogl_texture_quad_multiple_primitives (texture, - pipeline, - clamp_s, clamp_t, - rects[i].position, - tex_coords[0], - tex_coords[1], - tex_coords[2], - tex_coords[3]); - } - - if (state.override_source) - cogl_object_unref (pipeline); -} - -void -cogl_rectangles (const float *verts, - unsigned int n_rects) -{ - struct _CoglMutiTexturedRect *rects; - int i; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * _CoglMutiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rects = g_alloca (n_rects * sizeof (struct _CoglMutiTexturedRect)); - - for (i = 0; i < n_rects; i++) - { - rects[i].position = &verts[i * 4]; - rects[i].tex_coords = NULL; - rects[i].tex_coords_len = 0; - } - - _cogl_rectangles_with_multitexture_coords (rects, n_rects); -} - -void -cogl_rectangles_with_texture_coords (const float *verts, - unsigned int n_rects) -{ - struct _CoglMutiTexturedRect *rects; - int i; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * _CoglMutiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rects = g_alloca (n_rects * sizeof (struct _CoglMutiTexturedRect)); - - for (i = 0; i < n_rects; i++) - { - rects[i].position = &verts[i * 8]; - rects[i].tex_coords = &verts[i * 8 + 4]; - rects[i].tex_coords_len = 4; - } - - _cogl_rectangles_with_multitexture_coords (rects, n_rects); -} - -void -cogl_rectangle_with_texture_coords (float x_1, - float y_1, - float x_2, - float y_2, - float tx_1, - float ty_1, - float tx_2, - float ty_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - const float tex_coords[4] = {tx_1, ty_1, tx_2, ty_2}; - struct _CoglMutiTexturedRect rect; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * _CoglMutiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rect.position = position; - rect.tex_coords = tex_coords; - rect.tex_coords_len = 4; - - _cogl_rectangles_with_multitexture_coords (&rect, 1); -} - -void -cogl_rectangle_with_multitexture_coords (float x_1, - float y_1, - float x_2, - float y_2, - const float *user_tex_coords, - int user_tex_coords_len) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - struct _CoglMutiTexturedRect rect; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * _CoglMutiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rect.position = position; - rect.tex_coords = user_tex_coords; - rect.tex_coords_len = user_tex_coords_len; - - _cogl_rectangles_with_multitexture_coords (&rect, 1); -} - -void -cogl_rectangle (float x_1, - float y_1, - float x_2, - float y_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - struct _CoglMutiTexturedRect rect; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * _CoglMutiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rect.position = position; - rect.tex_coords = NULL; - rect.tex_coords_len = 0; - - _cogl_rectangles_with_multitexture_coords (&rect, 1); -} - -void -_cogl_rectangle_immediate (float x_1, - float y_1, - float x_2, - float y_2) -{ - /* Draw a rectangle using the vertex array API to avoid going - through the journal. This should only be used in cases where the - code might be called while the journal is already being flushed - such as when flushing the clip state */ - float vertices[8] = - { - x_1, y_1, - x_1, y_2, - x_2, y_1, - x_2, y_2 - }; - CoglVertexArray *vertex_array; - CoglAttribute *attributes[2]; - - vertex_array = cogl_vertex_array_new (sizeof (vertices), vertices); - attributes[0] = cogl_attribute_new (vertex_array, - "cogl_position_in", - sizeof (float) * 2, /* stride */ - 0, /* offset */ - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = NULL; - - _cogl_draw_attributes_array (COGL_VERTICES_MODE_TRIANGLE_STRIP, - 0, /* first_index */ - 4, /* n_vertices */ - attributes, - COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); - - - cogl_object_unref (attributes[0]); - cogl_object_unref (vertex_array); -} - -typedef struct _AppendTexCoordsState -{ - const CoglTextureVertex *vertices_in; - int vertex; - int layer; - float *vertices_out; -} AppendTexCoordsState; - -gboolean -append_tex_coord_attributes_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - AppendTexCoordsState *state = user_data; - CoglHandle tex_handle; - float tx, ty; - float *t; - - tx = state->vertices_in[state->vertex].tx; - ty = state->vertices_in[state->vertex].ty; - - /* COGL_INVALID_HANDLE textures will be handled in - * _cogl_pipeline_flush_layers_gl_state but there is no need to worry - * about scaling texture coordinates in this case */ - tex_handle = _cogl_pipeline_get_layer_texture (pipeline, layer_index); - if (tex_handle != COGL_INVALID_HANDLE) - _cogl_texture_transform_coords_to_gl (tex_handle, &tx, &ty); - - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - t = state->vertices_out + 3 + 2 * state->layer; - t[0] = tx; - t[1] = ty; - - state->layer++; - - return TRUE; -} - -typedef struct _ValidateState -{ - CoglPipeline *original_pipeline; - CoglPipeline *pipeline; -} ValidateState; - -static gboolean -_cogl_polygon_validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateState *state = user_data; - - /* By default COGL_PIPELINE_WRAP_MODE_AUTOMATIC becomes - * GL_CLAMP_TO_EDGE but we want the polygon API to use GL_REPEAT to - * maintain compatibility with previous releases - */ - - if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (state->original_pipeline == state->pipeline) - state->pipeline = cogl_pipeline_copy (pipeline); - - cogl_pipeline_set_layer_wrap_mode_s (state->pipeline, layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - - if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (state->original_pipeline == state->pipeline) - state->pipeline = cogl_pipeline_copy (pipeline); - - cogl_pipeline_set_layer_wrap_mode_t (state->pipeline, layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - - return TRUE; -} - -void -cogl_polygon (const CoglTextureVertex *vertices, - unsigned int n_vertices, - gboolean use_color) -{ - CoglPipeline *pipeline; - ValidateState validate_state; - int n_layers; - int n_attributes; - CoglAttribute **attributes; - int i; - unsigned int stride; - gsize stride_bytes; - CoglVertexArray *vertex_array; - float *v; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - pipeline = cogl_get_source (); - - validate_state.original_pipeline = pipeline; - validate_state.pipeline = pipeline; - cogl_pipeline_foreach_layer (pipeline, - _cogl_polygon_validate_layer_cb, - &validate_state); - pipeline = validate_state.pipeline; - - n_layers = cogl_pipeline_get_n_layers (pipeline); - - n_attributes = 1 + n_layers + (use_color ? 1 : 0); - attributes = g_alloca (sizeof (CoglAttribute *) * (n_attributes + 1)); - attributes[n_attributes] = NULL; - - /* Our data is arranged like: - * [X, Y, Z, TX0, TY0, TX1, TY1..., R, G, B, A,...] */ - stride = 3 + (2 * n_layers) + (use_color ? 1 : 0); - stride_bytes = stride * sizeof (float); - - /* Make sure there is enough space in the global vertex array. This - * is used so we can render the polygon with a single call to OpenGL - * but still support any number of vertices */ - g_array_set_size (ctx->polygon_vertices, n_vertices * stride); - - vertex_array = cogl_vertex_array_new (n_vertices * stride_bytes, NULL); - - attributes[0] = cogl_attribute_new (vertex_array, - "cogl_position_in", - stride_bytes, - 0, - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - - for (i = 0; i < n_layers; i++) - { - const char *names[] = { - "cogl_tex_coord0_in", - "cogl_tex_coord1_in", - "cogl_tex_coord2_in", - "cogl_tex_coord3_in", - "cogl_tex_coord4_in", - "cogl_tex_coord5_in", - "cogl_tex_coord6_in", - "cogl_tex_coord7_in" - }; - char *name = i < 8 ? (char *)names[i] : - g_strdup_printf ("cogl_tex_coord%d_in", i); - - attributes[i + 1] = cogl_attribute_new (vertex_array, - name, - stride_bytes, - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - 12 + 8 * i, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - } - - if (use_color) - { - attributes[n_attributes - 1] = - cogl_attribute_new (vertex_array, - "cogl_color_in", - stride_bytes, - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - 12 + 8 * n_layers, - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - } - - /* Convert the vertices into an array of float vertex attributes */ - v = (float *)ctx->polygon_vertices->data; - for (i = 0; i < n_vertices; i++) - { - AppendTexCoordsState append_tex_coords_state; - guint8 *c; - - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - v[0] = vertices[i].x; - v[1] = vertices[i].y; - v[2] = vertices[i].z; - - append_tex_coords_state.vertices_in = vertices; - append_tex_coords_state.vertex = i; - append_tex_coords_state.layer = 0; - append_tex_coords_state.vertices_out = v; - cogl_pipeline_foreach_layer (pipeline, - append_tex_coord_attributes_cb, - &append_tex_coords_state); - - if (use_color) - { - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - c = (guint8 *) (v + 3 + 2 * n_layers); - c[0] = cogl_color_get_red_byte (&vertices[i].color); - c[1] = cogl_color_get_green_byte (&vertices[i].color); - c[2] = cogl_color_get_blue_byte (&vertices[i].color); - c[3] = cogl_color_get_alpha_byte (&vertices[i].color); - } - - v += stride; - } - - v = (float *)ctx->polygon_vertices->data; - cogl_buffer_set_data (COGL_BUFFER (vertex_array), - 0, - v, - ctx->polygon_vertices->len * sizeof (float)); - - cogl_push_source (pipeline); - - cogl_draw_attributes_array (COGL_VERTICES_MODE_TRIANGLE_FAN, - 0, n_vertices, - attributes); - - cogl_pop_source (); - - if (pipeline != validate_state.original_pipeline) - cogl_object_unref (pipeline); -} - diff --git a/clutter/cogl/cogl/cogl-primitives.h b/clutter/cogl/cogl/cogl-primitives.h deleted file mode 100644 index f638056..0000000 --- a/clutter/cogl/cogl/cogl-primitives.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_PRIMITIVES_H -#define __COGL_PRIMITIVES_H - -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-primitives - * @short_description: Functions that draw various primitive 3D shapes - * - * The primitives API provides utilities for drawing some - * common 3D shapes in a more convenient way than the CoglVertexBuffer - * API provides. - */ - -/** - * cogl_rectangle: - * @x_1: X coordinate of the top-left corner - * @y_1: Y coordinate of the top-left corner - * @x_2: X coordinate of the bottom-right corner - * @y_2: Y coordinate of the bottom-right corner - * - * Fills a rectangle at the given coordinates with the current source material - **/ -void -cogl_rectangle (float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_rectangle_with_texture_coords: - * @x1: x coordinate upper left on screen. - * @y1: y coordinate upper left on screen. - * @x2: x coordinate lower right on screen. - * @y2: y coordinate lower right on screen. - * @tx1: x part of texture coordinate to use for upper left pixel - * @ty1: y part of texture coordinate to use for upper left pixel - * @tx2: x part of texture coordinate to use for lower right pixel - * @ty2: y part of texture coordinate to use for left pixel - * - * Draw a rectangle using the current material and supply texture coordinates - * to be used for the first texture layer of the material. To draw the entire - * texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0. - * - * Since: 1.0 - */ -void -cogl_rectangle_with_texture_coords (float x1, - float y1, - float x2, - float y2, - float tx1, - float ty1, - float tx2, - float ty2); - -/** - * cogl_rectangle_with_multitexture_coords: - * @x1: x coordinate upper left on screen. - * @y1: y coordinate upper left on screen. - * @x2: x coordinate lower right on screen. - * @y2: y coordinate lower right on screen. - * @tex_coords: (in) (array) (transfer none): An array containing groups of - * 4 float values: [tx1, ty1, tx2, ty2] that are interpreted as two texture - * coordinates; one for the upper left texel, and one for the lower right - * texel. Each value should be between 0.0 and 1.0, where the coordinate - * (0.0, 0.0) represents the top left of the texture, and (1.0, 1.0) the - * bottom right. - * @tex_coords_len: The length of the tex_coords array. (e.g. for one layer - * and one group of texture coordinates, this would be 4) - * - * This function draws a rectangle using the current source material to - * texture or fill with. As a material may contain multiple texture layers - * this interface lets you supply texture coordinates for each layer of the - * material. - * - * The first pair of coordinates are for the first layer (with the smallest - * layer index) and if you supply less texture coordinates than there are - * layers in the current source material then default texture coordinates - * (0.0, 0.0, 1.0, 1.0) are generated. - * - * Since: 1.0 - */ -void -cogl_rectangle_with_multitexture_coords (float x1, - float y1, - float x2, - float y2, - const float *tex_coords, - int tex_coords_len); - -/** - * cogl_rectangles_with_texture_coords: - * @verts: (in) (array) (transfer none): an array of vertices - * @n_rects: number of rectangles to draw - * - * Draws a series of rectangles in the same way that - * cogl_rectangle_with_texture_coords() does. In some situations it can give a - * significant performance boost to use this function rather than - * calling cogl_rectangle_with_texture_coords() separately for each rectangle. - * - * @verts should point to an array of #floats with - * @n_rects * 8 elements. Each group of 8 values corresponds to the - * parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same - * meaning as in cogl_rectangle_with_texture_coords(). - * - * Since: 0.8.6 - */ -void -cogl_rectangles_with_texture_coords (const float *verts, - unsigned int n_rects); - -/** - * cogl_rectangles: - * @verts: (in) (array) (transfer none): an array of vertices - * @n_rects: number of rectangles to draw - * - * Draws a series of rectangles in the same way that - * cogl_rectangle() does. In some situations it can give a - * significant performance boost to use this function rather than - * calling cogl_rectangle() separately for each rectangle. - * - * @verts should point to an array of #floats with - * @n_rects * 4 elements. Each group of 4 values corresponds to the - * parameters x1, y1, x2, and y2, and have the same - * meaning as in cogl_rectangle(). - * - * Since: 1.0 - */ -void -cogl_rectangles (const float *verts, - unsigned int n_rects); - -/** - * cogl_polygon: - * @vertices: An array of #CoglTextureVertex structs - * @n_vertices: The length of the vertices array - * @use_color: %TRUE if the color member of #CoglTextureVertex should be used - * - * Draws a convex polygon using the current source material to fill / texture - * with according to the texture coordinates passed. - * - * If @use_color is %TRUE then the color will be changed for each vertex using - * the value specified in the color member of #CoglTextureVertex. This can be - * used for example to make the texture fade out by setting the alpha value of - * the color. - * - * All of the texture coordinates must be in the range [0,1] and repeating the - * texture is not supported. - * - * Because of the way this function is implemented it will currently - * only work if either the texture is not sliced or the backend is not - * OpenGL ES and the minifying and magnifying functions are both set - * to COGL_MATERIAL_FILTER_NEAREST. - * - * Since: 1.0 - */ -void -cogl_polygon (const CoglTextureVertex *vertices, - unsigned int n_vertices, - gboolean use_color); - -G_END_DECLS - -#endif /* __COGL_PRIMITIVES_H */ diff --git a/clutter/cogl/cogl/cogl-private.h b/clutter/cogl/cogl/cogl-private.h deleted file mode 100644 index bd09f4e..0000000 --- a/clutter/cogl/cogl/cogl-private.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_PRIVATE_H__ -#define __COGL_PRIVATE_H__ - -G_BEGIN_DECLS - -gboolean -_cogl_gl_check_version (GError **error); - -void -_cogl_gl_update_features (CoglContext *context); - -gboolean -_cogl_check_extension (const char *name, const char *ext); - -void -_cogl_clear (const CoglColor *color, unsigned long buffers); - -void -_cogl_read_pixels_with_rowstride (int x, - int y, - int width, - int height, - CoglReadPixelsFlags source, - CoglPixelFormat format, - guint8 *pixels, - int rowstride); - -G_END_DECLS - -#endif /* __COGL_PRIVATE_H__ */ diff --git a/clutter/cogl/cogl/cogl-profile.c b/clutter/cogl/cogl/cogl-profile.c deleted file mode 100644 index 92ef707..0000000 --- a/clutter/cogl/cogl/cogl-profile.c +++ /dev/null @@ -1,78 +0,0 @@ - -#ifdef COGL_ENABLE_PROFILE - -#include "cogl-profile.h" -#include "cogl-debug.h" - -#include - -UProfContext *_cogl_uprof_context; - -static gboolean -debug_option_getter (void *user_data) -{ - unsigned int shift = GPOINTER_TO_UINT (user_data); - return COGL_DEBUG_ENABLED (shift); -} - -static void -debug_option_setter (gboolean value, void *user_data) -{ - unsigned int shift = GPOINTER_TO_UINT (user_data); - - if (value) - COGL_DEBUG_SET_FLAG (shift); - else - COGL_DEBUG_CLEAR_FLAG (shift); -} - -static void -print_exit_report (void) -{ - if (getenv ("COGL_PROFILE_OUTPUT_REPORT")) - { - UProfReport *report = uprof_report_new ("Cogl report"); - uprof_report_add_context (report, _cogl_uprof_context); - uprof_report_print (report); - uprof_report_unref (report); - } - uprof_context_unref (_cogl_uprof_context); -} - -void -_cogl_uprof_init (void) -{ - _cogl_uprof_context = uprof_context_new ("Cogl"); -#define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \ - G_STMT_START { \ - int shift = COGL_DEBUG_ ## MASK_NAME; \ - uprof_context_add_boolean_option (_cogl_uprof_context, \ - GROUP, \ - NAME, \ - NAME_FORMATTED, \ - DESCRIPTION, \ - debug_option_getter, \ - debug_option_setter, \ - GUINT_TO_POINTER (shift)); \ - } G_STMT_END; - -#include "cogl-debug-options.h" -#undef OPT - - g_atexit (print_exit_report); -} - -void -_cogl_profile_trace_message (const char *format, ...) -{ - va_list ap; - - va_start (ap, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, ap); - va_end (ap); - - if (_cogl_uprof_context) - uprof_context_vtrace_message (_cogl_uprof_context, format, ap); -} - -#endif diff --git a/clutter/cogl/cogl/cogl-profile.h b/clutter/cogl/cogl/cogl-profile.h deleted file mode 100644 index 1d058f7..0000000 --- a/clutter/cogl/cogl/cogl-profile.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_PROFILE_H__ -#define __COGL_PROFILE_H__ - - -#ifdef COGL_ENABLE_PROFILE - -#include - -extern UProfContext *_cogl_uprof_context; - -#define COGL_STATIC_TIMER UPROF_STATIC_TIMER -#define COGL_STATIC_COUNTER UPROF_STATIC_COUNTER -#define COGL_COUNTER_INC UPROF_COUNTER_INC -#define COGL_COUNTER_DEC UPROF_COUNTER_DEC -#define COGL_TIMER_START UPROF_TIMER_START -#define COGL_TIMER_STOP UPROF_TIMER_STOP - -void -_cogl_uprof_init (void); - -void -_cogl_profile_trace_message (const char *format, ...); - -#else - -#define COGL_STATIC_TIMER(A,B,C,D,E) extern void _cogl_dummy_decl (void) -#define COGL_STATIC_COUNTER(A,B,C,D) extern void _cogl_dummy_decl (void) -#define COGL_COUNTER_INC(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_COUNTER_DEC(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_TIMER_START(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_TIMER_STOP(A,B) G_STMT_START{ (void)0; }G_STMT_END - -#define _cogl_profile_trace_message g_message - -#endif - -#endif /* __COGL_PROFILE_H__ */ - diff --git a/clutter/cogl/cogl/cogl-program-private.h b/clutter/cogl/cogl/cogl-program-private.h deleted file mode 100644 index 0474744..0000000 --- a/clutter/cogl/cogl/cogl-program-private.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_PROGRAM_H -#define __COGL_PROGRAM_H - -#include "cogl-handle.h" -#include "cogl-internal.h" -#include "cogl-shader-private.h" - -typedef struct _CoglProgram CoglProgram; - -struct _CoglProgram -{ - CoglHandleObject _parent; - - GSList *attached_shaders; - - GArray *custom_uniforms; - - /* An age counter that changes whenever the list of shaders is modified */ - unsigned int age; -}; - -typedef struct _CoglProgramUniform CoglProgramUniform; - -struct _CoglProgramUniform -{ - char *name; - CoglBoxedValue value; - /* The cached GL location for this uniform. This is only valid - between calls to _cogl_program_dirty_all_uniforms */ - GLint location; - /* Whether we have a location yet */ - unsigned int location_valid : 1; - /* Whether the uniform value has changed since the last time the - uniforms were flushed */ - unsigned int dirty : 1; -}; - -CoglProgram *_cogl_program_pointer_from_handle (CoglHandle handle); - -/* Internal function to flush the custom uniforms for the given use - program. This assumes the target GL program is already bound. The - gl_program still needs to be passed so that CoglProgram can query - the uniform locations. gl_program_changed should be set to TRUE if - we are flushing the uniforms against a different GL program from - the last time it was flushed. This will cause it to requery all of - the locations and assume that all uniforms are dirty */ -void -_cogl_program_flush_uniforms (CoglProgram *program, - GLuint gl_program, - gboolean gl_program_changed); - -CoglShaderLanguage -_cogl_program_get_language (CoglHandle handle); - -gboolean -_cogl_program_has_fragment_shader (CoglHandle handle); - -gboolean -_cogl_program_has_vertex_shader (CoglHandle handle); - -#endif /* __COGL_PROGRAM_H */ diff --git a/clutter/cogl/cogl/cogl-program.c b/clutter/cogl/cogl/cogl-program.c deleted file mode 100644 index 10d632c..0000000 --- a/clutter/cogl/cogl/cogl-program.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" - -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" - -#include "cogl-shader-private.h" -#include "cogl-program-private.h" - -#include - -static void _cogl_program_free (CoglProgram *program); - -COGL_HANDLE_DEFINE (Program, program); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (program); - -/* A CoglProgram is effectively just a list of shaders that will be - used together and a set of values for the custom uniforms. No - actual GL program is created - instead this is the responsibility - of the GLSL material backend. The uniform values are collected in - an array and then flushed whenever the material backend requests - it. */ - -#ifndef HAVE_COGL_GLES2 - -#define glGetUniformLocation ctx->drv.pf_glGetUniformLocation -#define glUniform1f ctx->drv.pf_glUniform1f -#define glUniform2f ctx->drv.pf_glUniform2f -#define glUniform3f ctx->drv.pf_glUniform3f -#define glUniform4f ctx->drv.pf_glUniform4f -#define glUniform1fv ctx->drv.pf_glUniform1fv -#define glUniform2fv ctx->drv.pf_glUniform2fv -#define glUniform3fv ctx->drv.pf_glUniform3fv -#define glUniform4fv ctx->drv.pf_glUniform4fv -#define glUniform1i ctx->drv.pf_glUniform1i -#define glUniform2i ctx->drv.pf_glUniform2i -#define glUniform3i ctx->drv.pf_glUniform3i -#define glUniform4i ctx->drv.pf_glUniform4i -#define glUniform1iv ctx->drv.pf_glUniform1iv -#define glUniform2iv ctx->drv.pf_glUniform2iv -#define glUniform3iv ctx->drv.pf_glUniform3iv -#define glUniform4iv ctx->drv.pf_glUniform4iv -#define glUniformMatrix2fv ctx->drv.pf_glUniformMatrix2fv -#define glUniformMatrix3fv ctx->drv.pf_glUniformMatrix3fv -#define glUniformMatrix4fv ctx->drv.pf_glUniformMatrix4fv -#define glProgramLocalParameter4fv ctx->drv.pf_glProgramLocalParameter4fv - -#endif /* HAVE_COGL_GLES2 */ - -static void -_cogl_program_free (CoglProgram *program) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Unref all of the attached shaders */ - g_slist_foreach (program->attached_shaders, (GFunc) cogl_handle_unref, NULL); - /* Destroy the list */ - g_slist_free (program->attached_shaders); - - for (i = 0; i < program->custom_uniforms->len; i++) - { - CoglProgramUniform *uniform = - &g_array_index (program->custom_uniforms, CoglProgramUniform, i); - - g_free (uniform->name); - - if (uniform->value.count > 1) - g_free (uniform->value.v.array); - } - - g_array_free (program->custom_uniforms, TRUE); - - g_slice_free (CoglProgram, program); -} - -CoglHandle -cogl_create_program (void) -{ - CoglProgram *program; - - program = g_slice_new0 (CoglProgram); - - program->custom_uniforms = - g_array_new (FALSE, FALSE, sizeof (CoglProgramUniform)); - program->age = 0; - - return _cogl_program_handle_new (program); -} - -void -cogl_program_attach_shader (CoglHandle program_handle, - CoglHandle shader_handle) -{ - CoglProgram *program; - CoglShader *shader; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!cogl_is_program (program_handle) || !cogl_is_shader (shader_handle)) - return; - - program = _cogl_program_pointer_from_handle (program_handle); - shader = _cogl_shader_pointer_from_handle (shader_handle); - - /* Only one shader is allowed if the type is ARBfp */ -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - g_return_if_fail (program->attached_shaders == NULL); - else if (shader->language == COGL_SHADER_LANGUAGE_GLSL) - g_return_if_fail (_cogl_program_get_language (program) == - COGL_SHADER_LANGUAGE_GLSL); -#endif - - program->attached_shaders - = g_slist_prepend (program->attached_shaders, - cogl_handle_ref (shader_handle)); - - program->age++; -} - -void -cogl_program_link (CoglHandle handle) -{ - /* There's no point in linking the program here because it will have - to be relinked with a different fixed functionality shader - whenever the settings change */ -} - -void -cogl_program_use (CoglHandle handle) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (handle == COGL_INVALID_HANDLE || - cogl_is_program (handle)); - - if (ctx->current_program == 0 && handle != 0) - ctx->legacy_state_set++; - else if (handle == 0 && ctx->current_program != 0) - ctx->legacy_state_set--; - - if (handle != COGL_INVALID_HANDLE) - cogl_handle_ref (handle); - if (ctx->current_program != COGL_INVALID_HANDLE) - cogl_handle_unref (ctx->current_program); - ctx->current_program = handle; -} - -int -cogl_program_get_uniform_location (CoglHandle handle, - const char *uniform_name) -{ - int i; - CoglProgram *program; - CoglProgramUniform *uniform; - - if (!cogl_is_program (handle)) - return -1; - - program = _cogl_program_pointer_from_handle (handle); - - /* We can't just ask the GL program object for the uniform location - directly because it will change every time the program is linked - with a different shader. Instead we make our own mapping of - uniform numbers and cache the names */ - for (i = 0; i < program->custom_uniforms->len; i++) - { - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, i); - - if (!strcmp (uniform->name, uniform_name)) - return i; - } - - /* Create a new uniform with the given name */ - g_array_set_size (program->custom_uniforms, - program->custom_uniforms->len + 1); - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, - program->custom_uniforms->len - 1); - - uniform->name = g_strdup (uniform_name); - memset (&uniform->value, 0, sizeof (CoglBoxedValue)); - uniform->dirty = TRUE; - uniform->location_valid = FALSE; - - return program->custom_uniforms->len - 1; -} - -static void -cogl_program_uniform_x (CoglHandle handle, - int uniform_no, - int size, - int count, - CoglBoxedType type, - gsize value_size, - gconstpointer value, - gboolean transpose) -{ - CoglProgram *program = handle; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_program (handle)); - g_return_if_fail (program != NULL); - - if (uniform_no >= 0 && uniform_no < program->custom_uniforms->len && - size >= 1 && size <= 4 && count >= 1) - { - CoglProgramUniform *uniform = - &g_array_index (program->custom_uniforms, - CoglProgramUniform, uniform_no); - - if (count == 1) - { - if (uniform->value.count > 1) - g_free (uniform->value.v.array); - - memcpy (uniform->value.v.float_value, value, value_size); - } - else - { - if (uniform->value.count > 1) - { - if (uniform->value.count != count || - uniform->value.size != size || - uniform->value.type != type) - { - g_free (uniform->value.v.array); - uniform->value.v.array = g_malloc (count * value_size); - } - } - else - uniform->value.v.array = g_malloc (count * value_size); - - memcpy (uniform->value.v.array, value, count * value_size); - } - - uniform->value.type = type; - uniform->value.size = size; - uniform->value.count = count; - uniform->dirty = TRUE; - } -} - -void -cogl_program_uniform_1f (int uniform_no, - float value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - cogl_program_uniform_x (ctx->current_program, - uniform_no, 1, 1, COGL_BOXED_FLOAT, - sizeof (float), &value, FALSE); -} - -void -cogl_program_set_uniform_1f (CoglHandle handle, - int uniform_location, - float value) -{ - cogl_program_uniform_x (handle, - uniform_location, 1, 1, COGL_BOXED_FLOAT, - sizeof (float), &value, FALSE); -} - -void -cogl_program_uniform_1i (int uniform_no, - int value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - cogl_program_uniform_x (ctx->current_program, - uniform_no, 1, 1, COGL_BOXED_INT, - sizeof (int), &value, FALSE); -} - -void -cogl_program_set_uniform_1i (CoglHandle handle, - int uniform_location, - int value) -{ - cogl_program_uniform_x (handle, - uniform_location, 1, 1, COGL_BOXED_INT, - sizeof (int), &value, FALSE); -} - -void -cogl_program_uniform_float (int uniform_no, - int size, - int count, - const GLfloat *value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - cogl_program_uniform_x (ctx->current_program, - uniform_no, size, count, COGL_BOXED_FLOAT, - sizeof (float) * size, value, FALSE); -} - -void -cogl_program_set_uniform_float (CoglHandle handle, - int uniform_location, - int n_components, - int count, - const float *value) -{ - cogl_program_uniform_x (handle, - uniform_location, n_components, count, - COGL_BOXED_FLOAT, - sizeof (float) * n_components, value, FALSE); -} - -void -cogl_program_uniform_int (int uniform_no, - int size, - int count, - const GLint *value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - cogl_program_uniform_x (ctx->current_program, - uniform_no, size, count, COGL_BOXED_INT, - sizeof (int) * size, value, FALSE); -} - -void -cogl_program_set_uniform_int (CoglHandle handle, - int uniform_location, - int n_components, - int count, - const int *value) -{ - cogl_program_uniform_x (handle, - uniform_location, n_components, count, - COGL_BOXED_INT, - sizeof (int) * n_components, value, FALSE); -} - -void -cogl_program_set_uniform_matrix (CoglHandle handle, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value) -{ - g_return_if_fail (cogl_is_program (handle)); - - cogl_program_uniform_x (handle, - uniform_location, dimensions, count, - COGL_BOXED_MATRIX, - sizeof (float) * dimensions * dimensions, - value, - transpose); -} - -void -cogl_program_uniform_matrix (int uniform_no, - int size, - int count, - gboolean transpose, - const float *value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - cogl_program_set_uniform_matrix (ctx->current_program, - uniform_no, size, count, transpose, value); -} - -#ifndef HAVE_COGL_GLES - -/* ARBfp local parameters can be referenced like: - * - * "program.local[5]" - * ^14char offset (after whitespace is stripped) - */ -static int -get_local_param_index (const char *uniform_name) -{ - char *input = g_strdup (uniform_name); - int i; - char *p = input; - char *endptr; - int _index; - - for (i = 0; input[i] != '\0'; i++) - if (input[i] != '_' && input[i] != '\t') - *p++ = input[i]; - input[i] = '\0'; - - g_return_val_if_fail (strncmp ("program.local[", input, 14) == 0, -1); - - _index = g_ascii_strtoull (input + 14, &endptr, 10); - g_return_val_if_fail (endptr != input + 14, -1); - g_return_val_if_fail (*endptr == ']', -1); - - g_return_val_if_fail (_index >= 0, -1); - - g_free (input); - - return _index; -} - -static void -_cogl_program_flush_uniform_glsl (GLint location, - CoglBoxedValue *value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - switch (value->type) - { - case COGL_BOXED_NONE: - break; - - case COGL_BOXED_INT: - { - int *ptr; - - if (value->count == 1) - ptr = value->v.int_value; - else - ptr = value->v.int_array; - - switch (value->size) - { - case 1: glUniform1iv (location, value->count, ptr); break; - case 2: glUniform2iv (location, value->count, ptr); break; - case 3: glUniform3iv (location, value->count, ptr); break; - case 4: glUniform4iv (location, value->count, ptr); break; - } - } - break; - - case COGL_BOXED_FLOAT: - { - float *ptr; - - if (value->count == 1) - ptr = value->v.float_value; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 1: glUniform1fv (location, value->count, ptr); break; - case 2: glUniform2fv (location, value->count, ptr); break; - case 3: glUniform3fv (location, value->count, ptr); break; - case 4: glUniform4fv (location, value->count, ptr); break; - } - } - break; - - case COGL_BOXED_MATRIX: - { - float *ptr; - - if (value->count == 1) - ptr = value->v.matrix; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 2: - glUniformMatrix2fv (location, value->count, value->transpose, ptr); - break; - case 3: - glUniformMatrix3fv (location, value->count, value->transpose, ptr); - break; - case 4: - glUniformMatrix4fv (location, value->count, value->transpose, ptr); - break; - } - } - break; - } -} - -#endif /* HAVE_COGL_GLES */ - -#ifdef HAVE_COGL_GL - -static void -_cogl_program_flush_uniform_arbfp (GLint location, - CoglBoxedValue *value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (value->type != COGL_BOXED_NONE) - { - g_return_if_fail (value->type == COGL_BOXED_FLOAT); - g_return_if_fail (value->size == 4); - g_return_if_fail (value->count == 1); - - GE( glProgramLocalParameter4fv (GL_FRAGMENT_PROGRAM_ARB, location, - value->v.float_value) ); - } -} - -#endif /* HAVE_COGL_GL */ - -void -_cogl_program_flush_uniforms (CoglProgram *program, - GLuint gl_program, - gboolean gl_program_changed) -{ -#ifdef HAVE_COGL_GLES - - g_return_if_reached (); - -#else /* HAVE_COGL_GLES */ - - CoglProgramUniform *uniform; - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (i = 0; i < program->custom_uniforms->len; i++) - { - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, i); - - if (gl_program_changed || uniform->dirty) - { - if (gl_program_changed || !uniform->location_valid) - { - if (_cogl_program_get_language (program) == - COGL_SHADER_LANGUAGE_GLSL) - uniform->location = - glGetUniformLocation (gl_program, uniform->name); - else - uniform->location = - get_local_param_index (uniform->name); - - uniform->location_valid = TRUE; - } - - /* If the uniform isn't really in the program then there's - no need to actually set it */ - if (uniform->location != -1) - { - switch (_cogl_program_get_language (program)) - { - case COGL_SHADER_LANGUAGE_GLSL: - _cogl_program_flush_uniform_glsl (uniform->location, - &uniform->value); - break; - -#ifdef HAVE_COGL_GL - case COGL_SHADER_LANGUAGE_ARBFP: - _cogl_program_flush_uniform_arbfp (uniform->location, - &uniform->value); - break; -#endif - } - } - - uniform->dirty = FALSE; - } - } - -#endif /* HAVE_COGL_GLES */ -} - -CoglShaderLanguage -_cogl_program_get_language (CoglHandle handle) -{ - CoglProgram *program = handle; - - /* Use the language of the first shader */ - - if (program->attached_shaders) - { - CoglShader *shader = program->attached_shaders->data; - return shader->language; - } - else - return COGL_SHADER_LANGUAGE_GLSL; -} - -static gboolean -_cogl_program_has_shader_type (CoglProgram *program, - CoglShaderType type) -{ - GSList *l; - - for (l = program->attached_shaders; l; l = l->next) - { - CoglShader *shader = l->data; - - if (shader->type == type) - return TRUE; - } - - return FALSE; -} - -gboolean -_cogl_program_has_fragment_shader (CoglHandle handle) -{ - return _cogl_program_has_shader_type (handle, COGL_SHADER_TYPE_FRAGMENT); -} - -gboolean -_cogl_program_has_vertex_shader (CoglHandle handle) -{ - return _cogl_program_has_shader_type (handle, COGL_SHADER_TYPE_VERTEX); -} diff --git a/clutter/cogl/cogl/cogl-rectangle-map.c b/clutter/cogl/cogl/cogl-rectangle-map.c deleted file mode 100644 index 5fa8ab6..0000000 --- a/clutter/cogl/cogl/cogl-rectangle-map.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl-rectangle-map.h" -#include "cogl-debug.h" - -/* Implements a data structure which keeps track of unused - sub-rectangles within a larger rectangle using a binary tree - structure. The algorithm for this is based on the description here: - - http://www.blackpawn.com/texts/lightmaps/default.html -*/ - -#ifdef COGL_ENABLE_DEBUG - -/* The cairo header is only used for debugging to generate an image of - the atlas */ -#include - -static void _cogl_rectangle_map_dump_image (CoglRectangleMap *map); - -#endif /* COGL_ENABLE_DEBUG */ - -typedef struct _CoglRectangleMapNode CoglRectangleMapNode; -typedef struct _CoglRectangleMapStackEntry CoglRectangleMapStackEntry; - -typedef void (* CoglRectangleMapInternalForeachCb) (CoglRectangleMapNode *node, - void *data); - -typedef enum -{ - COGL_RECTANGLE_MAP_BRANCH, - COGL_RECTANGLE_MAP_FILLED_LEAF, - COGL_RECTANGLE_MAP_EMPTY_LEAF -} CoglRectangleMapNodeType; - -struct _CoglRectangleMap -{ - CoglRectangleMapNode *root; - - unsigned int n_rectangles; - - unsigned int space_remaining; - - GDestroyNotify value_destroy_func; - - /* Stack used for walking the structure. This is only used during - the lifetime of a single function call but it is kept here as an - optimisation to avoid reallocating it every time it is needed */ - GArray *stack; -}; - -struct _CoglRectangleMapNode -{ - CoglRectangleMapNodeType type; - - CoglRectangleMapEntry rectangle; - - unsigned int largest_gap; - - CoglRectangleMapNode *parent; - - union - { - /* Fields used when this is a branch */ - struct - { - CoglRectangleMapNode *left; - CoglRectangleMapNode *right; - } branch; - - /* Field used when this is a filled leaf */ - void *data; - } d; -}; - -struct _CoglRectangleMapStackEntry -{ - /* The node to search */ - CoglRectangleMapNode *node; - /* Index of next branch of this node to explore. Basically either 0 - to go left or 1 to go right */ - gboolean next_index; -}; - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_new (void) -{ - return g_slice_new (CoglRectangleMapNode); -} - -static void -_cogl_rectangle_map_node_free (CoglRectangleMapNode *node) -{ - g_slice_free (CoglRectangleMapNode, node); -} - -CoglRectangleMap * -_cogl_rectangle_map_new (unsigned int width, - unsigned int height, - GDestroyNotify value_destroy_func) -{ - CoglRectangleMap *map = g_new (CoglRectangleMap, 1); - CoglRectangleMapNode *root = _cogl_rectangle_map_node_new (); - - root->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - root->parent = NULL; - root->rectangle.x = 0; - root->rectangle.y = 0; - root->rectangle.width = width; - root->rectangle.height = height; - root->largest_gap = width * height; - - map->root = root; - map->n_rectangles = 0; - map->value_destroy_func = value_destroy_func; - map->space_remaining = width * height; - - map->stack = g_array_new (FALSE, FALSE, sizeof (CoglRectangleMapStackEntry)); - - return map; -} - -static void -_cogl_rectangle_map_stack_push (GArray *stack, - CoglRectangleMapNode *node, - gboolean next_index) -{ - CoglRectangleMapStackEntry *new_entry; - - g_array_set_size (stack, stack->len + 1); - - new_entry = &g_array_index (stack, CoglRectangleMapStackEntry, - stack->len - 1); - - new_entry->node = node; - new_entry->next_index = next_index; -} - -static void -_cogl_rectangle_map_stack_pop (GArray *stack) -{ - g_array_set_size (stack, stack->len - 1); -} - -static CoglRectangleMapStackEntry * -_cogl_rectangle_map_stack_get_top (GArray *stack) -{ - return &g_array_index (stack, CoglRectangleMapStackEntry, - stack->len - 1); -} - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_split_horizontally (CoglRectangleMapNode *node, - unsigned int left_width) -{ - /* Splits the node horizontally (according to emacs' definition, not - vim) by converting it to a branch and adding two new leaf - nodes. The leftmost branch will have the width left_width and - will be returned. If the node is already just the right size it - won't do anything */ - - CoglRectangleMapNode *left_node, *right_node; - - if (node->rectangle.width == left_width) - return node; - - left_node = _cogl_rectangle_map_node_new (); - left_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - left_node->parent = node; - left_node->rectangle.x = node->rectangle.x; - left_node->rectangle.y = node->rectangle.y; - left_node->rectangle.width = left_width; - left_node->rectangle.height = node->rectangle.height; - left_node->largest_gap = (left_node->rectangle.width * - left_node->rectangle.height); - node->d.branch.left = left_node; - - right_node = _cogl_rectangle_map_node_new (); - right_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - right_node->parent = node; - right_node->rectangle.x = node->rectangle.x + left_width; - right_node->rectangle.y = node->rectangle.y; - right_node->rectangle.width = node->rectangle.width - left_width; - right_node->rectangle.height = node->rectangle.height; - right_node->largest_gap = (right_node->rectangle.width * - right_node->rectangle.height); - node->d.branch.right = right_node; - - node->type = COGL_RECTANGLE_MAP_BRANCH; - - return left_node; -} - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_split_vertically (CoglRectangleMapNode *node, - unsigned int top_height) -{ - /* Splits the node vertically (according to emacs' definition, not - vim) by converting it to a branch and adding two new leaf - nodes. The topmost branch will have the height top_height and - will be returned. If the node is already just the right size it - won't do anything */ - - CoglRectangleMapNode *top_node, *bottom_node; - - if (node->rectangle.height == top_height) - return node; - - top_node = _cogl_rectangle_map_node_new (); - top_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - top_node->parent = node; - top_node->rectangle.x = node->rectangle.x; - top_node->rectangle.y = node->rectangle.y; - top_node->rectangle.width = node->rectangle.width; - top_node->rectangle.height = top_height; - top_node->largest_gap = (top_node->rectangle.width * - top_node->rectangle.height); - node->d.branch.left = top_node; - - bottom_node = _cogl_rectangle_map_node_new (); - bottom_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - bottom_node->parent = node; - bottom_node->rectangle.x = node->rectangle.x; - bottom_node->rectangle.y = node->rectangle.y + top_height; - bottom_node->rectangle.width = node->rectangle.width; - bottom_node->rectangle.height = node->rectangle.height - top_height; - bottom_node->largest_gap = (bottom_node->rectangle.width * - bottom_node->rectangle.height); - node->d.branch.right = bottom_node; - - node->type = COGL_RECTANGLE_MAP_BRANCH; - - return top_node; -} - -#ifdef COGL_ENABLE_DEBUG - -static unsigned int -_cogl_rectangle_map_verify_recursive (CoglRectangleMapNode *node) -{ - /* This is just used for debugging the data structure. It - recursively walks the tree to verify that the largest gap values - all add up */ - - switch (node->type) - { - case COGL_RECTANGLE_MAP_BRANCH: - { - int sum = - _cogl_rectangle_map_verify_recursive (node->d.branch.left) + - _cogl_rectangle_map_verify_recursive (node->d.branch.right); - g_assert (node->largest_gap == - MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap)); - return sum; - } - - case COGL_RECTANGLE_MAP_EMPTY_LEAF: - g_assert (node->largest_gap == - node->rectangle.width * node->rectangle.height); - return 0; - - case COGL_RECTANGLE_MAP_FILLED_LEAF: - g_assert (node->largest_gap == 0); - return 1; - } - - return 0; -} - -static unsigned int -_cogl_rectangle_map_get_space_remaining_recursive (CoglRectangleMapNode *node) -{ - /* This is just used for debugging the data structure. It - recursively walks the tree to verify that the remaining space - value adds up */ - - switch (node->type) - { - case COGL_RECTANGLE_MAP_BRANCH: - { - CoglRectangleMapNode *l = node->d.branch.left; - CoglRectangleMapNode *r = node->d.branch.right; - - return (_cogl_rectangle_map_get_space_remaining_recursive (l) + - _cogl_rectangle_map_get_space_remaining_recursive (r)); - } - - case COGL_RECTANGLE_MAP_EMPTY_LEAF: - return node->rectangle.width * node->rectangle.height; - - case COGL_RECTANGLE_MAP_FILLED_LEAF: - return 0; - } - - return 0; -} - -static void -_cogl_rectangle_map_verify (CoglRectangleMap *map) -{ - unsigned int actual_n_rectangles = - _cogl_rectangle_map_verify_recursive (map->root); - unsigned int actual_space_remaining = - _cogl_rectangle_map_get_space_remaining_recursive (map->root); - - g_assert_cmpuint (actual_n_rectangles, ==, map->n_rectangles); - g_assert_cmpuint (actual_space_remaining, ==, map->space_remaining); -} - -#endif /* COGL_ENABLE_DEBUG */ - -gboolean -_cogl_rectangle_map_add (CoglRectangleMap *map, - unsigned int width, - unsigned int height, - void *data, - CoglRectangleMapEntry *rectangle) -{ - unsigned int rectangle_size = width * height; - /* Stack of nodes to search in */ - GArray *stack = map->stack; - CoglRectangleMapNode *found_node = NULL; - - /* Zero-sized rectangles break the algorithm for removing rectangles - so we'll disallow them */ - g_return_val_if_fail (width > 0 && height > 0, FALSE); - - /* Start with the root node */ - g_array_set_size (stack, 0); - _cogl_rectangle_map_stack_push (stack, map->root, FALSE); - - /* Depth-first search for an empty node that is big enough */ - while (stack->len > 0) - { - CoglRectangleMapStackEntry *stack_top; - CoglRectangleMapNode *node; - int next_index; - - /* Pop an entry off the stack */ - stack_top = _cogl_rectangle_map_stack_get_top (stack); - node = stack_top->node; - next_index = stack_top->next_index; - _cogl_rectangle_map_stack_pop (stack); - - /* Regardless of the type of the node, there's no point - descending any further if the new rectangle won't fit within - it */ - if (node->rectangle.width >= width && - node->rectangle.height >= height && - node->largest_gap >= rectangle_size) - { - if (node->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - /* We've found a node we can use */ - found_node = node; - break; - } - else if (node->type == COGL_RECTANGLE_MAP_BRANCH) - { - if (next_index) - /* Try the right branch */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.right, - 0); - else - { - /* Make sure we remember to try the right branch once - we've finished descending the left branch */ - _cogl_rectangle_map_stack_push (stack, - node, - 1); - /* Try the left branch */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.left, - 0); - } - } - } - } - - if (found_node) - { - CoglRectangleMapNode *node; - - /* Split according to whichever axis will leave us with the - largest space */ - if (found_node->rectangle.width - width > - found_node->rectangle.height - height) - { - found_node = - _cogl_rectangle_map_node_split_horizontally (found_node, width); - found_node = - _cogl_rectangle_map_node_split_vertically (found_node, height); - } - else - { - found_node = - _cogl_rectangle_map_node_split_vertically (found_node, height); - found_node = - _cogl_rectangle_map_node_split_horizontally (found_node, width); - } - - found_node->type = COGL_RECTANGLE_MAP_FILLED_LEAF; - found_node->d.data = data; - found_node->largest_gap = 0; - if (rectangle) - *rectangle = found_node->rectangle; - - /* Walk back up the tree and update the stored largest gap for - the node's sub tree */ - for (node = found_node->parent; node; node = node->parent) - { - /* This node is a parent so it should always be a branch */ - g_assert (node->type == COGL_RECTANGLE_MAP_BRANCH); - - node->largest_gap = MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap); - } - - /* There is now an extra rectangle in the map */ - map->n_rectangles++; - /* and less space */ - map->space_remaining -= rectangle_size; - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DUMP_ATLAS_IMAGE))) - { - _cogl_rectangle_map_dump_image (map); - /* Dumping the rectangle map is really slow so we might as well - verify the space remaining here as it is also quite slow */ - _cogl_rectangle_map_verify (map); - } -#endif - - return TRUE; - } - else - return FALSE; -} - -void -_cogl_rectangle_map_remove (CoglRectangleMap *map, - const CoglRectangleMapEntry *rectangle) -{ - CoglRectangleMapNode *node = map->root; - unsigned int rectangle_size = rectangle->width * rectangle->height; - - /* We can do a binary-chop down the search tree to find the rectangle */ - while (node->type == COGL_RECTANGLE_MAP_BRANCH) - { - CoglRectangleMapNode *left_node = node->d.branch.left; - - /* If and only if the rectangle is in the left node then the x,y - position of the rectangle will be within the node's - rectangle */ - if (rectangle->x < left_node->rectangle.x + left_node->rectangle.width && - rectangle->y < left_node->rectangle.y + left_node->rectangle.height) - /* Go left */ - node = left_node; - else - /* Go right */ - node = node->d.branch.right; - } - - /* Make sure we found the right node */ - if (node->type != COGL_RECTANGLE_MAP_FILLED_LEAF || - node->rectangle.x != rectangle->x || - node->rectangle.y != rectangle->y || - node->rectangle.width != rectangle->width || - node->rectangle.height != rectangle->height) - /* This should only happen if someone tried to remove a rectangle - that was not in the map so something has gone wrong */ - g_return_if_reached (); - else - { - /* Convert the node back to an empty node */ - if (map->value_destroy_func) - map->value_destroy_func (node->d.data); - node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - node->largest_gap = rectangle_size; - - /* Walk back up the tree combining branch nodes that have two - empty leaves back into a single empty leaf */ - for (node = node->parent; node; node = node->parent) - { - /* This node is a parent so it should always be a branch */ - g_assert (node->type == COGL_RECTANGLE_MAP_BRANCH); - - if (node->d.branch.left->type == COGL_RECTANGLE_MAP_EMPTY_LEAF && - node->d.branch.right->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - _cogl_rectangle_map_node_free (node->d.branch.left); - _cogl_rectangle_map_node_free (node->d.branch.right); - node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - - node->largest_gap = (node->rectangle.width * - node->rectangle.height); - } - else - break; - } - - /* Reduce the amount of space remaining in all of the parents - further up the chain */ - for (; node; node = node->parent) - node->largest_gap = MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap); - - /* There is now one less rectangle */ - g_assert (map->n_rectangles > 0); - map->n_rectangles--; - /* and more space */ - map->space_remaining += rectangle_size; - } - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DUMP_ATLAS_IMAGE))) - { - _cogl_rectangle_map_dump_image (map); - /* Dumping the rectangle map is really slow so we might as well - verify the space remaining here as it is also quite slow */ - _cogl_rectangle_map_verify (map); - } -#endif -} - -unsigned int -_cogl_rectangle_map_get_width (CoglRectangleMap *map) -{ - return map->root->rectangle.width; -} - -unsigned int -_cogl_rectangle_map_get_height (CoglRectangleMap *map) -{ - return map->root->rectangle.height; -} - -unsigned int -_cogl_rectangle_map_get_remaining_space (CoglRectangleMap *map) -{ - return map->space_remaining; -} - -unsigned int -_cogl_rectangle_map_get_n_rectangles (CoglRectangleMap *map) -{ - return map->n_rectangles; -} - -static void -_cogl_rectangle_map_internal_foreach (CoglRectangleMap *map, - CoglRectangleMapInternalForeachCb func, - void *data) -{ - /* Stack of nodes to search in */ - GArray *stack = map->stack; - - /* Start with the root node */ - g_array_set_size (stack, 0); - _cogl_rectangle_map_stack_push (stack, map->root, 0); - - /* Iterate all nodes depth-first */ - while (stack->len > 0) - { - CoglRectangleMapStackEntry *stack_top = - _cogl_rectangle_map_stack_get_top (stack); - CoglRectangleMapNode *node = stack_top->node; - - switch (node->type) - { - case COGL_RECTANGLE_MAP_BRANCH: - if (stack_top->next_index == 0) - { - /* Next time we come back to this node, go to the right */ - stack_top->next_index = 1; - - /* Explore the left branch next */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.left, - 0); - } - else if (stack_top->next_index == 1) - { - /* Next time we come back to this node, stop processing it */ - stack_top->next_index = 2; - - /* Explore the right branch next */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.right, - 0); - } - else - { - /* We're finished with this node so we can call the callback */ - func (node, data); - _cogl_rectangle_map_stack_pop (stack); - } - break; - - default: - /* Some sort of leaf node, just call the callback */ - func (node, data); - _cogl_rectangle_map_stack_pop (stack); - break; - } - } - - /* The stack should now be empty */ - g_assert (stack->len == 0); -} - -typedef struct _CoglRectangleMapForeachClosure -{ - CoglRectangleMapCallback callback; - void *data; -} CoglRectangleMapForeachClosure; - -static void -_cogl_rectangle_map_foreach_cb (CoglRectangleMapNode *node, void *data) -{ - CoglRectangleMapForeachClosure *closure = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF) - closure->callback (&node->rectangle, node->d.data, closure->data); -} - -void -_cogl_rectangle_map_foreach (CoglRectangleMap *map, - CoglRectangleMapCallback callback, - void *data) -{ - CoglRectangleMapForeachClosure closure; - - closure.callback = callback; - closure.data = data; - - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_foreach_cb, - &closure); -} - -static void -_cogl_rectangle_map_free_cb (CoglRectangleMapNode *node, void *data) -{ - CoglRectangleMap *map = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF && map->value_destroy_func) - map->value_destroy_func (node->d.data); - - _cogl_rectangle_map_node_free (node); -} - -void -_cogl_rectangle_map_free (CoglRectangleMap *map) -{ - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_free_cb, - map); - - g_array_free (map->stack, TRUE); - - g_free (map); -} - -#ifdef COGL_ENABLE_DEBUG - -static void -_cogl_rectangle_map_dump_image_cb (CoglRectangleMapNode *node, void *data) -{ - cairo_t *cr = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF || - node->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - /* Fill the rectangle using a different colour depending on - whether the rectangle is used */ - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF) - cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); - else - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); - - cairo_rectangle (cr, - node->rectangle.x, - node->rectangle.y, - node->rectangle.width, - node->rectangle.height); - - cairo_fill_preserve (cr); - - /* Draw a white outline around the rectangle */ - cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); - cairo_stroke (cr); - } -} - -static void -_cogl_rectangle_map_dump_image (CoglRectangleMap *map) -{ - /* This dumps a png to help visualize the map. Each leaf rectangle - is drawn with a white outline. Unused leaves are filled in black - and used leaves are blue */ - - cairo_surface_t *surface = - cairo_image_surface_create (CAIRO_FORMAT_RGB24, - _cogl_rectangle_map_get_width (map), - _cogl_rectangle_map_get_height (map)); - cairo_t *cr = cairo_create (surface); - - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_dump_image_cb, - cr); - - cairo_destroy (cr); - - cairo_surface_write_to_png (surface, "cogl-rectangle-map-dump.png"); - - cairo_surface_destroy (surface); -} - -#endif /* COGL_ENABLE_DEBUG */ diff --git a/clutter/cogl/cogl/cogl-rectangle-map.h b/clutter/cogl/cogl/cogl-rectangle-map.h deleted file mode 100644 index 51b9260..0000000 --- a/clutter/cogl/cogl/cogl-rectangle-map.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __COGL_RECTANGLE_MAP_H -#define __COGL_RECTANGLE_MAP_H - -#include - -typedef struct _CoglRectangleMap CoglRectangleMap; -typedef struct _CoglRectangleMapEntry CoglRectangleMapEntry; - -typedef void (* CoglRectangleMapCallback) (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data); - -struct _CoglRectangleMapEntry -{ - unsigned int x, y; - unsigned int width, height; -}; - -CoglRectangleMap * -_cogl_rectangle_map_new (unsigned int width, - unsigned int height, - GDestroyNotify value_destroy_func); - -gboolean -_cogl_rectangle_map_add (CoglRectangleMap *map, - unsigned int width, - unsigned int height, - void *data, - CoglRectangleMapEntry *rectangle); - -void -_cogl_rectangle_map_remove (CoglRectangleMap *map, - const CoglRectangleMapEntry *rectangle); - -unsigned int -_cogl_rectangle_map_get_width (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_height (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_remaining_space (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_n_rectangles (CoglRectangleMap *map); - -void -_cogl_rectangle_map_foreach (CoglRectangleMap *map, - CoglRectangleMapCallback callback, - void *data); - -void -_cogl_rectangle_map_free (CoglRectangleMap *map); - -#endif /* __COGL_RECTANGLE_MAP_H */ diff --git a/clutter/cogl/cogl/cogl-renderer-glx-private.h b/clutter/cogl/cogl/cogl-renderer-glx-private.h deleted file mode 100644 index aaebc9e..0000000 --- a/clutter/cogl/cogl/cogl-renderer-glx-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -#ifndef __COGL_RENDERER_GLX_PRIVATE_H -#define __COGL_RENDERER_GLX_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-renderer-xlib-private.h" - -typedef struct _CoglRendererGLX -{ - CoglRendererXlib _parent; - - int glx_major; - int glx_minor; - - int glx_error_base; - int glx_event_base; - - gboolean is_direct; - - /* Vblank stuff */ - int dri_fd; - - /* Function pointers for GLX specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * pf_ ## name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "cogl-winsys-glx-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglRendererGLX; - -#endif /* __COGL_RENDERER_GLX_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-renderer-private.h b/clutter/cogl/cogl/cogl-renderer-private.h deleted file mode 100644 index 8b9ebe7..0000000 --- a/clutter/cogl/cogl/cogl-renderer-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - */ - -#ifndef __COGL_RENDERER_PRIVATE_H -#define __COGL_RENDERER_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-winsys-private.h" - -#ifdef COGL_HAS_XLIB_SUPPORT -#include -#endif - -struct _CoglRenderer -{ - CoglObject _parent; - gboolean connected; - const CoglWinsysVtable *winsys_vtable; -#ifdef COGL_HAS_XLIB_SUPPORT - Display *foreign_xdpy; -#endif - /* List of callback functions that will be given every native event */ - GSList *event_filters; - void *winsys; -}; - -#endif /* __COGL_RENDERER_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-renderer-x11-private.h b/clutter/cogl/cogl/cogl-renderer-x11-private.h deleted file mode 100644 index 5ec56cc..0000000 --- a/clutter/cogl/cogl/cogl-renderer-x11-private.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - */ - -#ifndef __COGL_RENDERER_X11_PRIVATE_H -#define __COGL_RENDERER_X11_PRIVATE_H - -typedef struct _CoglRendererX11 -{ - int damage_base; -} CoglRendererX11; - -#endif /* __COGL_RENDERER_X11_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-renderer-xlib-private.h b/clutter/cogl/cogl/cogl-renderer-xlib-private.h deleted file mode 100644 index bc8ccb5..0000000 --- a/clutter/cogl/cogl/cogl-renderer-xlib-private.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - */ - -#ifndef __COGL_RENDERER_XLIB_PRIVATE_H -#define __COGL_RENDERER_XLIB_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-xlib-private.h" -#include "cogl-renderer-x11-private.h" - -typedef struct _CoglRendererXlib -{ - CoglRendererX11 _parent; - - Display *xdpy; - - /* Current top of the XError trap state stack. The actual memory for - these is expected to be allocated on the stack by the caller */ - CoglXlibTrapState *trap_state; -} CoglRendererXlib; - -gboolean -_cogl_renderer_xlib_connect (CoglRenderer *renderer, GError **error); - -void -_cogl_renderer_xlib_disconnect (CoglRenderer *renderer); - -/* - * cogl_renderer_xlib_trap_errors: - * @state: A temporary place to store data for the trap. - * - * Traps every X error until _cogl_xlib_untrap_errors() called. You - * should allocate an uninitialised CoglXlibTrapState struct on the - * stack to pass to this function. The same pointer should later be - * passed to _cogl_xlib_untrap_errors(). Calls to - * _cogl_xlib_trap_errors() can be nested as long as - * _cogl_xlib_untrap_errors() is called with the corresponding state - * pointers in reverse order. - */ -void -_cogl_renderer_xlib_trap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state); - -/* - * cogl_renderer_xlib_untrap_errors: - * @state: The state that was passed to _cogl_xlib_trap_errors(). - * - * Removes the X error trap and returns the current status. - * - * Return value: the trapped error code, or 0 for success - */ -int -_cogl_renderer_xlib_untrap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state); - -#endif /* __COGL_RENDERER_XLIB_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-renderer-xlib.c b/clutter/cogl/cogl/cogl-renderer-xlib.c deleted file mode 100644 index f8dbe50..0000000 --- a/clutter/cogl/cogl/cogl-renderer-xlib.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-object.h" - -#include "cogl-renderer-private.h" -#include "cogl-renderer-xlib-private.h" -#include "cogl-renderer-x11-private.h" -#include "cogl-winsys-private.h" - -#include -#include - -static char *_cogl_x11_display_name = NULL; -static GList *_cogl_xlib_renderers = NULL; - -static void -register_xlib_renderer (CoglRenderer *renderer) -{ - GList *l; - - for (l = _cogl_xlib_renderers; l; l = l->next) - if (l->data == renderer) - return; - - _cogl_xlib_renderers = g_list_prepend (_cogl_xlib_renderers, renderer); -} - -static void -unregister_xlib_renderer (CoglRenderer *renderer) -{ - _cogl_xlib_renderers = g_list_remove (_cogl_xlib_renderers, renderer); -} - -static CoglRenderer * -get_renderer_for_xdisplay (Display *xdpy) -{ - GList *l; - - for (l = _cogl_xlib_renderers; l; l = l->next) - { - CoglRenderer *renderer = l->data; - CoglRendererXlib *xlib_renderer = renderer->winsys; - - if (xlib_renderer->xdpy == xdpy) - return renderer; - } - - return NULL; -} - -static int -error_handler (Display *xdpy, - XErrorEvent *error) -{ - CoglRenderer *renderer; - CoglRendererXlib *xlib_renderer; - - renderer = get_renderer_for_xdisplay (xdpy); - - xlib_renderer = renderer->winsys; - g_assert (xlib_renderer->trap_state); - - xlib_renderer->trap_state->trapped_error_code = error->error_code; - - return 0; -} - -void -_cogl_renderer_xlib_trap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state) -{ - CoglRendererXlib *xlib_renderer; - - xlib_renderer = renderer->winsys; - - state->trapped_error_code = 0; - state->old_error_handler = XSetErrorHandler (error_handler); - - state->old_state = xlib_renderer->trap_state; - xlib_renderer->trap_state = state; -} - -int -_cogl_renderer_xlib_untrap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state) -{ - CoglRendererXlib *xlib_renderer; - - xlib_renderer = renderer->winsys; - g_assert (state == xlib_renderer->trap_state); - - XSetErrorHandler (state->old_error_handler); - - xlib_renderer->trap_state = state->old_state; - - return state->trapped_error_code; -} - -static Display * -assert_xlib_display (CoglRenderer *renderer, GError **error) -{ - Display *xdpy = cogl_renderer_xlib_get_foreign_display (renderer); - CoglRendererXlib *xlib_renderer = renderer->winsys; - - /* A foreign display may have already been set... */ - if (xdpy) - { - xlib_renderer->xdpy = xdpy; - return xdpy; - } - - xdpy = XOpenDisplay (_cogl_x11_display_name); - if (xdpy == NULL) - { - g_set_error (error, - COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, - "Failed to open X Display %s", _cogl_x11_display_name); - return NULL; - } - - xlib_renderer->xdpy = xdpy; - return xdpy; -} - -gboolean -_cogl_renderer_xlib_connect (CoglRenderer *renderer, GError **error) -{ - CoglRendererXlib *xlib_renderer = renderer->winsys; - CoglRendererX11 *x11_renderer = renderer->winsys; - int damage_error; - - if (!assert_xlib_display (renderer, error)) - return FALSE; - - /* Check whether damage events are supported on this display */ - if (!XDamageQueryExtension (xlib_renderer->xdpy, - &x11_renderer->damage_base, - &damage_error)) - x11_renderer->damage_base = -1; - - xlib_renderer->trap_state = NULL; - - register_xlib_renderer (renderer); - - return TRUE; -} - -void -_cogl_renderer_xlib_disconnect (CoglRenderer *renderer) -{ - CoglRendererXlib *xlib_renderer = renderer->winsys; - - if (!renderer->foreign_xdpy) - XCloseDisplay (xlib_renderer->xdpy); - - unregister_xlib_renderer (renderer); -} - -Display * -cogl_renderer_xlib_get_display (CoglRenderer *renderer) -{ - CoglRendererXlib *xlib_renderer; - - g_return_val_if_fail (cogl_is_renderer (renderer), NULL); - - xlib_renderer = renderer->winsys; - - return xlib_renderer->xdpy; -} diff --git a/clutter/cogl/cogl/cogl-renderer.c b/clutter/cogl/cogl/cogl-renderer.c deleted file mode 100644 index 93e33a4..0000000 --- a/clutter/cogl/cogl/cogl-renderer.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-object.h" - -#include "cogl-renderer.h" -#include "cogl-renderer-private.h" -#include "cogl-display-private.h" -#include "cogl-winsys-private.h" - -#ifdef COGL_HAS_FULL_WINSYS - -#ifdef COGL_HAS_GLX_SUPPORT -extern const CoglWinsysVtable *_cogl_winsys_glx_get_vtable (void); -#endif -#ifdef COGL_HAS_EGL_SUPPORT -extern const CoglWinsysVtable *_cogl_winsys_egl_get_vtable (void); -#endif - -typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void); - -static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] = -{ -#ifdef COGL_HAS_GLX_SUPPORT - _cogl_winsys_glx_get_vtable, -#endif -#ifdef COGL_HAS_EGL_SUPPORT - _cogl_winsys_egl_get_vtable -#endif -}; - -#endif /* COGL_HAS_FULL_WINSYS */ - -static void _cogl_renderer_free (CoglRenderer *renderer); - -COGL_OBJECT_DEFINE (Renderer, renderer); - -typedef struct _CoglNativeFilterClosure -{ - CoglNativeFilterFunc func; - void *data; -} CoglNativeFilterClosure; - -GQuark -cogl_renderer_error_quark (void) -{ - return g_quark_from_static_string ("cogl-renderer-error-quark"); -} - -static const CoglWinsysVtable * -_cogl_renderer_get_winsys (CoglRenderer *renderer) -{ - return renderer->winsys_vtable; -} - -static void -native_filter_closure_free (CoglNativeFilterClosure *closure) -{ - g_slice_free (CoglNativeFilterClosure, closure); -} - -static void -_cogl_renderer_free (CoglRenderer *renderer) -{ -#ifdef COGL_HAS_FULL_WINSYS - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - winsys->renderer_disconnect (renderer); -#endif - - g_slist_foreach (renderer->event_filters, - (GFunc) native_filter_closure_free, - NULL); - g_slist_free (renderer->event_filters); - - g_free (renderer); -} - -CoglRenderer * -cogl_renderer_new (void) -{ - CoglRenderer *renderer = g_new0 (CoglRenderer, 1); - - renderer->connected = FALSE; - renderer->event_filters = NULL; - - return _cogl_renderer_object_new (renderer); -} - -#if COGL_HAS_XLIB_SUPPORT -void -cogl_renderer_xlib_set_foreign_display (CoglRenderer *renderer, - Display *xdisplay) -{ - g_return_if_fail (cogl_is_renderer (renderer)); - - /* NB: Renderers are considered immutable once connected */ - g_return_if_fail (!renderer->connected); - - renderer->foreign_xdpy = xdisplay; -} - -Display * -cogl_renderer_xlib_get_foreign_display (CoglRenderer *renderer) -{ - g_return_val_if_fail (cogl_is_renderer (renderer), NULL); - - return renderer->foreign_xdpy; -} -#endif /* COGL_HAS_XLIB_SUPPORT */ - -gboolean -cogl_renderer_check_onscreen_template (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template, - GError **error) -{ -#ifdef COGL_HAS_FULL_WINSYS - CoglDisplay *display; - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - if (!winsys->renderer_connect (renderer, error)) - return FALSE; - - display = cogl_display_new (renderer, onscreen_template); - if (!cogl_display_setup (display, error)) - { - cogl_object_unref (display); - return FALSE; - } - - cogl_object_unref (display); -#endif - return TRUE; -} - -/* Final connection API */ - -gboolean -cogl_renderer_connect (CoglRenderer *renderer, GError **error) -{ -#ifdef COGL_HAS_FULL_WINSYS - int i; - char *renderer_name = getenv ("COGL_RENDERER"); -#endif - GString *error_message; - - if (renderer->connected) - return TRUE; - -#ifdef COGL_HAS_FULL_WINSYS - error_message = g_string_new (""); - for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++) - { - const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i](); - GError *tmp_error = NULL; - - if (renderer_name && strcmp (winsys->name, renderer_name) != 0) - continue; - - if (!winsys->renderer_connect (renderer, &tmp_error)) - { - g_string_append_c (error_message, '\n'); - g_string_append (error_message, tmp_error->message); - g_error_free (tmp_error); - } - else - { - renderer->winsys_vtable = winsys; - renderer->connected = TRUE; - g_string_free (error_message, TRUE); - return TRUE; - } - } - - if (!renderer->connected) - { - renderer->winsys_vtable = NULL; - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to connected to any renderer: %s", - error_message->str); - g_string_free (error_message, TRUE); - return FALSE; - } - - return TRUE; -#else - renderer->connected = TRUE; - return TRUE; -#endif -} - -CoglFilterReturn -cogl_renderer_handle_native_event (CoglRenderer *renderer, - void *event) -{ - GSList *l, *next; - - /* Pass the event on to all of the registered filters in turn */ - for (l = renderer->event_filters; l; l = next) - { - CoglNativeFilterClosure *closure = l->data; - - /* The next pointer is taken now so that we can handle the - closure being removed during emission */ - next = l->next; - - if (closure->func (event, closure->data) == COGL_FILTER_REMOVE) - return COGL_FILTER_REMOVE; - } - - /* If the backend for the renderer also wants to see the events, it - should just register its own filter */ - - return COGL_FILTER_CONTINUE; -} - -void -cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - CoglNativeFilterClosure *closure; - - closure = g_slice_new (CoglNativeFilterClosure); - closure->func = func; - closure->data = data; - - renderer->event_filters = g_slist_prepend (renderer->event_filters, closure); -} - -void -cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - GSList *l, *prev = NULL; - - for (l = renderer->event_filters; l; prev = l, l = l->next) - { - CoglNativeFilterClosure *closure = l->data; - - if (closure->func == func && closure->data == data) - { - native_filter_closure_free (closure); - if (prev) - prev->next = g_slist_delete_link (prev->next, l); - else - renderer->event_filters = - g_slist_delete_link (renderer->event_filters, l); - break; - } - } -} diff --git a/clutter/cogl/cogl/cogl-renderer.h b/clutter/cogl/cogl/cogl-renderer.h deleted file mode 100644 index 6d23fe2..0000000 --- a/clutter/cogl/cogl/cogl-renderer.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_RENDERER_H__ -#define __COGL_RENDERER_H__ - -#include - -#include -#include - -#ifdef COGL_HAS_XLIB -#include -#endif - -G_BEGIN_DECLS - -/** - * SECTION:cogl-renderer - * @short_description: - * - */ - -#define cogl_renderer_error_quark cogl_renderer_error_quark_EXP - -#define COGL_RENDERER_ERROR cogl_renderer_error_quark () -GQuark -cogl_renderer_error_quark (void); - -typedef struct _CoglRenderer CoglRenderer; - -#define cogl_is_renderer cogl_is_renderer_EXP -gboolean -cogl_is_renderer (void *object); - -#define cogl_renderer_new cogl_renderer_new_EXP -CoglRenderer * -cogl_renderer_new (void); - -/* optional configuration APIs */ - -#define cogl_renderer_handle_native_event cogl_renderer_handle_native_event_EXP -/* - * cogl_renderer_handle_native_event: - * @event: pointer to native event structure - * - * This function processes a single event; it can be used to hook into - * external event retrieval (for example that done by Clutter or - * GDK). The type of the structure that event points to depends on the - * window system used for the renderer. On an xlib renderer it would - * be a pointer to an XEvent or an a Windows renderer it would be a - * pointer to a MSG struct. - * - * Return value: #CoglFilterReturn. %COGL_FILTER_REMOVE indicates that - * Cogl has internally handled the event and the caller should do no - * further processing. %COGL_FILTER_CONTINUE indicates that Cogl is - * either not interested in the event, or has used the event to update - * internal state without taking any exclusive action. - */ -CoglFilterReturn -cogl_renderer_handle_native_event (CoglRenderer *renderer, - void *event); - -#define cogl_renderer_add_native_filter cogl_renderer_add_native_filter_EXP -/* - * _cogl_renderer_add_native_filter: - * - * Adds a callback function that will receive all native events. The - * function can stop further processing of the event by return - * %COGL_FILTER_REMOVE. What is considered a native event depends on - * the type of renderer used. An xlib based renderer would pass all - * XEvents whereas a Windows based renderer would pass MSGs. - */ -void -cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - -#define cogl_renderer_remove_native_filter \ - cogl_renderer_remove_native_filter_EXP -/* - * _cogl_renderer_remove_native_filter: - * - * Removes a callback that was previously added with - * _cogl_renderer_add_native_filter(). - */ -void -cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - -#ifdef COGL_HAS_XLIB - -#define cogl_renderer_xlib_get_foreign_display \ - cogl_renderer_xlib_get_foreign_display_EXP -/* - * cogl_renderer_xlib_get_foreign_display: - * - * Return value: the foreign Xlib display that will be used by any Xlib based - * winsys backend. The display needs to be set with - * cogl_renderer_xlib_set_foreign_display() before this function is called. - */ -Display * -cogl_renderer_xlib_get_foreign_display (CoglRenderer *renderer); - -#define cogl_renderer_xlib_set_foreign_display \ - cogl_renderer_xlib_set_foreign_display_EXP -/* - * cogl_renderer_xlib_set_foreign_display: - * - * Sets a foreign Xlib display that Cogl will use for and Xlib based winsys - * backend. - */ -void -cogl_renderer_xlib_set_foreign_display (CoglRenderer *renderer, - Display *display); - -#define cogl_renderer_xlib_get_display cogl_renderer_xlib_get_display_EXP -Display * -cogl_renderer_xlib_get_display (CoglRenderer *renderer); - -#endif /* COGL_HAS_XLIB */ - -#define cogl_renderer_check_onscreen_template \ - cogl_renderer_check_onscreen_template_EXP -gboolean -cogl_renderer_check_onscreen_template (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template, - GError **error); - -/* Final connection API */ - -#define cogl_renderer_connect cogl_renderer_connect_EXP -gboolean -cogl_renderer_connect (CoglRenderer *renderer, GError **error); - -G_END_DECLS - -#endif /* __COGL_RENDERER_H__ */ - diff --git a/clutter/cogl/cogl/cogl-shader-boilerplate.h b/clutter/cogl/cogl/cogl-shader-boilerplate.h deleted file mode 100644 index 3a23de1..0000000 --- a/clutter/cogl/cogl/cogl-shader-boilerplate.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_SHADER_BOILERPLATE_H -#define __COGL_SHADER_BOILERPLATE_H - -#include "cogl.h" - - -#ifndef HAVE_COGL_GLES2 - -#define _COGL_COMMON_SHADER_BOILERPLATE \ - "#define COGL_VERSION 100\n" \ - "\n" \ - "#define cogl_modelview_matrix gl_ModelViewMatrix\n" \ - "#define cogl_modelview_projection_matrix gl_ModelViewProjectionMatrix\n" \ - "#define cogl_projection_matrix gl_ProjectionMatrix\n" \ - "#define cogl_texture_matrix gl_TextureMatrix\n" \ - "\n" - -#define _COGL_VERTEX_SHADER_BOILERPLATE \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "#define cogl_position_in gl_Vertex\n" \ - "#define cogl_color_in gl_Color\n" \ - "#define cogl_tex_coord_in gl_MultiTexCoord0\n" \ - "#define cogl_tex_coord0_in gl_MultiTexCoord0\n" \ - "#define cogl_tex_coord1_in gl_MultiTexCoord1\n" \ - "#define cogl_tex_coord2_in gl_MultiTexCoord2\n" \ - "#define cogl_tex_coord3_in gl_MultiTexCoord3\n" \ - "#define cogl_tex_coord4_in gl_MultiTexCoord4\n" \ - "#define cogl_tex_coord5_in gl_MultiTexCoord5\n" \ - "#define cogl_tex_coord6_in gl_MultiTexCoord6\n" \ - "#define cogl_tex_coord7_in gl_MultiTexCoord7\n" \ - "#define cogl_normal_in gl_Normal\n" \ - "\n" \ - "#define cogl_position_out gl_Position\n" \ - "#define cogl_point_size_out gl_PointSize\n" \ - "#define cogl_color_out gl_FrontColor\n" \ - "#define cogl_tex_coord_out gl_TexCoord\n" - -#define _COGL_FRAGMENT_SHADER_BOILERPLATE \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "#define cogl_color_in gl_Color\n" \ - "#define cogl_tex_coord_in gl_TexCoord\n" \ - "\n" \ - "#define cogl_color_out gl_FragColor\n" \ - "#define cogl_depth_out gl_FragDepth\n" \ - "\n" \ - "#define cogl_front_facing gl_FrontFacing\n" -#if 0 - /* GLSL 1.2 has a bottom left origin, though later versions - * allow use of an origin_upper_left keyword which would be - * more appropriate for Cogl. */ - "#define coglFragCoord gl_FragCoord\n" -#endif - -#else /* HAVE_COGL_GLES2 */ - -#define _COGL_COMMON_SHADER_BOILERPLATE \ - "#define COGL_VERSION 100\n" \ - "\n" \ - "uniform mat4 cogl_modelview_matrix;\n" \ - "uniform mat4 cogl_modelview_projection_matrix;\n" \ - "uniform mat4 cogl_projection_matrix;\n" \ - "uniform float cogl_point_size_in;\n" - -/* This declares all of the variables that we might need. This is - working on the assumption that the compiler will optimise them out - if they are not actually used. The GLSL spec for GLES at least - implies that this will happen for varyings but it doesn't - explicitly so for attributes */ -#define _COGL_VERTEX_SHADER_BOILERPLATE \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "#define cogl_color_out _cogl_color\n" \ - "varying vec4 _cogl_color;\n" \ - "#define cogl_tex_coord_out _cogl_tex_coord\n" \ - "#define cogl_position_out gl_Position\n" \ - "#define cogl_point_size_out gl_PointSize\n" \ - "\n" \ - "attribute vec4 cogl_color_in;\n" \ - "attribute vec4 cogl_position_in;\n" \ - "#define cogl_tex_coord_in cogl_tex_coord0_in;\n" \ - "attribute vec3 cogl_normal_in;\n" - -#define _COGL_FRAGMENT_SHADER_BOILERPLATE \ - "#if __VERSION__ == 100\n" \ - "precision highp float;\n" \ - "#endif\n" \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "\n" \ - "varying vec4 _cogl_color;\n" \ - "\n" \ - "#define cogl_color_in _cogl_color\n" \ - "#define cogl_tex_coord_in _cogl_tex_coord\n" \ - "\n" \ - "#define cogl_color_out gl_FragColor\n" \ - "#define cogl_depth_out gl_FragDepth\n" \ - "\n" \ - "#define cogl_front_facing gl_FrontFacing\n" - -#endif /* HAVE_COGL_GLES2 */ - -#endif /* __COGL_SHADER_BOILERPLATE_H */ - diff --git a/clutter/cogl/cogl/cogl-shader-private.h b/clutter/cogl/cogl/cogl-shader-private.h deleted file mode 100644 index 3b4b232..0000000 --- a/clutter/cogl/cogl/cogl-shader-private.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_SHADER_H -#define __COGL_SHADER_H - -#include "cogl-handle.h" - -typedef struct _CoglShader CoglShader; - -typedef enum -{ - COGL_SHADER_LANGUAGE_GLSL, -#ifdef HAVE_COGL_GL - COGL_SHADER_LANGUAGE_ARBFP -#endif -} CoglShaderLanguage; - -struct _CoglShader -{ - CoglHandleObject _parent; - GLuint gl_handle; - int n_tex_coord_attribs; - CoglShaderType type; - CoglShaderLanguage language; - char *source; -}; - -CoglShader *_cogl_shader_pointer_from_handle (CoglHandle handle); - -void -_cogl_shader_compile_real (CoglHandle handle, int n_tex_coord_attribs); - -CoglShaderLanguage -_cogl_program_get_language (CoglHandle handle); - -void -_cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle, - GLenum shader_gl_type, - int n_tex_coord_attribs, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in); - -#endif /* __COGL_SHADER_H */ diff --git a/clutter/cogl/cogl/cogl-shader.c b/clutter/cogl/cogl/cogl-shader.c deleted file mode 100644 index cb00836..0000000 --- a/clutter/cogl/cogl/cogl-shader.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-shader-private.h" -#include "cogl-shader-boilerplate.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" - -#include - -#include - -#ifdef HAVE_COGL_GL -#define glCreateShader ctx->drv.pf_glCreateShader -#define glGetShaderiv ctx->drv.pf_glGetShaderiv -#define glGetShaderInfoLog ctx->drv.pf_glGetShaderInfoLog -#define glCompileShader ctx->drv.pf_glCompileShader -#define glShaderSource ctx->drv.pf_glShaderSource -#define glDeleteShader ctx->drv.pf_glDeleteShader -#define glProgramString ctx->drv.pf_glProgramString -#define glBindProgram ctx->drv.pf_glBindProgram -#define glDeletePrograms ctx->drv.pf_glDeletePrograms -#define glGenPrograms ctx->drv.pf_glGenPrograms -#define GET_CONTEXT _COGL_GET_CONTEXT -#else -#define GET_CONTEXT(CTXVAR,RETVAL) G_STMT_START { } G_STMT_END -#endif - -static void _cogl_shader_free (CoglShader *shader); - -COGL_HANDLE_DEFINE (Shader, shader); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (shader); - -static void -_cogl_shader_free (CoglShader *shader) -{ -#ifndef HAVE_COGL_GLES - - /* Frees shader resources but its handle is not - released! Do that separately before this! */ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - { - if (shader->gl_handle) - GE (glDeletePrograms (1, &shader->gl_handle)); - } - else -#endif - if (shader->gl_handle) - GE (glDeleteShader (shader->gl_handle)); - -#endif /* HAVE_COGL_GLES */ - - g_slice_free (CoglShader, shader); -} - -CoglHandle -cogl_create_shader (CoglShaderType type) -{ - CoglShader *shader; - - GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - switch (type) - { - case COGL_SHADER_TYPE_VERTEX: - case COGL_SHADER_TYPE_FRAGMENT: - break; - default: - g_warning ("Unexpected shader type (0x%08lX) given to " - "cogl_create_shader", (unsigned long) type); - return COGL_INVALID_HANDLE; - } - - shader = g_slice_new (CoglShader); - shader->language = COGL_SHADER_LANGUAGE_GLSL; - shader->gl_handle = 0; -#ifdef HAVE_COGL_GLES2 - shader->n_tex_coord_attribs = 0; -#endif - shader->type = type; - - return _cogl_shader_handle_new (shader); -} - -static void -delete_shader (CoglShader *shader) -{ -#ifndef HAVE_COGL_GLES - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - { - if (shader->gl_handle) - GE (glDeletePrograms (1, &shader->gl_handle)); - } - else -#endif - { - if (shader->gl_handle) - GE (glDeleteShader (shader->gl_handle)); - } - - shader->gl_handle = 0; - -#endif /* HAVE_COGL_GLES */ -} - -void -cogl_shader_source (CoglHandle handle, - const char *source) -{ - CoglShader *shader; - CoglShaderLanguage language; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!cogl_is_shader (handle)) - return; - - shader = _cogl_shader_pointer_from_handle (handle); - -#ifdef HAVE_COGL_GL - if (strncmp (source, "!!ARBfp1.0", 10) == 0) - language = COGL_SHADER_LANGUAGE_ARBFP; - else -#endif - language = COGL_SHADER_LANGUAGE_GLSL; - - /* Delete the old object if the language is changing... */ - if (G_UNLIKELY (language != shader->language) && - shader->gl_handle) - delete_shader (shader); - - shader->source = g_strdup (source); - - shader->language = language; -} - -void -cogl_shader_compile (CoglHandle handle) -{ -#ifdef HAVE_COGL_GL - CoglShader *shader = handle; -#endif - - if (!cogl_is_shader (handle)) - return; - -#ifdef HAVE_COGL_GL - _cogl_shader_compile_real (shader, 0 /* ignored */); -#endif - - /* XXX: For GLES2 we don't actually compile anything until the - * shader gets used so we have an opportunity to add some - * boilerplate to the shader. - * - * At the end of the day this is obviously a badly designed API - * given that we are having to lie to the user. It was a mistake to - * so thinly wrap the OpenGL shader API and the current plan is to - * replace it with a pipeline snippets API. */ -} - -void -_cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle, - GLenum shader_gl_type, - int n_tex_coord_attribs, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in) -{ -#ifndef HAVE_COGL_GLES - - static const char vertex_boilerplate[] = _COGL_VERTEX_SHADER_BOILERPLATE; - static const char fragment_boilerplate[] = _COGL_FRAGMENT_SHADER_BOILERPLATE; - - const char **strings = g_alloca (sizeof (char *) * (count_in + 3)); - GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 3)); - int count = 0; -#ifdef HAVE_COGL_GLES2 - char *tex_coord_declarations = NULL; -#endif - - GET_CONTEXT (ctx, NO_RETVAL); - -#ifdef HAVE_COGL_GLES2 - if (cogl_features_available (COGL_FEATURE_TEXTURE_3D)) - { - static const char texture_3d_extension[] = - "#extension GL_OES_texture_3D : enable\n"; - strings[count] = texture_3d_extension; - lengths[count++] = sizeof (texture_3d_extension) - 1; - } -#endif - - if (shader_gl_type == GL_VERTEX_SHADER) - { - strings[count] = vertex_boilerplate; - lengths[count++] = sizeof (vertex_boilerplate) - 1; - } - else if (shader_gl_type == GL_FRAGMENT_SHADER) - { - strings[count] = fragment_boilerplate; - lengths[count++] = sizeof (fragment_boilerplate) - 1; - } - -#ifdef HAVE_COGL_GLES2 - if (n_tex_coord_attribs) - { - GString *declarations = g_string_new (NULL); - - g_string_append_printf (declarations, - "varying vec4 _cogl_tex_coord[%d];\n", - n_tex_coord_attribs); - - if (shader_gl_type == GL_VERTEX_SHADER) - { - int i; - - g_string_append_printf (declarations, - "uniform mat4 cogl_texture_matrix[%d];\n", - n_tex_coord_attribs); - - for (i = 0; i < n_tex_coord_attribs; i++) - g_string_append_printf (declarations, - "attribute vec4 cogl_tex_coord%d_in;\n", - i); - } - - tex_coord_declarations = g_string_free (declarations, FALSE); - strings[count] = tex_coord_declarations; - lengths[count++] = -1; /* null terminated */ - } -#endif - - memcpy (strings + count, strings_in, sizeof (char *) * count_in); - if (lengths_in) - memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in); - else - { - int i; - - for (i = 0; i < count_in; i++) - lengths[count + i] = -1; /* null terminated */ - } - count += count_in; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - { - GString *buf = g_string_new (NULL); - int i; - - g_string_append_printf (buf, - "%s shader:\n", - shader_gl_type == GL_VERTEX_SHADER ? - "vertex" : "fragment"); - for (i = 0; i < count; i++) - if (lengths[i] != -1) - g_string_append_len (buf, strings[i], lengths[i]); - else - g_string_append (buf, strings[i]); - - g_message ("%s", buf->str); - - g_string_free (buf, TRUE); - } - - GE( glShaderSource (shader_gl_handle, count, - (const char **) strings, lengths) ); - -#ifdef HAVE_COGL_GLES2 - g_free (tex_coord_declarations); -#endif - -#endif /* HAVE_COGL_GLES */ -} - -void -_cogl_shader_compile_real (CoglHandle handle, - int n_tex_coord_attribs) -{ -#ifndef HAVE_COGL_GLES - - CoglShader *shader = handle; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - { -#ifdef COGL_GL_DEBUG - GLenum gl_error; -#endif - - if (shader->gl_handle) - return; - - GE (glGenPrograms (1, &shader->gl_handle)); - - GE (glBindProgram (GL_FRAGMENT_PROGRAM_ARB, shader->gl_handle)); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - g_message ("user ARBfp program:\n%s", shader->source); - -#ifdef COGL_GL_DEBUG - while ((gl_error = glGetError ()) != GL_NO_ERROR) - ; -#endif - glProgramString (GL_FRAGMENT_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - strlen (shader->source), - shader->source); -#ifdef COGL_GL_DEBUG - gl_error = glGetError (); - if (gl_error != GL_NO_ERROR) - { - g_warning ("%s: GL error (%d): Failed to compile ARBfp:\n%s\n%s", - G_STRLOC, - gl_error, - shader->source, - glGetString (GL_PROGRAM_ERROR_STRING_ARB)); - } -#endif - } - else -#endif - { - GLenum gl_type; - - if (shader->gl_handle -#ifdef HAVE_COGL_GLES2 - && shader->n_tex_coord_attribs >= n_tex_coord_attribs -#endif - ) - return; - - if (shader->gl_handle) - delete_shader (shader); - - switch (shader->type) - { - case COGL_SHADER_TYPE_VERTEX: - gl_type = GL_VERTEX_SHADER; - break; - case COGL_SHADER_TYPE_FRAGMENT: - gl_type = GL_FRAGMENT_SHADER; - break; - default: - g_assert_not_reached (); - break; - } - - shader->gl_handle = glCreateShader (gl_type); - - _cogl_shader_set_source_with_boilerplate (shader->gl_handle, - gl_type, - n_tex_coord_attribs, - 1, - (const char **) &shader->source, - NULL); - - GE (glCompileShader (shader->gl_handle)); - -#ifdef HAVE_COGL_GLES2 - shader->n_tex_coord_attribs = n_tex_coord_attribs; -#endif - -#ifdef COGL_GL_DEBUG - if (!cogl_shader_is_compiled (handle)) - { - char *log = cogl_shader_get_info_log (handle); - g_warning ("Failed to compile GLSL program:\nsrc:\n%s\nerror:\n%s\n", - shader->source, - log); - } -#endif - } - -#endif /* HAVE_COGL_GLES */ -} - -char * -cogl_shader_get_info_log (CoglHandle handle) -{ -#ifdef HAVE_COGL_GLES - - return NULL; - -#else /* HAVE_COGL_GLES */ - - CoglShader *shader; - - GET_CONTEXT (ctx, NULL); - - if (!cogl_is_shader (handle)) - return NULL; - - shader = _cogl_shader_pointer_from_handle (handle); - -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - { - /* ARBfp exposes a program error string, but since cogl_program - * doesn't have any API to query an error log it is not currently - * exposed. */ - return g_strdup (""); - } - else -#endif - { - char buffer[512]; - int len = 0; - - /* We don't normally compile the shader when the user calls - * cogl_shader_compile() because we want to be able to add - * boilerplate code that depends on how it ends up finally being - * used. - * - * Here we force an early compile if the user is interested in - * log information to increase the chance that the log will be - * useful! We have to guess the number of texture coordinate - * attributes that may be used (normally less than 4) since that - * affects the boilerplate. - */ - if (!shader->gl_handle) - _cogl_shader_compile_real (handle, 4); - - glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer); - buffer[len] = '\0'; - return g_strdup (buffer); - } - -#endif /* HAVE_COGL_GLES */ -} - -CoglShaderType -cogl_shader_get_type (CoglHandle handle) -{ - CoglShader *shader; - - GET_CONTEXT (ctx, COGL_SHADER_TYPE_VERTEX); - - if (!cogl_is_shader (handle)) - { - g_warning ("Non shader handle type passed to cogl_shader_get_type"); - return COGL_SHADER_TYPE_VERTEX; - } - - shader = _cogl_shader_pointer_from_handle (handle); - return shader->type; -} - -gboolean -cogl_shader_is_compiled (CoglHandle handle) -{ -#ifdef HAVE_COGL_GLES - - return FALSE; - -#else /* HAVE_COGL_GLES */ - - GLint status; - CoglShader *shader; - - GET_CONTEXT (ctx, FALSE); - - if (!cogl_is_shader (handle)) - return FALSE; - - shader = _cogl_shader_pointer_from_handle (handle); - -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - return TRUE; - else -#endif - { - /* FIXME: We currently have an arbitrary limit of 4 texture - * coordinate attributes since our API means we have to add - * some boilerplate to the users GLSL program (for GLES2) - * before we actually know how many attributes are in use. - * - * 4 will probably be enough (or at least that limitation should - * be enough until we can replace this API with the pipeline - * snippets API) but if it isn't then the shader won't compile, - * through no fault of the user. - * - * To some extent this is just a symptom of bad API design; it - * was a mistake for Cogl to so thinly wrap the OpenGL shader - * API. Eventually we plan for this whole API will be deprecated - * by the pipeline snippets framework. - */ - if (!shader->gl_handle) - _cogl_shader_compile_real (handle, 4); - - GE (glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status)); - if (status == GL_TRUE) - return TRUE; - else - return FALSE; - } - -#endif /* HAVE_COGL_GLES */ -} diff --git a/clutter/cogl/cogl/cogl-shader.h b/clutter/cogl/cogl/cogl-shader.h deleted file mode 100644 index 9d0d7ad..0000000 --- a/clutter/cogl/cogl/cogl-shader.h +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_SHADER_H__ -#define __COGL_SHADER_H__ - -#include -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-shaders - * @short_description: Fuctions for accessing the programmable GL pipeline - * - * COGL allows accessing the GL programmable pipeline in order to create - * vertex and fragment shaders. - * - * The only supported format is GLSL shaders. - */ - -/** - * CoglShaderType: - * @COGL_SHADER_TYPE_VERTEX: A program for proccessing vertices - * @COGL_SHADER_TYPE_FRAGMENT: A program for processing fragments - * - * Types of shaders - * - * Since: 1.0 - */ -typedef enum { - COGL_SHADER_TYPE_VERTEX, - COGL_SHADER_TYPE_FRAGMENT -} CoglShaderType; - -/** - * cogl_create_shader: - * @shader_type: COGL_SHADER_TYPE_VERTEX or COGL_SHADER_TYPE_FRAGMENT. - * - * Create a new shader handle, use #cogl_shader_source to set the source code - * to be used on it. - * - * Returns: a new shader handle. - */ -CoglHandle -cogl_create_shader (CoglShaderType shader_type); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_shader_ref: - * @handle: A #CoglHandle to a shader. - * - * Add an extra reference to a shader. - * - * Returns: @handle - */ -CoglHandle -cogl_shader_ref (CoglHandle handle) G_GNUC_DEPRECATED; - -/** - * cogl_shader_unref: - * @handle: A #CoglHandle to a shader. - * - * Removes a reference to a shader. If it was the last reference the - * shader object will be destroyed. - */ -void -cogl_shader_unref (CoglHandle handle) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_is_shader: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing shader object. - * - * Returns: %TRUE if the handle references a shader, - * %FALSE otherwise - */ -gboolean cogl_is_shader (CoglHandle handle); - -/** - * cogl_shader_source: - * @shader: #CoglHandle for a shader. - * @source: GLSL shader source. - * - * Replaces the current GLSL source associated with a shader with a new - * one. - */ -void -cogl_shader_source (CoglHandle shader, - const char *source); -/** - * cogl_shader_compile: - * @handle: #CoglHandle for a shader. - * - * Compiles the shader, no return value, but the shader is now ready for - * linking into a program. - */ -void -cogl_shader_compile (CoglHandle handle); - -/** - * cogl_shader_get_info_log: - * @handle: #CoglHandle for a shader. - * - * Retrieves the information log for a coglobject, can be used in conjunction - * with cogl_shader_get_parameteriv() to retrieve the compiler warnings/error - * messages that caused a shader to not compile correctly, mainly useful for - * debugging purposes. - * - * Return value: a newly allocated string containing the info log. Use - * g_free() to free it - */ -char * -cogl_shader_get_info_log (CoglHandle handle); - -/** - * cogl_shader_get_type: - * @handle: #CoglHandle for a shader. - * - * Retrieves the type of a shader #CoglHandle - * - * Return value: %COGL_SHADER_TYPE_VERTEX if the shader is a vertex processor - * or %COGL_SHADER_TYPE_FRAGMENT if the shader is a frament processor - */ -CoglShaderType -cogl_shader_get_type (CoglHandle handle); - -/** - * cogl_shader_is_compiled: - * @handle: #CoglHandle for a shader. - * - * Retrieves whether a shader #CoglHandle has been compiled - * - * Return value: %TRUE if the shader object has sucessfully be compiled - */ -gboolean -cogl_shader_is_compiled (CoglHandle handle); - -/** - * cogl_create_program: - * - * Create a new cogl program object that can be used to replace parts of the GL - * rendering pipeline with custom code. - * - * Returns: a new cogl program. - */ -CoglHandle -cogl_create_program (void); - -/** - * cogl_program_ref: - * @handle: A #CoglHandle to a program. - * - * Add an extra reference to a program. - * - * Returns: @handle - */ -CoglHandle -cogl_program_ref (CoglHandle handle); - -/** - * cogl_program_unref: - * @handle: A #CoglHandle to a program. - * - * Removes a reference to a program. If it was the last reference the - * program object will be destroyed. - */ -void -cogl_program_unref (CoglHandle handle); - -/** - * cogl_is_program: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing program object. - * - * Returns: %TRUE if the handle references a program, - * %FALSE otherwise - */ -gboolean -cogl_is_program (CoglHandle handle); - -/** - * cogl_program_attach_shader: - * @program_handle: a #CoglHandle for a shdaer program. - * @shader_handle: a #CoglHandle for a vertex of fragment shader. - * - * Attaches a shader to a program object, a program can have one vertex shader - * and one fragment shader attached. - */ -void -cogl_program_attach_shader (CoglHandle program_handle, - CoglHandle shader_handle); - - -/** - * cogl_program_link: - * @handle: a #CoglHandle for a shader program. - * - * Links a program making it ready for use. - */ -void -cogl_program_link (CoglHandle handle); - -/** - * cogl_program_use: - * @handle: a #CoglHandle for a shader program or %COGL_INVALID_HANDLE. - * - * Activate a specific shader program replacing that part of the GL - * rendering pipeline, if passed in %COGL_INVALID_HANDLE the default - * behavior of GL is reinstated. - */ -void -cogl_program_use (CoglHandle handle); - -/** - * cogl_program_get_uniform_location: - * @handle: a #CoglHandle for a shader program. - * @uniform_name: the name of a uniform. - * - * Retrieve the location (offset) of a uniform variable in a shader program, - * a uniform is a variable that is constant for all vertices/fragments for a - * shader object and is possible to modify as an external parameter. - * - * Return value: the offset of a uniform in a specified program. - * This uniform can be set using cogl_program_uniform_1f() when the - * program is in use. - */ -int -cogl_program_get_uniform_location (CoglHandle handle, - const char *uniform_name); - -/** - * cogl_program_set_uniform_1f: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @value: the new value of the uniform. - * - * Changes the value of a floating point uniform for the given linked - * @program. - * - * Since: 1.4 - */ -void -cogl_program_set_uniform_1f (CoglHandle program, - int uniform_location, - float value); - -/** - * cogl_program_set_uniform_1i: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @value: the new value of the uniform. - * - * Changes the value of an integer uniform for the given linked - * @program. - * - * Since: 1.4 - */ -void -cogl_program_set_uniform_1i (CoglHandle program, - int uniform_location, - int value); - -/** - * cogl_program_set_uniform_float: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @n_components: The number of components for the uniform. For - * example with glsl you'd use 3 for a vec3 or 4 for a vec4. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @value: (array length=count): the new value of the uniform[s]. - * - * Changes the value of a float vector uniform, or uniform array for - * the given linked @program. - * - * Since: 1.4 - */ -void -cogl_program_set_uniform_float (CoglHandle program, - int uniform_location, - int n_components, - int count, - const float *value); - -/** - * cogl_program_set_uniform_int: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @n_components: The number of components for the uniform. For - * example with glsl you'd use 3 for a vec3 or 4 for a vec4. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @value: (array length=count): the new value of the uniform[s]. - * - * Changes the value of a int vector uniform, or uniform array for - * the given linked @program. - * - * Since: 1.4 - */ -void -cogl_program_set_uniform_int (CoglHandle program, - int uniform_location, - int n_components, - int count, - const int *value); - -/** - * cogl_program_set_uniform_matrix: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @dimensions: The dimensions of the matrix. So for for example pass - * 2 for a 2x2 matrix or 3 for 3x3. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @transpose: Whether to transpose the matrix when setting the uniform. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a matrix uniform, or uniform array in the - * given linked @program. - * - * Since: 1.4 - */ -void -cogl_program_set_uniform_matrix (CoglHandle program, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_program_uniform_1f: - * @uniform_no: the uniform to set. - * @value: the new value of the uniform. - * - * Changes the value of a floating point uniform in the currently - * used (see cogl_program_use()) shader program. - * - * Deprecated: 1.4: Use cogl_program_set_uniform_1f() instead. - */ -void -cogl_program_uniform_1f (int uniform_no, - float value) G_GNUC_DEPRECATED; - -/** - * cogl_program_uniform_1i: - * @uniform_no: the uniform to set. - * @value: the new value of the uniform. - * - * Changes the value of an integer uniform in the currently - * used (see cogl_program_use()) shader program. - * - * Deprecated: 1.4: Use cogl_program_set_uniform_1i() instead. - */ -void -cogl_program_uniform_1i (int uniform_no, - int value) G_GNUC_DEPRECATED; - -/** - * cogl_program_uniform_float: - * @uniform_no: the uniform to set. - * @size: Size of float vector. - * @count: Size of array of uniforms. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a float vector uniform, or uniform array in the - * currently used (see cogl_program_use()) shader program. - * - * Deprecated: 1.4: Use cogl_program_set_uniform_float() instead. - */ -void -cogl_program_uniform_float (int uniform_no, - int size, - int count, - const float *value) G_GNUC_DEPRECATED; - -/** - * cogl_program_uniform_int: - * @uniform_no: the uniform to set. - * @size: Size of int vector. - * @count: Size of array of uniforms. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a int vector uniform, or uniform array in the - * currently used (see cogl_program_use()) shader program. - */ -void -cogl_program_uniform_int (int uniform_no, - int size, - int count, - const int *value) G_GNUC_DEPRECATED; - -/** - * cogl_program_uniform_matrix: - * @uniform_no: the uniform to set. - * @size: Size of matrix. - * @count: Size of array of uniforms. - * @transpose: Whether to transpose the matrix when setting the uniform. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a matrix uniform, or uniform array in the - * currently used (see cogl_program_use()) shader program. The @size - * parameter is used to determine the square size of the matrix. - */ -void -cogl_program_uniform_matrix (int uniform_no, - int size, - int count, - gboolean transpose, - const float *value) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -G_END_DECLS - -#endif /* __COGL_SHADER_H__ */ diff --git a/clutter/cogl/cogl/cogl-spans.c b/clutter/cogl/cogl/cogl-spans.c deleted file mode 100644 index 4a3f0a8..0000000 --- a/clutter/cogl/cogl/cogl-spans.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "math.h" - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-spans.h" - -void -_cogl_span_iter_update (CoglSpanIter *iter) -{ - /* Pick current span */ - iter->span = &g_array_index (iter->array, CoglSpan, iter->index); - - /* Offset next position by span size */ - iter->next_pos = iter->pos + - (float)(iter->span->size - iter->span->waste); - - /* Check if span intersects the area to cover */ - if (iter->next_pos <= iter->cover_start || - iter->pos >= iter->cover_end) - { - /* Intersection undefined */ - iter->intersects = FALSE; - return; - } - - iter->intersects = TRUE; - - /* Clip start position to coverage area */ - if (iter->pos < iter->cover_start) - iter->intersect_start = iter->cover_start; - else - iter->intersect_start = iter->pos; - - /* Clip end position to coverage area */ - if (iter->next_pos > iter->cover_end) - iter->intersect_end = iter->cover_end; - else - iter->intersect_end = iter->next_pos; -} - -void -_cogl_span_iter_begin (CoglSpanIter *iter, - GArray *spans, - float normalize_factor, - float cover_start, - float cover_end) -{ - float cover_start_normalized; - - iter->index = 0; - iter->span = NULL; - - iter->array = spans; - - /* We always iterate in a positive direction from the origin. If - * iter->flipped == TRUE that means whoever is using this API should - * interpreted the current span as extending in the opposite direction. I.e. - * it extends to the left if iterating the X axis, or up if the Y axis. */ - if (cover_start > cover_end) - { - float tmp = cover_start; - cover_start = cover_end; - cover_end = tmp; - iter->flipped = TRUE; - } - else - iter->flipped = FALSE; - - /* The texture spans cover the normalized texture coordinate space ranging - * from [0,1] but to help support repeating of sliced textures we allow - * iteration of any range so we need to relate the start of the range to the - * nearest point equivalent to 0. - */ - cover_start_normalized = cover_start / normalize_factor; - iter->origin = floorf (cover_start_normalized) * normalize_factor; - - iter->cover_start = cover_start; - iter->cover_end = cover_end; - iter->pos = iter->origin; - - /* Update intersection */ - _cogl_span_iter_update (iter); -} - -void -_cogl_span_iter_next (CoglSpanIter *iter) -{ - /* Move current position */ - iter->pos = iter->next_pos; - - /* Pick next slice (wrap when last reached) */ - iter->index = (iter->index + 1) % iter->array->len; - - /* Update intersection */ - _cogl_span_iter_update (iter); -} - -gboolean -_cogl_span_iter_end (CoglSpanIter *iter) -{ - /* End reached when whole area covered */ - return iter->pos >= iter->cover_end; -} - - diff --git a/clutter/cogl/cogl/cogl-spans.h b/clutter/cogl/cogl/cogl-spans.h deleted file mode 100644 index a134f95..0000000 --- a/clutter/cogl/cogl/cogl-spans.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_SPANS_PRIVATE_H -#define __COGL_SPANS_PRIVATE_H - -#include "cogl-handle.h" - -typedef struct _CoglSpan -{ - int start; - int size; - int waste; -} CoglSpan; - -typedef struct _CoglSpanIter -{ - int index; - GArray *array; - CoglSpan *span; - float pos; - float next_pos; - float origin; - float cover_start; - float cover_end; - float intersect_start; - float intersect_end; - float intersect_start_local; - float intersect_end_local; - gboolean intersects; - gboolean flipped; -} CoglSpanIter; - -void -_cogl_span_iter_update (CoglSpanIter *iter); - -void -_cogl_span_iter_begin (CoglSpanIter *iter, - GArray *spans, - float normalize_factor, - float cover_start, - float cover_end); - -void -_cogl_span_iter_next (CoglSpanIter *iter); - -gboolean -_cogl_span_iter_end (CoglSpanIter *iter); - -#endif /* __COGL_SPANS_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-sub-texture-private.h b/clutter/cogl/cogl/cogl-sub-texture-private.h deleted file mode 100644 index 0cc3c91..0000000 --- a/clutter/cogl/cogl/cogl-sub-texture-private.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_SUB_TEXTURE_H -#define __COGL_SUB_TEXTURE_H - -#include "cogl-handle.h" -#include "cogl-texture-private.h" - -#define COGL_SUB_TEXTURE(tex) ((CoglSubTexture *) tex) - -typedef struct _CoglSubTexture CoglSubTexture; - -struct _CoglSubTexture -{ - CoglTexture _parent; - - /* This is the texture that was passed in to - _cogl_sub_texture_new. If this is also a sub texture then we will - use the full texture from that to render instead of making a - chain. However we want to preserve the next texture in case the - user is expecting us to keep a reference and also so that we can - later add a cogl_sub_texture_get_full_texture() function. */ - CoglHandle next_texture; - /* This is the texture that will actually be used to draw. It will - point to the end of the chain if a sub texture of a sub texture - is created */ - CoglHandle full_texture; - - /* The region represented by this sub-texture. This is the region of - full_texture which won't necessarily be the same as the region - passed to _cogl_sub_texture_new if next_texture is actually - already a sub texture */ - int sub_x; - int sub_y; - int sub_width; - int sub_height; -}; - -GQuark -_cogl_handle_sub_texture_get_type (void); - -CoglHandle -_cogl_sub_texture_new (CoglHandle next_texture, - int sub_x, - int sub_y, - int sub_width, - int sub_height); - -#endif /* __COGL_SUB_TEXTURE_H */ diff --git a/clutter/cogl/cogl/cogl-sub-texture.c b/clutter/cogl/cogl/cogl-sub-texture.c deleted file mode 100644 index d00dcd5..0000000 --- a/clutter/cogl/cogl/cogl-sub-texture.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-sub-texture-private.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-texture-driver.h" - -#include -#include - -static void _cogl_sub_texture_free (CoglSubTexture *sub_tex); - -COGL_TEXTURE_INTERNAL_DEFINE (SubTexture, sub_texture); - -static const CoglTextureVtable cogl_sub_texture_vtable; - -static void -_cogl_sub_texture_map_range (float *t1, float *t2, - int sub_offset, - int sub_size, - int full_size) -{ - float t1_frac, t1_int, t2_frac, t2_int; - - t1_frac = modff (*t1, &t1_int); - t2_frac = modff (*t2, &t2_int); - - if (t1_frac < 0.0f) - { - t1_frac += 1.0f; - t1_int -= 1.0f; - } - if (t2_frac < 0.0f) - { - t2_frac += 1.0f; - t2_int -= 1.0f; - } - - /* If one of the coordinates is zero we need to make sure it is - still greater than the other coordinate if it was originally so - we'll flip it to the other side */ - if (*t1 < *t2) - { - if (t2_frac == 0.0f) - { - t2_frac = 1.0f; - t2_int -= 1.0f; - } - } - else - { - if (t1_frac == 0.0f) - { - t1_frac = 1.0f; - t1_int -= 1.0f; - } - } - - /* Convert the fractional part leaving the integer part intact */ - t1_frac = (sub_offset + t1_frac * sub_size) / full_size; - *t1 = t1_frac + t1_int; - - t2_frac = (sub_offset + t2_frac * sub_size) / full_size; - *t2 = t2_frac + t2_int; -} - -static void -_cogl_sub_texture_map_quad (CoglSubTexture *sub_tex, - float *coords) -{ - unsigned int full_width = cogl_texture_get_width (sub_tex->full_texture); - unsigned int full_height = cogl_texture_get_height (sub_tex->full_texture); - - _cogl_sub_texture_map_range (coords + 0, coords + 2, - sub_tex->sub_x, sub_tex->sub_width, - full_width); - _cogl_sub_texture_map_range (coords + 1, coords + 3, - sub_tex->sub_y, sub_tex->sub_height, - full_height); -} - -/* Maps from the texture coordinates of the full texture to the - texture coordinates of the sub texture */ -static float -_cogl_sub_texture_unmap_coord (float t, - int sub_offset, - int sub_size, - int full_size) -{ - float frac_part, int_part; - - /* Convert the fractional part leaving the integer part in tact */ - frac_part = modff (t, &int_part); - - if (cogl_util_float_signbit (frac_part)) - frac_part = ((1.0f + frac_part) * full_size - - sub_offset - sub_size) / sub_size; - else - frac_part = (frac_part * full_size - sub_offset) / sub_size; - - return frac_part + int_part; -} - -static void -_cogl_sub_texture_unmap_coords (CoglSubTexture *sub_tex, - float *s, - float *t) -{ - unsigned int full_width = cogl_texture_get_width (sub_tex->full_texture); - unsigned int full_height = cogl_texture_get_height (sub_tex->full_texture); - - *s = _cogl_sub_texture_unmap_coord (*s, sub_tex->sub_x, sub_tex->sub_width, - full_width); - *t = _cogl_sub_texture_unmap_coord (*t, sub_tex->sub_y, sub_tex->sub_height, - full_height); -} - -typedef struct _CoglSubTextureForeachData -{ - CoglSubTexture *sub_tex; - CoglTextureSliceCallback callback; - void *user_data; -} CoglSubTextureForeachData; - -static void -_cogl_sub_texture_foreach_cb (CoglHandle handle, - const float *slice_coords, - const float *full_virtual_coords, - void *user_data) -{ - CoglSubTextureForeachData *data = user_data; - float virtual_coords[4]; - - memcpy (virtual_coords, full_virtual_coords, sizeof (virtual_coords)); - /* Convert the virtual coords from the full-texture space to the sub - texture space */ - _cogl_sub_texture_unmap_coords (data->sub_tex, - &virtual_coords[0], - &virtual_coords[1]); - _cogl_sub_texture_unmap_coords (data->sub_tex, - &virtual_coords[2], - &virtual_coords[3]); - - data->callback (handle, - slice_coords, virtual_coords, - data->user_data); -} - -static void -_cogl_sub_texture_manual_repeat_cb (const float *coords, - void *user_data) -{ - CoglSubTextureForeachData *data = user_data; - float mapped_coords[4]; - - memcpy (mapped_coords, coords, sizeof (mapped_coords)); - - _cogl_sub_texture_map_quad (data->sub_tex, mapped_coords); - - _cogl_texture_foreach_sub_texture_in_region (data->sub_tex->full_texture, - mapped_coords[0], - mapped_coords[1], - mapped_coords[2], - mapped_coords[3], - _cogl_sub_texture_foreach_cb, - user_data); -} - -static void -_cogl_sub_texture_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - CoglSubTextureForeachData data; - - data.sub_tex = sub_tex; - data.callback = callback; - data.user_data = user_data; - - _cogl_texture_iterate_manual_repeats (_cogl_sub_texture_manual_repeat_cb, - virtual_tx_1, virtual_ty_1, - virtual_tx_2, virtual_ty_2, - &data); -} - -static void -_cogl_sub_texture_set_wrap_mode_parameters (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_set_wrap_mode_parameters (sub_tex->full_texture, - wrap_mode_s, - wrap_mode_t, - wrap_mode_p); -} - -static void -_cogl_sub_texture_free (CoglSubTexture *sub_tex) -{ - cogl_handle_unref (sub_tex->next_texture); - cogl_handle_unref (sub_tex->full_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (sub_tex)); -} - -CoglHandle -_cogl_sub_texture_new (CoglHandle next_texture, - int sub_x, int sub_y, - int sub_width, int sub_height) -{ - CoglHandle full_texture; - CoglSubTexture *sub_tex; - CoglTexture *tex; - unsigned int next_width, next_height; - - next_width = cogl_texture_get_width (next_texture); - next_height = cogl_texture_get_height (next_texture); - - /* The region must specify a non-zero subset of the full texture */ - g_return_val_if_fail (sub_x >= 0 && sub_y >= 0, COGL_INVALID_HANDLE); - g_return_val_if_fail (sub_width > 0 && sub_height > 0, COGL_INVALID_HANDLE); - g_return_val_if_fail (sub_x + sub_width <= next_width, COGL_INVALID_HANDLE); - g_return_val_if_fail (sub_y + sub_height <= next_height, COGL_INVALID_HANDLE); - - sub_tex = g_new (CoglSubTexture, 1); - - tex = COGL_TEXTURE (sub_tex); - - _cogl_texture_init (tex, &cogl_sub_texture_vtable); - - /* If the next texture is also a sub texture we can avoid one level - of indirection by referencing the full texture of that texture - instead. */ - if (_cogl_is_sub_texture (next_texture)) - { - CoglSubTexture *other_sub_tex = - _cogl_sub_texture_pointer_from_handle (next_texture); - full_texture = other_sub_tex->full_texture; - sub_x += other_sub_tex->sub_x; - sub_y += other_sub_tex->sub_y; - } - else - full_texture = next_texture; - - sub_tex->next_texture = cogl_handle_ref (next_texture); - sub_tex->full_texture = cogl_handle_ref (full_texture); - - sub_tex->sub_x = sub_x; - sub_tex->sub_y = sub_y; - sub_tex->sub_width = sub_width; - sub_tex->sub_height = sub_height; - - return _cogl_sub_texture_handle_new (sub_tex); -} - -static int -_cogl_sub_texture_get_max_waste (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_get_max_waste (sub_tex->full_texture); -} - -static gboolean -_cogl_sub_texture_is_sliced (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_is_sliced (sub_tex->full_texture); -} - -static gboolean -_cogl_sub_texture_can_hardware_repeat (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - /* We can hardware repeat if the subtexture actually represents all of the - of the full texture */ - return (sub_tex->sub_width == - cogl_texture_get_width (sub_tex->full_texture) && - sub_tex->sub_height == - cogl_texture_get_height (sub_tex->full_texture) && - _cogl_texture_can_hardware_repeat (sub_tex->full_texture)); -} - -static void -_cogl_sub_texture_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - /* This won't work if the sub texture is not the size of the full - texture and the coordinates are outside the range [0,1] */ - *s = ((*s * sub_tex->sub_width + sub_tex->sub_x) / - cogl_texture_get_width (sub_tex->full_texture)); - *t = ((*t * sub_tex->sub_height + sub_tex->sub_y) / - cogl_texture_get_height (sub_tex->full_texture)); - - _cogl_texture_transform_coords_to_gl (sub_tex->full_texture, s, t); -} - -static CoglTransformResult -_cogl_sub_texture_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - int i; - - /* We can't support repeating with this method. In this case - cogl-primitives will resort to manual repeating */ - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - _cogl_sub_texture_map_quad (sub_tex, coords); - - return _cogl_texture_transform_quad_coords_to_gl (sub_tex->full_texture, - coords); -} - -static gboolean -_cogl_sub_texture_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_get_gl_texture (sub_tex->full_texture, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_sub_texture_set_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_set_filters (sub_tex->full_texture, min_filter, mag_filter); -} - -static void -_cogl_sub_texture_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_pre_paint (sub_tex->full_texture, flags); -} - -static void -_cogl_sub_texture_ensure_non_quad_rendering (CoglTexture *tex) -{ -} - -static gboolean -_cogl_sub_texture_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return _cogl_texture_set_region_from_bitmap (sub_tex->full_texture, - src_x, src_y, - dst_x + sub_tex->sub_x, - dst_y + sub_tex->sub_y, - dst_width, dst_height, - bmp); -} - -static CoglPixelFormat -_cogl_sub_texture_get_format (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_get_format (sub_tex->full_texture); -} - -static GLenum -_cogl_sub_texture_get_gl_format (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return _cogl_texture_get_gl_format (sub_tex->full_texture); -} - -static int -_cogl_sub_texture_get_width (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return sub_tex->sub_width; -} - -static int -_cogl_sub_texture_get_height (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return sub_tex->sub_height; -} - -static const CoglTextureVtable -cogl_sub_texture_vtable = - { - _cogl_sub_texture_set_region, - NULL, /* get_data */ - _cogl_sub_texture_foreach_sub_texture_in_region, - _cogl_sub_texture_get_max_waste, - _cogl_sub_texture_is_sliced, - _cogl_sub_texture_can_hardware_repeat, - _cogl_sub_texture_transform_coords_to_gl, - _cogl_sub_texture_transform_quad_coords_to_gl, - _cogl_sub_texture_get_gl_texture, - _cogl_sub_texture_set_filters, - _cogl_sub_texture_pre_paint, - _cogl_sub_texture_ensure_non_quad_rendering, - _cogl_sub_texture_set_wrap_mode_parameters, - _cogl_sub_texture_get_format, - _cogl_sub_texture_get_gl_format, - _cogl_sub_texture_get_width, - _cogl_sub_texture_get_height, - NULL /* is_foreign */ - }; diff --git a/clutter/cogl/cogl/cogl-swap-chain-private.h b/clutter/cogl/cogl/cogl-swap-chain-private.h deleted file mode 100644 index 2f63109..0000000 --- a/clutter/cogl/cogl/cogl-swap-chain-private.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - */ - -#ifndef __COGL_SWAP_CHAIN_PRIVATE_H -#define __COGL_SWAP_CHAIN_PRIVATE_H - -#include "cogl-object-private.h" - -struct _CoglSwapChain -{ - CoglObject _parent; - - gboolean has_alpha; - - int length; -}; - -#endif /* __COGL_SWAP_CHAIN_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-swap-chain.c b/clutter/cogl/cogl/cogl-swap-chain.c deleted file mode 100644 index 9326146..0000000 --- a/clutter/cogl/cogl/cogl-swap-chain.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-object.h" - -#include "cogl-swap-chain-private.h" - -static void _cogl_swap_chain_free (CoglSwapChain *swap_chain); - -COGL_OBJECT_DEFINE (SwapChain, swap_chain); - -GQuark -cogl_swap_chain_error_quark (void) -{ - return g_quark_from_static_string ("cogl-swap-chain-error-quark"); -} - -static void -_cogl_swap_chain_free (CoglSwapChain *swap_chain) -{ - g_slice_free (CoglSwapChain, swap_chain); -} - -CoglSwapChain * -cogl_swap_chain_new (void) -{ - CoglSwapChain *swap_chain = g_slice_new0 (CoglSwapChain); - - swap_chain->length = -1; /* no preference */ - - return _cogl_swap_chain_object_new (swap_chain); -} - -void -cogl_swap_chain_set_has_alpha (CoglSwapChain *swap_chain, - gboolean has_alpha) -{ - swap_chain->has_alpha = has_alpha; -} - -void -cogl_swap_chain_set_length (CoglSwapChain *swap_chain, - int length) -{ - swap_chain->length = length; -} diff --git a/clutter/cogl/cogl/cogl-swap-chain.h b/clutter/cogl/cogl/cogl-swap-chain.h deleted file mode 100644 index 2f3ae58..0000000 --- a/clutter/cogl/cogl/cogl-swap-chain.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_SWAP_CHAIN_H__ -#define __COGL_SWAP_CHAIN_H__ - -G_BEGIN_DECLS - -typedef struct _CoglSwapChain CoglSwapChain; - -#define cogl_swap_chain_new cogl_swap_chain_new_EXP -CoglSwapChain * -cogl_swap_chain_new (void); - -#define cogl_swap_chain_set_has_alpha cogl_swap_chain_set_has_alpha_EXP -void -cogl_swap_chain_set_has_alpha (CoglSwapChain *swap_chain, - gboolean has_alpha); - -#define cogl_swap_chain_set_length cogl_swap_chain_set_length_EXP -void -cogl_swap_chain_set_length (CoglSwapChain *swap_chain, - int length); - -G_END_DECLS - -#endif /* __COGL_SWAP_CHAIN_H__ */ diff --git a/clutter/cogl/cogl/cogl-texture-2d-private.h b/clutter/cogl/cogl/cogl-texture-2d-private.h deleted file mode 100644 index 9c30341..0000000 --- a/clutter/cogl/cogl/cogl-texture-2d-private.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_TEXTURE_2D_H -#define __COGL_TEXTURE_2D_H - -#include "cogl-handle.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" - -#define COGL_TEXTURE_2D(tex) ((CoglTexture2D *) tex) - -typedef struct _CoglTexture2D CoglTexture2D; - -struct _CoglTexture2D -{ - CoglTexture _parent; - - /* The internal format of the GL texture represented as a - CoglPixelFormat */ - CoglPixelFormat format; - /* The internal format of the GL texture represented as a GL enum */ - GLenum gl_format; - /* The texture object number */ - GLuint gl_texture; - int width; - int height; - GLenum min_filter; - GLenum mag_filter; - GLint wrap_mode_s; - GLint wrap_mode_t; - gboolean auto_mipmap; - gboolean mipmaps_dirty; - gboolean is_foreign; - - CoglTexturePixel first_pixel; -}; - -GQuark -_cogl_handle_texture_2d_get_type (void); - -gboolean -_cogl_is_texture_2d (CoglHandle object); - -CoglHandle -_cogl_texture_2d_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -CoglHandle -_cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -CoglHandle -_cogl_texture_2d_new_from_foreign (GLuint gl_handle, - GLuint width, - GLuint height, - CoglPixelFormat format); - -/* - * _cogl_texture_2d_externally_modified: - * @handle: A handle to a 2D texture - * - * This should be called whenever the texture is modified other than - * by using cogl_texture_set_region. It will cause the mipmaps to be - * invalidated - */ -void -_cogl_texture_2d_externally_modified (CoglHandle handle); - -/* - * _cogl_texture_2d_copy_from_framebuffer: - * @handle: A handle to a 2D texture - * @dst_x: X-position to store the image within the texture - * @dst_y: Y-position to store the image within the texture - * @src_x: X-position to within the framebuffer to read from - * @src_y: Y-position to within the framebuffer to read from - * @width: width of the rectangle to copy - * @height: height of the rectangle to copy - * - * This copies a portion of the current read framebuffer into the - * texture. - */ -void -_cogl_texture_2d_copy_from_framebuffer (CoglHandle handle, - int dst_x, - int dst_y, - int src_x, - int src_y, - int width, - int height); - -#endif /* __COGL_TEXTURE_2D_H */ diff --git a/clutter/cogl/cogl/cogl-texture-2d-sliced-private.h b/clutter/cogl/cogl/cogl-texture-2d-sliced-private.h deleted file mode 100644 index 67a8ce9..0000000 --- a/clutter/cogl/cogl/cogl-texture-2d-sliced-private.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_TEXTURE_2D_SLICED_H -#define __COGL_TEXTURE_2D_SLICED_H - -#include "cogl-bitmap-private.h" -#include "cogl-handle.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" - -#define COGL_TEXTURE_2D_SLICED(tex) ((CoglTexture2DSliced *)tex) - -typedef struct _CoglTexture2DSliced CoglTexture2DSliced; - -struct _CoglTexture2DSliced -{ - CoglTexture _parent; - GArray *slice_x_spans; - GArray *slice_y_spans; - GArray *slice_textures; - int max_waste; - - int width; - int height; -}; - -GQuark -_cogl_handle_texture_2d_sliced_get_type (void); - -CoglHandle -_cogl_texture_2d_sliced_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -CoglHandle -_cogl_texture_2d_sliced_new_from_foreign (GLuint gl_handle, - GLenum gl_target, - GLuint width, - GLuint height, - GLuint x_pot_waste, - GLuint y_pot_waste, - CoglPixelFormat format); - -CoglHandle -_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -#endif /* __COGL_TEXTURE_2D_SLICED_H */ diff --git a/clutter/cogl/cogl/cogl-texture-2d-sliced.c b/clutter/cogl/cogl/cogl-texture-2d-sliced.c deleted file mode 100644 index 29152b7..0000000 --- a/clutter/cogl/cogl/cogl-texture-2d-sliced.c +++ /dev/null @@ -1,1397 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-2d-sliced-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-spans.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" - -#include -#include -#include - -static void _cogl_texture_2d_sliced_free (CoglTexture2DSliced *tex_2ds); - -COGL_TEXTURE_INTERNAL_DEFINE (Texture2DSliced, texture_2d_sliced); - -static const CoglTextureVtable cogl_texture_2d_sliced_vtable; - -typedef struct -{ - CoglTexture2DSliced *tex; - CoglSpan *x_span; - CoglSpan *y_span; - - CoglTextureSliceCallback callback; - void *user_data; -} ForeachData; - -static void -_cogl_texture_2d_sliced_foreach_cb (CoglHandle handle, - const float *slice_coords, - const float *virtual_coords_in, - void *user_data) -{ - float virtual_coords_out[4]; - ForeachData *data = user_data; - - /* Convert the virtual coordinates of the texture slice back to - coordinates in the space of the outer texture */ - virtual_coords_out[0] = (virtual_coords_in[0] * data->x_span->size + - data->x_span->start) / data->tex->width; - virtual_coords_out[1] = (virtual_coords_in[1] * data->y_span->size + - data->y_span->start) / data->tex->height; - virtual_coords_out[2] = (virtual_coords_in[2] * data->x_span->size + - data->x_span->start) / data->tex->width; - virtual_coords_out[3] = (virtual_coords_in[3] * data->y_span->size + - data->y_span->start) / data->tex->height; - - data->callback (handle, - slice_coords, - virtual_coords_out, - data->user_data); -} - -/* To differentiate between texture coordinates of a specific, real, slice - * texture and the texture coordinates of the composite, sliced texture, the - * coordinates of the sliced texture are called "virtual" coordinates and the - * coordinates of slices are called "slice" coordinates. */ -/* This function lets you iterate all the slices that lie within the given - * virtual coordinates of the parent sliced texture. */ -/* Note: no guarantee is given about the order in which the slices will be - * visited */ -static void -_cogl_texture_2d_sliced_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - float width = tex_2ds->width; - float height = tex_2ds->height; - CoglSpanIter iter_x; - CoglSpanIter iter_y; - ForeachData data; - - data.tex = COGL_TEXTURE_2D_SLICED (tex); - data.callback = callback; - data.user_data = user_data; - - /* Slice spans are stored in denormalized coordinates, and this is what - * the _cogl_span_iter_* funcs expect to be given, so we scale the given - * virtual coordinates by the texture size to denormalize. - */ - /* XXX: I wonder if it's worth changing how we store spans so we can avoid - * the need to denormalize here */ - virtual_tx_1 *= width; - virtual_ty_1 *= height; - virtual_tx_2 *= width; - virtual_ty_2 *= height; - - /* Iterate the y axis of the virtual rectangle */ - for (_cogl_span_iter_begin (&iter_y, - tex_2ds->slice_y_spans, - height, - virtual_ty_1, - virtual_ty_2); - !_cogl_span_iter_end (&iter_y); - _cogl_span_iter_next (&iter_y)) - { - float y_intersect_start = iter_y.intersect_start; - float y_intersect_end = iter_y.intersect_end; - float slice_ty1; - float slice_ty2; - - /* Discard slices out of rectangle early */ - if (!iter_y.intersects) - continue; - - if (iter_y.flipped) - { - y_intersect_start = iter_y.intersect_end; - y_intersect_end = iter_y.intersect_start; - } - - /* Localize slice texture coordinates */ - slice_ty1 = y_intersect_start - iter_y.pos; - slice_ty2 = y_intersect_end - iter_y.pos; - - /* Normalize slice texture coordinates */ - slice_ty1 /= iter_y.span->size; - slice_ty2 /= iter_y.span->size; - - data.y_span = iter_y.span; - - /* Iterate the x axis of the virtual rectangle */ - for (_cogl_span_iter_begin (&iter_x, - tex_2ds->slice_x_spans, - width, - virtual_tx_1, - virtual_tx_2); - !_cogl_span_iter_end (&iter_x); - _cogl_span_iter_next (&iter_x)) - { - float x_intersect_start = iter_x.intersect_start; - float x_intersect_end = iter_x.intersect_end; - float slice_tx1; - float slice_tx2; - CoglHandle slice_tex; - - /* Discard slices out of rectangle early */ - if (!iter_x.intersects) - continue; - - if (iter_x.flipped) - { - x_intersect_start = iter_x.intersect_end; - x_intersect_end = iter_x.intersect_start; - } - - /* Localize slice texture coordinates */ - slice_tx1 = x_intersect_start - iter_x.pos; - slice_tx2 = x_intersect_end - iter_x.pos; - - /* Normalize slice texture coordinates */ - slice_tx1 /= iter_x.span->size; - slice_tx2 /= iter_x.span->size; - - data.x_span = iter_x.span; - - /* Pluck out the cogl texture for this slice */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, - iter_y.index * iter_x.array->len + - iter_x.index); - - _cogl_texture_foreach_sub_texture_in_region - (slice_tex, - slice_tx1, slice_ty1, slice_tx2, slice_ty2, - _cogl_texture_2d_sliced_foreach_cb, - &data); - } - } -} - -static guint8 * -_cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds, - CoglPixelFormat format) -{ - CoglSpan *last_x_span; - CoglSpan *last_y_span; - guint8 *waste_buf = NULL; - - /* If the texture has any waste then allocate a buffer big enough to - fill the gaps */ - last_x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, - tex_2ds->slice_x_spans->len - 1); - last_y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, - tex_2ds->slice_y_spans->len - 1); - if (last_x_span->waste > 0 || last_y_span->waste > 0) - { - int bpp = _cogl_get_format_bpp (format); - CoglSpan *first_x_span - = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - CoglSpan *first_y_span - = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - unsigned int right_size = first_y_span->size * last_x_span->waste; - unsigned int bottom_size = first_x_span->size * last_y_span->waste; - - waste_buf = g_malloc (MAX (right_size, bottom_size) * bpp); - } - - return waste_buf; -} - -static void -_cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, - CoglBitmap *source_bmp, - CoglHandle slice_tex, - guint8 *waste_buf, - CoglSpan *x_span, - CoglSpan *y_span, - CoglSpanIter *x_iter, - CoglSpanIter *y_iter, - int src_x, - int src_y, - int dst_x, - int dst_y) -{ - gboolean need_x, need_y; - - /* If the x_span is sliced and the upload touches the - rightmost pixels then fill the waste with copies of the - pixels */ - need_x = x_span->waste > 0 && - x_iter->intersect_end - x_iter->pos >= x_span->size - x_span->waste; - - /* same for the bottom-most pixels */ - need_y = y_span->waste > 0 && - y_iter->intersect_end - y_iter->pos >= y_span->size - y_span->waste; - - if (need_x || need_y) - { - int bmp_rowstride = _cogl_bitmap_get_rowstride (source_bmp); - CoglPixelFormat source_format = _cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_get_format_bpp (source_format); - guint8 *bmp_data; - const guint8 *src; - guint8 *dst; - unsigned int wy, wx; - CoglBitmap *waste_bmp; - - bmp_data = _cogl_bitmap_map (source_bmp, COGL_BUFFER_ACCESS_READ, 0); - - if (bmp_data == NULL) - return; - - if (need_x) - { - src = (bmp_data + ((src_y + (int) y_iter->intersect_start - dst_y) * - bmp_rowstride) + - (src_x + x_span->start + x_span->size - - x_span->waste - dst_x - 1) * bpp); - - dst = waste_buf; - - for (wy = 0; - wy < y_iter->intersect_end - y_iter->intersect_start; - wy++) - { - for (wx = 0; wx < x_span->waste; wx++) - { - memcpy (dst, src, bpp); - dst += bpp; - } - src += bmp_rowstride; - } - - waste_bmp = - _cogl_bitmap_new_from_data (waste_buf, - source_format, - x_span->waste, - y_iter->intersect_end - - y_iter->intersect_start, - x_span->waste * bpp, - NULL, - NULL); - - _cogl_texture_set_region_from_bitmap (slice_tex, - 0, /* src_x */ - 0, /* src_y */ - /* dst_x */ - x_span->size - x_span->waste, - y_iter->intersect_start - - y_span->start, /* dst_y */ - x_span->waste, /* dst_width */ - /* dst_height */ - y_iter->intersect_end - - y_iter->intersect_start, - waste_bmp); - - cogl_object_unref (waste_bmp); - } - - if (need_y) - { - unsigned int copy_width, intersect_width; - - src = (bmp_data + ((src_x + (int) x_iter->intersect_start - dst_x) * - bpp) + - (src_y + y_span->start + y_span->size - y_span->waste - - dst_y - 1) * bmp_rowstride); - - dst = waste_buf; - - if (x_iter->intersect_end - x_iter->pos - >= x_span->size - x_span->waste) - copy_width = x_span->size + x_iter->pos - x_iter->intersect_start; - else - copy_width = x_iter->intersect_end - x_iter->intersect_start; - - intersect_width = x_iter->intersect_end - x_iter->intersect_start; - - for (wy = 0; wy < y_span->waste; wy++) - { - memcpy (dst, src, intersect_width * bpp); - dst += intersect_width * bpp; - - for (wx = intersect_width; wx < copy_width; wx++) - { - memcpy (dst, dst - bpp, bpp); - dst += bpp; - } - } - - waste_bmp = - _cogl_bitmap_new_from_data (waste_buf, - source_format, - copy_width, - y_span->waste, - copy_width * bpp, - NULL, - NULL); - - _cogl_texture_set_region_from_bitmap (slice_tex, - 0, /* src_x */ - 0, /* src_y */ - /* dst_x */ - x_iter->intersect_start - - x_iter->pos, - /* dst_y */ - y_span->size - y_span->waste, - copy_width, /* dst_width */ - y_span->waste, /* dst_height */ - waste_bmp); - - cogl_object_unref (waste_bmp); - } - - _cogl_bitmap_unmap (source_bmp); - } -} - -static gboolean -_cogl_texture_2d_sliced_upload_to_gl (CoglTexture2DSliced *tex_2ds, - CoglBitmap *bmp) -{ - CoglSpan *x_span; - CoglSpan *y_span; - CoglHandle slice_tex; - int x, y; - guint8 *waste_buf; - CoglPixelFormat bmp_format; - - bmp_format = _cogl_bitmap_get_format (bmp); - - waste_buf = _cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds, - bmp_format); - - /* Iterate vertical slices */ - for (y = 0; y < tex_2ds->slice_y_spans->len; ++y) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y); - - /* Iterate horizontal slices */ - for (x = 0; x < tex_2ds->slice_x_spans->len; ++x) - { - int slice_num = y * tex_2ds->slice_x_spans->len + x; - CoglSpanIter x_iter, y_iter; - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x); - - /* Pick the gl texture object handle */ - slice_tex = g_array_index (tex_2ds->slice_textures, - CoglHandle, slice_num); - - _cogl_texture_set_region_from_bitmap (slice_tex, - x_span->start, /* src x */ - y_span->start, /* src y */ - 0, /* dst x */ - 0, /* dst y */ - x_span->size - - x_span->waste, /* width */ - y_span->size - - y_span->waste, /* height */ - bmp); - - /* Set up a fake iterator that covers the whole slice */ - x_iter.intersect_start = x_span->start; - x_iter.intersect_end = (x_span->start + - x_span->size - - x_span->waste); - x_iter.pos = x_span->start; - - y_iter.intersect_start = y_span->start; - y_iter.intersect_end = (y_span->start + - y_span->size - - y_span->waste); - y_iter.pos = y_span->start; - - _cogl_texture_2d_sliced_set_waste (tex_2ds, - bmp, - slice_tex, - waste_buf, - x_span, y_span, - &x_iter, &y_iter, - 0, /* src_x */ - 0, /* src_y */ - 0, /* dst_x */ - 0); /* dst_y */ - } - } - - if (waste_buf) - g_free (waste_buf); - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_upload_subregion_to_gl (CoglTexture2DSliced *tex_2ds, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type) -{ - CoglSpan *x_span; - CoglSpan *y_span; - CoglSpanIter x_iter; - CoglSpanIter y_iter; - CoglHandle slice_tex; - int source_x = 0, source_y = 0; - int inter_w = 0, inter_h = 0; - int local_x = 0, local_y = 0; - guint8 *waste_buf; - CoglPixelFormat source_format; - - source_format = _cogl_bitmap_get_format (source_bmp); - - waste_buf = - _cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds, source_format); - - /* Iterate vertical spans */ - for (source_y = src_y, - _cogl_span_iter_begin (&y_iter, - tex_2ds->slice_y_spans, - tex_2ds->height, - dst_y, - dst_y + height); - - !_cogl_span_iter_end (&y_iter); - - _cogl_span_iter_next (&y_iter), - source_y += inter_h ) - { - /* Discard slices out of the subregion early */ - if (!y_iter.intersects) - { - inter_h = 0; - continue; - } - - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, - y_iter.index); - - /* Iterate horizontal spans */ - for (source_x = src_x, - _cogl_span_iter_begin (&x_iter, - tex_2ds->slice_x_spans, - tex_2ds->width, - dst_x, - dst_x + width); - - !_cogl_span_iter_end (&x_iter); - - _cogl_span_iter_next (&x_iter), - source_x += inter_w ) - { - int slice_num; - - /* Discard slices out of the subregion early */ - if (!x_iter.intersects) - { - inter_w = 0; - continue; - } - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, - x_iter.index); - - /* Pick intersection width and height */ - inter_w = (x_iter.intersect_end - x_iter.intersect_start); - inter_h = (y_iter.intersect_end - y_iter.intersect_start); - - /* Localize intersection top-left corner to slice*/ - local_x = (x_iter.intersect_start - x_iter.pos); - local_y = (y_iter.intersect_start - y_iter.pos); - - slice_num = y_iter.index * tex_2ds->slice_x_spans->len + x_iter.index; - - /* Pick slice texture */ - slice_tex = g_array_index (tex_2ds->slice_textures, - CoglHandle, slice_num); - - _cogl_texture_set_region_from_bitmap (slice_tex, - source_x, - source_y, - local_x, /* dst x */ - local_y, /* dst y */ - inter_w, /* width */ - inter_h, /* height */ - source_bmp); - - _cogl_texture_2d_sliced_set_waste (tex_2ds, - source_bmp, - slice_tex, - waste_buf, - x_span, y_span, - &x_iter, &y_iter, - src_x, src_y, - dst_x, dst_y); - } - } - - g_free (waste_buf); - - return TRUE; -} - -static int -_cogl_rect_slices_for_size (int size_to_fill, - int max_span_size, - int max_waste, - GArray *out_spans) -{ - int n_spans = 0; - CoglSpan span; - - /* Init first slice span */ - span.start = 0; - span.size = max_span_size; - span.waste = 0; - - /* Repeat until whole area covered */ - while (size_to_fill >= span.size) - { - /* Add another slice span of same size */ - if (out_spans) - g_array_append_val (out_spans, span); - span.start += span.size; - size_to_fill -= span.size; - n_spans++; - } - - /* Add one last smaller slice span */ - if (size_to_fill > 0) - { - span.size = size_to_fill; - if (out_spans) - g_array_append_val (out_spans, span); - n_spans++; - } - - return n_spans; -} - -static int -_cogl_pot_slices_for_size (int size_to_fill, - int max_span_size, - int max_waste, - GArray *out_spans) -{ - int n_spans = 0; - CoglSpan span; - - /* Init first slice span */ - span.start = 0; - span.size = max_span_size; - span.waste = 0; - - /* Fix invalid max_waste */ - if (max_waste < 0) - max_waste = 0; - - while (TRUE) - { - /* Is the whole area covered? */ - if (size_to_fill > span.size) - { - /* Not yet - add a span of this size */ - if (out_spans) - g_array_append_val (out_spans, span); - - span.start += span.size; - size_to_fill -= span.size; - n_spans++; - } - else if (span.size - size_to_fill <= max_waste) - { - /* Yes and waste is small enough */ - /* Pick the next power of two up from size_to_fill. This can - sometimes be less than the span.size that would be chosen - otherwise */ - span.size = _cogl_util_next_p2 (size_to_fill); - span.waste = span.size - size_to_fill; - if (out_spans) - g_array_append_val (out_spans, span); - - return ++n_spans; - } - else - { - /* Yes but waste is too large */ - while (span.size - size_to_fill > max_waste) - { - span.size /= 2; - g_assert (span.size > 0); - } - } - } - - /* Can't get here */ - return 0; -} - -static void -_cogl_texture_2d_sliced_set_wrap_mode_parameters (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - /* Pass the set wrap mode on to all of the child textures */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglHandle slice_tex = g_array_index (tex_2ds->slice_textures, - CoglHandle, - i); - - _cogl_texture_set_wrap_mode_parameters (slice_tex, - wrap_mode_s, - wrap_mode_t, - wrap_mode_p); - } -} - -static gboolean -_cogl_texture_2d_sliced_slices_create (CoglTexture2DSliced *tex_2ds, - int width, int height, - CoglPixelFormat format, - CoglTextureFlags flags) -{ - int max_width; - int max_height; - CoglHandle *slice_textures; - int n_x_slices; - int n_y_slices; - int n_slices; - int x, y; - CoglSpan *x_span; - CoglSpan *y_span; - GLenum gl_intformat; - GLenum gl_type; - - int (*slices_for_size) (int, int, int, GArray*); - - /* Initialize size of largest slice according to supported features */ - if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)) - { - max_width = width; - max_height = height; - slices_for_size = _cogl_rect_slices_for_size; - } - else - { - max_width = _cogl_util_next_p2 (width); - max_height = _cogl_util_next_p2 (height); - slices_for_size = _cogl_pot_slices_for_size; - } - - _cogl_pixel_format_to_gl (format, &gl_intformat, NULL, &gl_type); - - /* Negative number means no slicing forced by the user */ - if (tex_2ds->max_waste <= -1) - { - CoglSpan span; - - /* Check if size supported else bail out */ - if (!_cogl_texture_driver_size_supported (GL_TEXTURE_2D, - gl_intformat, - gl_type, - max_width, - max_height)) - { - return FALSE; - } - - n_x_slices = 1; - n_y_slices = 1; - - /* Init span arrays */ - tex_2ds->slice_x_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - 1); - - tex_2ds->slice_y_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - 1); - - /* Add a single span for width and height */ - span.start = 0; - span.size = max_width; - span.waste = max_width - width; - g_array_append_val (tex_2ds->slice_x_spans, span); - - span.size = max_height; - span.waste = max_height - height; - g_array_append_val (tex_2ds->slice_y_spans, span); - } - else - { - /* Decrease the size of largest slice until supported by GL */ - while (!_cogl_texture_driver_size_supported (GL_TEXTURE_2D, - gl_intformat, - gl_type, - max_width, - max_height)) - { - /* Alternate between width and height */ - if (max_width > max_height) - max_width /= 2; - else - max_height /= 2; - - if (max_width == 0 || max_height == 0) - return FALSE; - } - - /* Determine the slices required to cover the bitmap area */ - n_x_slices = slices_for_size (width, - max_width, tex_2ds->max_waste, - NULL); - - n_y_slices = slices_for_size (height, - max_height, tex_2ds->max_waste, - NULL); - - /* Init span arrays with reserved size */ - tex_2ds->slice_x_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - n_x_slices); - - tex_2ds->slice_y_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - n_y_slices); - - /* Fill span arrays with info */ - slices_for_size (width, - max_width, tex_2ds->max_waste, - tex_2ds->slice_x_spans); - - slices_for_size (height, - max_height, tex_2ds->max_waste, - tex_2ds->slice_y_spans); - } - - /* Init and resize GL handle array */ - n_slices = n_x_slices * n_y_slices; - - tex_2ds->slice_textures = g_array_sized_new (FALSE, FALSE, - sizeof (CoglHandle), - n_slices); - - g_array_set_size (tex_2ds->slice_textures, n_slices); - - /* Generate a "working set" of GL texture objects - * (some implementations might supported faster - * re-binding between textures inside a set) */ - slice_textures = (CoglHandle *) tex_2ds->slice_textures->data; - - /* Init each GL texture object */ - for (y = 0; y < n_y_slices; ++y) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y); - - for (x = 0; x < n_x_slices; ++x) - { - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x); - - COGL_NOTE (SLICING, "CREATE SLICE (%d,%d)\tsize (%d,%d)", - x, y, - x_span->size - x_span->waste, - y_span->size - y_span->waste); - - slice_textures[y * n_x_slices + x] = - cogl_texture_new_with_size (x_span->size, y_span->size, - COGL_TEXTURE_NO_ATLAS | flags, - format); - } - } - - return TRUE; -} - -static void -_cogl_texture_2d_sliced_slices_free (CoglTexture2DSliced *tex_2ds) -{ - if (tex_2ds->slice_x_spans != NULL) - g_array_free (tex_2ds->slice_x_spans, TRUE); - - if (tex_2ds->slice_y_spans != NULL) - g_array_free (tex_2ds->slice_y_spans, TRUE); - - if (tex_2ds->slice_textures != NULL) - { - int i; - - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglHandle slice_tex = - g_array_index (tex_2ds->slice_textures, CoglHandle, i); - cogl_handle_unref (slice_tex); - } - - g_array_free (tex_2ds->slice_textures, TRUE); - } -} - -static void -_cogl_texture_2d_sliced_free (CoglTexture2DSliced *tex_2ds) -{ - _cogl_texture_2d_sliced_slices_free (tex_2ds); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_2ds)); -} - -static gboolean -_cogl_texture_2d_sliced_init_base (CoglTexture2DSliced *tex_2ds, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureFlags flags) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - - _cogl_texture_init (tex, &cogl_texture_2d_sliced_vtable); - - tex_2ds->slice_x_spans = NULL; - tex_2ds->slice_y_spans = NULL; - tex_2ds->slice_textures = NULL; - - /* Create slices for the given format and size */ - if (!_cogl_texture_2d_sliced_slices_create (tex_2ds, - width, - height, - internal_format, - flags)) - return FALSE; - - tex_2ds->width = width; - tex_2ds->height = height; - - return TRUE; -} - -CoglHandle -_cogl_texture_2d_sliced_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTexture2DSliced *tex_2ds; - - /* Since no data, we need some internal format */ - if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - - /* Init texture with empty bitmap */ - tex_2ds = g_new (CoglTexture2DSliced, 1); - - if ((flags & COGL_TEXTURE_NO_SLICING)) - tex_2ds->max_waste = -1; - else - tex_2ds->max_waste = COGL_TEXTURE_MAX_WASTE; - - if (!_cogl_texture_2d_sliced_init_base (tex_2ds, - width, height, - internal_format, - flags)) - { - _cogl_texture_2d_sliced_free (tex_2ds); - return COGL_INVALID_HANDLE; - } - - return _cogl_texture_2d_sliced_handle_new (tex_2ds); -} - -CoglHandle -_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTexture2DSliced *tex_2ds; - CoglBitmap *dst_bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - int width, height; - - g_return_val_if_fail (cogl_is_bitmap (bmp), COGL_INVALID_HANDLE); - - width = _cogl_bitmap_get_width (bmp); - height = _cogl_bitmap_get_height (bmp); - - /* Create new texture and fill with loaded data */ - tex_2ds = g_new0 (CoglTexture2DSliced, 1); - - if (flags & COGL_TEXTURE_NO_SLICING) - tex_2ds->max_waste = -1; - else - tex_2ds->max_waste = COGL_TEXTURE_MAX_WASTE; - - /* FIXME: If upload fails we should set some kind of - * error flag but still return texture handle if the - * user decides to destroy another texture and upload - * this one instead (reloading from file is not needed - * in that case). As a rule then, everytime a valid - * CoglHandle is returned, it should also be destroyed - * with cogl_handle_unref at some point! */ - - dst_bmp = _cogl_texture_prepare_for_upload (bmp, - internal_format, - &internal_format, - &gl_intformat, - &gl_format, - &gl_type); - if (dst_bmp == COGL_INVALID_HANDLE) - { - _cogl_texture_2d_sliced_free (tex_2ds); - return COGL_INVALID_HANDLE; - } - - if (!_cogl_texture_2d_sliced_init_base (tex_2ds, - width, height, - internal_format, - flags)) - goto error; - - if (!_cogl_texture_2d_sliced_upload_to_gl (tex_2ds, - dst_bmp)) - goto error; - - cogl_object_unref (dst_bmp); - - return _cogl_texture_2d_sliced_handle_new (tex_2ds); - - error: - cogl_object_unref (dst_bmp); - _cogl_texture_2d_sliced_free (tex_2ds); - return COGL_INVALID_HANDLE; -} - -CoglHandle -_cogl_texture_2d_sliced_new_from_foreign (GLuint gl_handle, - GLenum gl_target, - GLuint width, - GLuint height, - GLuint x_pot_waste, - GLuint y_pot_waste, - CoglPixelFormat format) -{ - /* NOTE: width, height and internal format are not queriable - * in GLES, hence such a function prototype. - */ - - GLint gl_width = 0; - GLint gl_height = 0; - CoglTexture2DSliced *tex_2ds; - CoglTexture *tex; - CoglSpan x_span; - CoglSpan y_span; - CoglHandle tex_2d; - - /* This should only be called when the texture target is 2D. If a - rectangle texture is used then _cogl_texture_new_from_foreign - will create a cogl_texture_rectangle instead */ - g_assert (gl_target == GL_TEXTURE_2D); - - gl_width = width + x_pot_waste; - gl_height = height + y_pot_waste; - - /* Validate pot waste */ - if (x_pot_waste < 0 || x_pot_waste >= width || - y_pot_waste < 0 || y_pot_waste >= height) - return COGL_INVALID_HANDLE; - - tex_2d = _cogl_texture_2d_new_from_foreign (gl_target, - gl_width, - gl_height, - format); - - if (!tex_2d) - return COGL_INVALID_HANDLE; - - /* The texture 2d backend may use a different pixel format if it - queries the actual texture so we'll refetch the format it - actually used */ - format = cogl_texture_get_format (tex_2d); - - /* Create new texture */ - tex_2ds = g_new0 (CoglTexture2DSliced, 1); - - tex = COGL_TEXTURE (tex_2ds); - tex->vtable = &cogl_texture_2d_sliced_vtable; - - tex_2ds->width = gl_width - x_pot_waste; - tex_2ds->height = gl_height - y_pot_waste; - tex_2ds->max_waste = 0; - - /* Create slice arrays */ - tex_2ds->slice_x_spans = - g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), 1); - - tex_2ds->slice_y_spans = - g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), 1); - - tex_2ds->slice_textures = - g_array_sized_new (FALSE, FALSE, - sizeof (CoglHandle), 1); - - /* Store info for a single slice */ - x_span.start = 0; - x_span.size = gl_width; - x_span.waste = x_pot_waste; - g_array_append_val (tex_2ds->slice_x_spans, x_span); - - y_span.start = 0; - y_span.size = gl_height; - y_span.waste = y_pot_waste; - g_array_append_val (tex_2ds->slice_y_spans, y_span); - - g_array_append_val (tex_2ds->slice_textures, tex_2d); - - return _cogl_texture_2d_sliced_handle_new (tex_2ds); -} - -static gboolean -_cogl_texture_2d_sliced_is_foreign (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglHandle slice_tex; - - /* Make sure slices were created */ - if (tex_2ds->slice_textures == NULL) - return FALSE; - - /* Pass the call on to the first slice */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, 0); - return _cogl_texture_is_foreign (slice_tex); -} - -static int -_cogl_texture_2d_sliced_get_max_waste (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - return tex_2ds->max_waste; -} - -static gboolean -_cogl_texture_2d_sliced_is_sliced (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - if (tex_2ds->slice_textures == NULL) - return FALSE; - - if (tex_2ds->slice_textures->len <= 1) - return FALSE; - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_can_hardware_repeat (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglHandle slice_tex; - CoglSpan *x_span; - CoglSpan *y_span; - - /* If there's more than one texture then we can't hardware repeat */ - if (tex_2ds->slice_textures->len != 1) - return FALSE; - - /* If there's any waste then we can't hardware repeat */ - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - if (x_span->waste > 0 || y_span->waste > 0) - return FALSE; - - /* Otherwise pass the query on to the single slice texture */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, 0); - return _cogl_texture_can_hardware_repeat (slice_tex); -} - -static void -_cogl_texture_2d_sliced_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglSpan *x_span; - CoglSpan *y_span; - CoglHandle slice_tex; - - g_assert (!_cogl_texture_2d_sliced_is_sliced (tex)); - - /* Don't include the waste in the texture coordinates */ - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - - *s *= tex_2ds->width / (float)x_span->size; - *t *= tex_2ds->height / (float)y_span->size; - - /* Let the child texture further transform the coords */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, 0); - _cogl_texture_transform_coords_to_gl (slice_tex, s, t); -} - -static CoglTransformResult -_cogl_texture_2d_sliced_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - gboolean need_repeat = FALSE; - int i; - - /* This is a bit lazy - in the case where the quad lies entirely - * within a single slice we could avoid the fallback. But that - * could likely lead to visual inconsistency if the fallback involves - * dropping layers, so this might be the right thing to do anyways. - */ - if (_cogl_texture_2d_sliced_is_sliced (tex)) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - - if (need_repeat && !_cogl_texture_2d_sliced_can_hardware_repeat (tex)) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 0, coords + 1); - _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 2, coords + 3); - - return (need_repeat - ? COGL_TRANSFORM_HARDWARE_REPEAT : COGL_TRANSFORM_NO_REPEAT); -} - -static gboolean -_cogl_texture_2d_sliced_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglHandle slice_tex; - - if (tex_2ds->slice_textures == NULL) - return FALSE; - - if (tex_2ds->slice_textures->len < 1) - return FALSE; - - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, 0); - - return cogl_texture_get_gl_texture (slice_tex, out_gl_handle, out_gl_target); -} - -static void -_cogl_texture_2d_sliced_set_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglHandle slice_tex; - int i; - - /* Make sure slices were created */ - if (tex_2ds->slice_textures == NULL) - return; - - /* Apply new filters to every slice. The slice texture itself should - cache the value and avoid resubmitting the same filter value to - GL */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, i); - _cogl_texture_set_filters (slice_tex, min_filter, mag_filter); - } -} - -static void -_cogl_texture_2d_sliced_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - /* Make sure slices were created */ - if (tex_2ds->slice_textures == NULL) - return; - - /* Pass the pre-paint on to every slice */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglHandle slice_tex = g_array_index (tex_2ds->slice_textures, - CoglHandle, i); - _cogl_texture_pre_paint (slice_tex, flags); - } -} - -static void -_cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - /* Make sure slices were created */ - if (tex_2ds->slice_textures == NULL) - return; - - /* Pass the call on to every slice */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglHandle slice_tex = g_array_index (tex_2ds->slice_textures, - CoglHandle, i); - _cogl_texture_ensure_non_quad_rendering (slice_tex); - } -} - -static gboolean -_cogl_texture_2d_sliced_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - GLenum gl_format; - GLenum gl_type; - - _cogl_pixel_format_to_gl (_cogl_bitmap_get_format (bmp), - NULL, /* internal format */ - &gl_format, - &gl_type); - - /* Send data to GL */ - _cogl_texture_2d_sliced_upload_subregion_to_gl (tex_2ds, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - bmp, - gl_format, - gl_type); - - return TRUE; -} - -static CoglPixelFormat -_cogl_texture_2d_sliced_get_format (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglHandle slice_tex; - - /* Make sure slices were created */ - if (tex_2ds->slice_textures == NULL) - return 0; - - /* Pass the call on to the first slice */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, 0); - return cogl_texture_get_format (slice_tex); -} - -static GLenum -_cogl_texture_2d_sliced_get_gl_format (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglHandle slice_tex; - - /* Make sure slices were created */ - if (tex_2ds->slice_textures == NULL) - return 0; - - /* Pass the call on to the first slice */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglHandle, 0); - return _cogl_texture_get_gl_format (slice_tex); -} - -static int -_cogl_texture_2d_sliced_get_width (CoglTexture *tex) -{ - return COGL_TEXTURE_2D_SLICED (tex)->width; -} - -static int -_cogl_texture_2d_sliced_get_height (CoglTexture *tex) -{ - return COGL_TEXTURE_2D_SLICED (tex)->height; -} - -static const CoglTextureVtable -cogl_texture_2d_sliced_vtable = - { - _cogl_texture_2d_sliced_set_region, - NULL, /* get_data */ - _cogl_texture_2d_sliced_foreach_sub_texture_in_region, - _cogl_texture_2d_sliced_get_max_waste, - _cogl_texture_2d_sliced_is_sliced, - _cogl_texture_2d_sliced_can_hardware_repeat, - _cogl_texture_2d_sliced_transform_coords_to_gl, - _cogl_texture_2d_sliced_transform_quad_coords_to_gl, - _cogl_texture_2d_sliced_get_gl_texture, - _cogl_texture_2d_sliced_set_filters, - _cogl_texture_2d_sliced_pre_paint, - _cogl_texture_2d_sliced_ensure_non_quad_rendering, - _cogl_texture_2d_sliced_set_wrap_mode_parameters, - _cogl_texture_2d_sliced_get_format, - _cogl_texture_2d_sliced_get_gl_format, - _cogl_texture_2d_sliced_get_width, - _cogl_texture_2d_sliced_get_height, - _cogl_texture_2d_sliced_is_foreign - }; diff --git a/clutter/cogl/cogl/cogl-texture-2d.c b/clutter/cogl/cogl/cogl-texture-2d.c deleted file mode 100644 index 05a455a..0000000 --- a/clutter/cogl/cogl/cogl-texture-2d.c +++ /dev/null @@ -1,741 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-framebuffer-private.h" - -#include -#include - -static void _cogl_texture_2d_free (CoglTexture2D *tex_2d); - -COGL_TEXTURE_INTERNAL_DEFINE (Texture2D, texture_2d); - -static const CoglTextureVtable cogl_texture_2d_vtable; - -typedef struct _CoglTexture2DManualRepeatData -{ - CoglTexture2D *tex_2d; - CoglTextureSliceCallback callback; - void *user_data; -} CoglTexture2DManualRepeatData; - -static void -_cogl_texture_2d_wrap_coords (float t_1, float t_2, - float *out_t_1, float *out_t_2) -{ - float int_part; - - /* Wrap t_1 and t_2 to the range [0,1] */ - - modff (t_1 < t_2 ? t_1 : t_2, &int_part); - t_1 -= int_part; - t_2 -= int_part; - if (cogl_util_float_signbit (int_part)) - { - *out_t_1 = 1.0f + t_1; - *out_t_2 = 1.0f + t_2; - } - else - { - *out_t_1 = t_1; - *out_t_2 = t_2; - } -} - -static void -_cogl_texture_2d_manual_repeat_cb (const float *coords, - void *user_data) -{ - CoglTexture2DManualRepeatData *data = user_data; - float slice_coords[4]; - - _cogl_texture_2d_wrap_coords (coords[0], coords[2], - slice_coords + 0, slice_coords + 2); - _cogl_texture_2d_wrap_coords (coords[1], coords[3], - slice_coords + 1, slice_coords + 3); - - data->callback (COGL_TEXTURE (data->tex_2d), - slice_coords, - coords, - data->user_data); -} - -static void -_cogl_texture_2d_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglTexture2DManualRepeatData data; - - data.tex_2d = tex_2d; - data.callback = callback; - data.user_data = user_data; - - /* We need to implement manual repeating because if Cogl is calling - this function then it will set the wrap mode to GL_CLAMP_TO_EDGE - and hardware repeating can't be done */ - _cogl_texture_iterate_manual_repeats (_cogl_texture_2d_manual_repeat_cb, - virtual_tx_1, virtual_ty_1, - virtual_tx_2, virtual_ty_2, - &data); -} - -static void -_cogl_texture_2d_set_wrap_mode_parameters (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - /* Only set the wrap mode if it's different from the current value - to avoid too many GL calls. Texture 2D doesn't make use of the r - coordinate so we can ignore its wrap mode */ - if (tex_2d->wrap_mode_s != wrap_mode_s || - tex_2d->wrap_mode_t != wrap_mode_t) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); - GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode_s) ); - GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode_t) ); - - tex_2d->wrap_mode_s = wrap_mode_s; - tex_2d->wrap_mode_t = wrap_mode_t; - } -} - -static void -_cogl_texture_2d_free (CoglTexture2D *tex_2d) -{ - if (!tex_2d->is_foreign) - _cogl_delete_gl_texture (tex_2d->gl_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_2d)); -} - -static gboolean -_cogl_texture_2d_can_create (unsigned int width, - unsigned int height, - CoglPixelFormat internal_format) -{ - GLenum gl_intformat; - GLenum gl_type; - - /* If NPOT textures aren't supported then the size must be a power - of two */ - if (!cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && - (!_cogl_util_is_pot (width) || - !_cogl_util_is_pot (height))) - return FALSE; - - _cogl_pixel_format_to_gl (internal_format, - &gl_intformat, - NULL, - &gl_type); - - /* Check that the driver can create a texture with that size */ - if (!_cogl_texture_driver_size_supported (GL_TEXTURE_2D, - gl_intformat, - gl_type, - width, - height)) - return FALSE; - - return TRUE; -} - -static CoglTexture2D * -_cogl_texture_2d_create_base (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTexture2D *tex_2d = g_new (CoglTexture2D, 1); - CoglTexture *tex = COGL_TEXTURE (tex_2d); - - _cogl_texture_init (tex, &cogl_texture_2d_vtable); - - tex_2d->width = width; - tex_2d->height = height; - tex_2d->mipmaps_dirty = TRUE; - tex_2d->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0; - - /* We default to GL_LINEAR for both filters */ - tex_2d->min_filter = GL_LINEAR; - tex_2d->mag_filter = GL_LINEAR; - - /* Wrap mode not yet set */ - tex_2d->wrap_mode_s = GL_FALSE; - tex_2d->wrap_mode_t = GL_FALSE; - - tex_2d->is_foreign = FALSE; - - tex_2d->format = internal_format; - - return tex_2d; -} - -CoglHandle -_cogl_texture_2d_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTexture2D *tex_2d; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - /* Since no data, we need some internal format */ - if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - - if (!_cogl_texture_2d_can_create (width, height, internal_format)) - return COGL_INVALID_HANDLE; - - internal_format = _cogl_pixel_format_to_gl (internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - tex_2d = _cogl_texture_2d_create_base (width, height, flags, internal_format); - - _cogl_texture_driver_gen (GL_TEXTURE_2D, 1, &tex_2d->gl_texture); - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); - GE( glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat, - width, height, 0, gl_format, gl_type, NULL) ); - - return _cogl_texture_2d_handle_new (tex_2d); -} - -CoglHandle -_cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTexture2D *tex_2d; - CoglBitmap *dst_bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - guint8 *data; - - g_return_val_if_fail (bmp != NULL, COGL_INVALID_HANDLE); - - internal_format = - _cogl_texture_determine_internal_format (_cogl_bitmap_get_format (bmp), - internal_format); - - if (!_cogl_texture_2d_can_create (_cogl_bitmap_get_width (bmp), - _cogl_bitmap_get_height (bmp), - internal_format)) - return COGL_INVALID_HANDLE; - - if ((dst_bmp = _cogl_texture_prepare_for_upload (bmp, - internal_format, - &internal_format, - &gl_intformat, - &gl_format, - &gl_type)) == NULL) - return COGL_INVALID_HANDLE; - - tex_2d = _cogl_texture_2d_create_base (_cogl_bitmap_get_width (bmp), - _cogl_bitmap_get_height (bmp), - flags, - internal_format); - - /* Keep a copy of the first pixel so that if glGenerateMipmap isn't - supported we can fallback to using GL_GENERATE_MIPMAP */ - if (!cogl_features_available (COGL_FEATURE_OFFSCREEN) && - (data = _cogl_bitmap_map (dst_bmp, - COGL_BUFFER_ACCESS_READ, 0))) - { - tex_2d->first_pixel.gl_format = gl_format; - tex_2d->first_pixel.gl_type = gl_type; - memcpy (tex_2d->first_pixel.data, data, - _cogl_get_format_bpp (_cogl_bitmap_get_format (dst_bmp))); - - _cogl_bitmap_unmap (dst_bmp); - } - - _cogl_texture_driver_gen (GL_TEXTURE_2D, 1, &tex_2d->gl_texture); - _cogl_texture_driver_upload_to_gl (GL_TEXTURE_2D, - tex_2d->gl_texture, - FALSE, - dst_bmp, - gl_intformat, - gl_format, - gl_type); - - tex_2d->gl_format = gl_intformat; - - cogl_object_unref (dst_bmp); - - return _cogl_texture_2d_handle_new (tex_2d); -} - -CoglHandle -_cogl_texture_2d_new_from_foreign (GLuint gl_handle, - GLuint width, - GLuint height, - CoglPixelFormat format) -{ - /* NOTE: width, height and internal format are not queriable - * in GLES, hence such a function prototype. - */ - - GLenum gl_error = 0; - GLint gl_compressed = GL_FALSE; - GLenum gl_int_format = 0; - CoglTexture2D *tex_2d; - - if (!_cogl_texture_driver_allows_foreign_gl_target (GL_TEXTURE_2D)) - return COGL_INVALID_HANDLE; - - /* Make sure it is a valid GL texture object */ - if (!glIsTexture (gl_handle)) - return COGL_INVALID_HANDLE; - - /* Make sure binding succeeds */ - while ((gl_error = glGetError ()) != GL_NO_ERROR) - ; - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, gl_handle, TRUE); - if (glGetError () != GL_NO_ERROR) - return COGL_INVALID_HANDLE; - - /* Obtain texture parameters - (only level 0 we are interested in) */ - -#if HAVE_COGL_GL - - GE( glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, - GL_TEXTURE_COMPRESSED, - &gl_compressed) ); - - { - GLint val; - - GE( glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, - GL_TEXTURE_INTERNAL_FORMAT, - &val) ); - - gl_int_format = val; - } - - /* If we can query GL for the actual pixel format then we'll ignore - the passed in format and use that. */ - if (!_cogl_pixel_format_from_gl_internal (gl_int_format, &format)) - return COGL_INVALID_HANDLE; - -#else - - /* Otherwise we'll assume we can derive the GL format from the - passed in format */ - _cogl_pixel_format_to_gl (format, - &gl_int_format, - NULL, - NULL); - -#endif - - /* Note: We always trust the given width and height without querying - * the texture object because the user may be creating a Cogl - * texture for a texture_from_pixmap object where glTexImage2D may - * not have been called and the texture_from_pixmap spec doesn't - * clarify that it is reliable to query back the size from OpenGL. - */ - - /* Validate width and height */ - if (width <= 0 || height <= 0) - return COGL_INVALID_HANDLE; - - /* Compressed texture images not supported */ - if (gl_compressed == GL_TRUE) - return COGL_INVALID_HANDLE; - - /* Note: previously this code would query the texture object for - whether it has GL_GENERATE_MIPMAP enabled to determine whether to - auto-generate the mipmap. This doesn't make much sense any more - since Cogl switch to using glGenerateMipmap. Ideally I think - cogl_texture_new_from_foreign should take a flags parameter so - that the application can decide whether it wants - auto-mipmapping. To be compatible with existing code, Cogl now - disables its own auto-mipmapping but leaves the value of - GL_GENERATE_MIPMAP alone so that it would still work but without - the dirtiness tracking that Cogl would do. */ - - /* Create new texture */ - tex_2d = _cogl_texture_2d_create_base (width, height, - COGL_TEXTURE_NO_AUTO_MIPMAP, - format); - - /* Setup bitmap info */ - tex_2d->is_foreign = TRUE; - tex_2d->mipmaps_dirty = TRUE; - - tex_2d->format = format; - - tex_2d->gl_texture = gl_handle; - tex_2d->gl_format = gl_int_format; - - /* Unknown filter */ - tex_2d->min_filter = GL_FALSE; - tex_2d->mag_filter = GL_FALSE; - - return _cogl_texture_2d_handle_new (tex_2d); -} - -void -_cogl_texture_2d_externally_modified (CoglHandle handle) -{ - if (!_cogl_is_texture_2d (handle)) - return; - - COGL_TEXTURE_2D (handle)->mipmaps_dirty = TRUE; -} - -void -_cogl_texture_2d_copy_from_framebuffer (CoglHandle handle, - int dst_x, - int dst_y, - int src_x, - int src_y, - int width, - int height) -{ - CoglTexture2D *tex_2d; - - g_return_if_fail (_cogl_is_texture_2d (handle)); - - tex_2d = COGL_TEXTURE_2D (handle); - - /* Make sure the current framebuffers are bound. We explicitly avoid - flushing the clip state so we can bind our own empty state */ - _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), - _cogl_get_read_framebuffer (), - 0); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); - - glCopyTexSubImage2D (GL_TEXTURE_2D, - 0, /* level */ - dst_x, dst_y, - src_x, src_y, - width, height); - - tex_2d->mipmaps_dirty = TRUE; -} - -static int -_cogl_texture_2d_get_max_waste (CoglTexture *tex) -{ - return -1; -} - -static gboolean -_cogl_texture_2d_is_sliced (CoglTexture *tex) -{ - return FALSE; -} - -static gboolean -_cogl_texture_2d_can_hardware_repeat (CoglTexture *tex) -{ - return TRUE; -} - -static void -_cogl_texture_2d_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - /* The texture coordinates map directly so we don't need to do - anything */ -} - -static CoglTransformResult -_cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - /* The texture coordinates map directly so we don't need to do - anything other than check for repeats */ - - gboolean need_repeat = FALSE; - int i; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - - return (need_repeat ? COGL_TRANSFORM_HARDWARE_REPEAT - : COGL_TRANSFORM_NO_REPEAT); -} - -static gboolean -_cogl_texture_2d_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - if (out_gl_handle) - *out_gl_handle = tex_2d->gl_texture; - - if (out_gl_target) - *out_gl_target = GL_TEXTURE_2D; - - return TRUE; -} - -static void -_cogl_texture_2d_set_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - if (min_filter == tex_2d->min_filter - && mag_filter == tex_2d->mag_filter) - return; - - /* Store new values */ - tex_2d->min_filter = min_filter; - tex_2d->mag_filter = mag_filter; - - /* Apply new filters to the texture */ - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); - GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter) ); - GE( glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter) ); -} - -static void -_cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Only update if the mipmaps are dirty */ - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) && - tex_2d->auto_mipmap && tex_2d->mipmaps_dirty) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); - - /* glGenerateMipmap is defined in the FBO extension. If it's not - available we'll fallback to temporarily enabling - GL_GENERATE_MIPMAP and reuploading the first pixel */ - if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) - _cogl_texture_driver_gl_generate_mipmaps (GL_TEXTURE_2D); -#ifndef HAVE_COGL_GLES2 - else - { - GE( glTexParameteri (GL_TEXTURE_2D, - GL_GENERATE_MIPMAP, - GL_TRUE) ); - GE( glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 1, 1, - tex_2d->first_pixel.gl_format, - tex_2d->first_pixel.gl_type, - tex_2d->first_pixel.data) ); - GE( glTexParameteri (GL_TEXTURE_2D, - GL_GENERATE_MIPMAP, - GL_FALSE) ); - } -#endif - - tex_2d->mipmaps_dirty = FALSE; - } -} - -static void -_cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex) -{ - /* Nothing needs to be done */ -} - -static gboolean -_cogl_texture_2d_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - GLenum gl_format; - GLenum gl_type; - guint8 *data; - - _cogl_pixel_format_to_gl (_cogl_bitmap_get_format (bmp), - NULL, /* internal format */ - &gl_format, - &gl_type); - - /* If this touches the first pixel then we'll update our copy */ - if (dst_x == 0 && dst_y == 0 && - !cogl_features_available (COGL_FEATURE_OFFSCREEN) && - (data = _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0))) - { - CoglPixelFormat bpp = - _cogl_get_format_bpp (_cogl_bitmap_get_format (bmp)); - tex_2d->first_pixel.gl_format = gl_format; - tex_2d->first_pixel.gl_type = gl_type; - memcpy (tex_2d->first_pixel.data, - data + _cogl_bitmap_get_rowstride (bmp) * src_y + bpp * src_x, - bpp); - - _cogl_bitmap_unmap (bmp); - } - - /* Send data to GL */ - _cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_2D, - tex_2d->gl_texture, - FALSE, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - bmp, - gl_format, - gl_type); - - tex_2d->mipmaps_dirty = TRUE; - - return TRUE; -} - -static gboolean -_cogl_texture_2d_get_data (CoglTexture *tex, - CoglPixelFormat format, - unsigned int rowstride, - guint8 *data) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - int bpp; - GLenum gl_format; - GLenum gl_type; - - bpp = _cogl_get_format_bpp (format); - - _cogl_pixel_format_to_gl (format, - NULL, /* internal format */ - &gl_format, - &gl_type); - - _cogl_texture_driver_prep_gl_for_pixels_download (rowstride, bpp); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); - return _cogl_texture_driver_gl_get_tex_image (GL_TEXTURE_2D, - gl_format, - gl_type, - data); -} - -static CoglPixelFormat -_cogl_texture_2d_get_format (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->format; -} - -static GLenum -_cogl_texture_2d_get_gl_format (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->gl_format; -} - -static int -_cogl_texture_2d_get_width (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->width; -} - -static int -_cogl_texture_2d_get_height (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->height; -} - -static gboolean -_cogl_texture_2d_is_foreign (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->is_foreign; -} - -static const CoglTextureVtable -cogl_texture_2d_vtable = - { - _cogl_texture_2d_set_region, - _cogl_texture_2d_get_data, - _cogl_texture_2d_foreach_sub_texture_in_region, - _cogl_texture_2d_get_max_waste, - _cogl_texture_2d_is_sliced, - _cogl_texture_2d_can_hardware_repeat, - _cogl_texture_2d_transform_coords_to_gl, - _cogl_texture_2d_transform_quad_coords_to_gl, - _cogl_texture_2d_get_gl_texture, - _cogl_texture_2d_set_filters, - _cogl_texture_2d_pre_paint, - _cogl_texture_2d_ensure_non_quad_rendering, - _cogl_texture_2d_set_wrap_mode_parameters, - _cogl_texture_2d_get_format, - _cogl_texture_2d_get_gl_format, - _cogl_texture_2d_get_width, - _cogl_texture_2d_get_height, - _cogl_texture_2d_is_foreign - }; diff --git a/clutter/cogl/cogl/cogl-texture-3d-private.h b/clutter/cogl/cogl/cogl-texture-3d-private.h deleted file mode 100644 index 7fa29ae..0000000 --- a/clutter/cogl/cogl/cogl-texture-3d-private.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_TEXTURE_3D_PRIVATE_H -#define __COGL_TEXTURE_3D_PRIVATE_H - -#include "cogl-handle.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" - -#define COGL_TEXTURE_3D(tex) ((CoglTexture3D *) tex) - -typedef struct _CoglTexture3D CoglTexture3D; - -struct _CoglTexture3D -{ - CoglTexture _parent; - - /* The internal format of the GL texture represented as a - CoglPixelFormat */ - CoglPixelFormat format; - /* The internal format of the GL texture represented as a GL enum */ - GLenum gl_format; - /* The texture object number */ - GLuint gl_texture; - int width; - int height; - int depth; - GLenum min_filter; - GLenum mag_filter; - GLint wrap_mode_s; - GLint wrap_mode_t; - GLint wrap_mode_p; - gboolean auto_mipmap; - gboolean mipmaps_dirty; - - CoglTexturePixel first_pixel; -}; - -GQuark -_cogl_handle_texture_3d_get_type (void); - -/* - * cogl_texture_3d_new_from_bitmap: - * @bmp_handle: A #CoglHandle to a bitmap. - * @height: height of the texture in pixels. - * @depth: depth of the texture in pixels. - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat that will be used for storing - * the buffer on the GPU. If COGL_PIXEL_FORMAT_ANY is given then a - * premultiplied format similar to the format of the source data will - * be used. The default blending equations of Cogl expect premultiplied - * color data; the main use of passing a non-premultiplied format here - * is if you have non-premultiplied source data and are going to adjust - * the blend mode (see cogl_pipeline_set_blend()) or use the data for - * something other than straight blending. - * @error: A GError return location. - * - * Creates a new 3D texture and initializes it with the images in - * @bmp_handle. The images are assumed to be packed together after one - * another in the increasing y axis. The height of individual image is - * given as @height and the number of images is given in @depth. The - * actual height of the bitmap can be larger than @height × @depth. In - * this case it assumes there is padding between the images. - * - * Return value: the newly created texture or %COGL_INVALID_HANDLE if - * there was an error. - */ -CoglHandle -_cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error); - -#endif /* __COGL_TEXTURE_3D_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-texture-3d.c b/clutter/cogl/cogl/cogl-texture-3d.c deleted file mode 100644 index 6b89887..0000000 --- a/clutter/cogl/cogl/cogl-texture-3d.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-texture-3d-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" - -#include -#include - -/* These might not be defined on GLES */ -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif -#ifndef GL_TEXTURE_WRAP_R -#define GL_TEXTURE_WRAP_R 0x8072 -#endif - -#define glTexImage3D ctx->drv.pf_glTexImage3D -#define glTexSubImage3D ctx->drv.pf_glTexSubImage3D - -static void _cogl_texture_3d_free (CoglTexture3D *tex_3d); - -COGL_TEXTURE_DEFINE (Texture3D, texture_3d); - -static const CoglTextureVtable cogl_texture_3d_vtable; - -typedef struct _CoglTexture3DManualRepeatData -{ - CoglTexture3D *tex_3d; - CoglTextureSliceCallback callback; - void *user_data; -} CoglTexture3DManualRepeatData; - -static void -_cogl_texture_3d_wrap_coords (float t_1, float t_2, - float *out_t_1, float *out_t_2) -{ - float int_part; - - /* Wrap t_1 and t_2 to the range [0,1] */ - - modff (t_1 < t_2 ? t_1 : t_2, &int_part); - t_1 -= int_part; - t_2 -= int_part; - if (cogl_util_float_signbit (int_part)) - { - *out_t_1 = 1.0f + t_1; - *out_t_2 = 1.0f + t_2; - } - else - { - *out_t_1 = t_1; - *out_t_2 = t_2; - } -} - -static void -_cogl_texture_3d_manual_repeat_cb (const float *coords, - void *user_data) -{ - CoglTexture3DManualRepeatData *data = user_data; - float slice_coords[4]; - - _cogl_texture_3d_wrap_coords (coords[0], coords[2], - slice_coords + 0, slice_coords + 2); - _cogl_texture_3d_wrap_coords (coords[1], coords[3], - slice_coords + 1, slice_coords + 3); - - data->callback (COGL_TEXTURE (data->tex_3d), - slice_coords, - coords, - data->user_data); -} - -static void -_cogl_texture_3d_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - CoglTexture3DManualRepeatData data; - - data.tex_3d = tex_3d; - data.callback = callback; - data.user_data = user_data; - - /* We need to implement manual repeating because if Cogl is calling - this function then it will set the wrap mode to GL_CLAMP_TO_EDGE - and hardware repeating can't be done */ - _cogl_texture_iterate_manual_repeats (_cogl_texture_3d_manual_repeat_cb, - virtual_tx_1, virtual_ty_1, - virtual_tx_2, virtual_ty_2, - &data); -} - -static void -_cogl_texture_3d_set_wrap_mode_parameters (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - - /* Only set the wrap mode if it's different from the current value - to avoid too many GL calls. */ - if (tex_3d->wrap_mode_s != wrap_mode_s || - tex_3d->wrap_mode_t != wrap_mode_t || - tex_3d->wrap_mode_p != wrap_mode_p) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE); - GE( glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, wrap_mode_s) ); - GE( glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, wrap_mode_t) ); - GE( glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, wrap_mode_p) ); - - tex_3d->wrap_mode_s = wrap_mode_s; - tex_3d->wrap_mode_t = wrap_mode_t; - tex_3d->wrap_mode_p = wrap_mode_p; - } -} - -static void -_cogl_texture_3d_free (CoglTexture3D *tex_3d) -{ - _cogl_delete_gl_texture (tex_3d->gl_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_3d)); -} - -static CoglTexture3D * -_cogl_texture_3d_create_base (unsigned int width, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTexture3D *tex_3d = g_new (CoglTexture3D, 1); - CoglTexture *tex = COGL_TEXTURE (tex_3d); - - _cogl_texture_init (tex, &cogl_texture_3d_vtable); - - tex_3d->width = width; - tex_3d->height = height; - tex_3d->depth = depth; - tex_3d->mipmaps_dirty = TRUE; - tex_3d->auto_mipmap = (flags & COGL_TEXTURE_NO_AUTO_MIPMAP) == 0; - - /* We default to GL_LINEAR for both filters */ - tex_3d->min_filter = GL_LINEAR; - tex_3d->mag_filter = GL_LINEAR; - - /* Wrap mode not yet set */ - tex_3d->wrap_mode_s = GL_FALSE; - tex_3d->wrap_mode_t = GL_FALSE; - tex_3d->wrap_mode_p = GL_FALSE; - - tex_3d->format = internal_format; - - return tex_3d; -} - -static gboolean -_cogl_texture_3d_can_create (unsigned int width, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error) -{ - GLenum gl_intformat; - GLenum gl_type; - - /* This should only happen on GLES */ - if (!cogl_features_available (COGL_FEATURE_TEXTURE_3D)) - { - g_set_error (error, - COGL_ERROR, - COGL_ERROR_UNSUPPORTED, - "3D textures are not supported by the GPU"); - return FALSE; - } - - /* If NPOT textures aren't supported then the size must be a power - of two */ - if (!cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && - (!_cogl_util_is_pot (width) || - !_cogl_util_is_pot (height) || - !_cogl_util_is_pot (depth))) - { - g_set_error (error, - COGL_ERROR, - COGL_ERROR_UNSUPPORTED, - "A non-power-of-two size was requested but this is not " - "supported by the GPU"); - return FALSE; - } - - _cogl_pixel_format_to_gl (internal_format, - &gl_intformat, - NULL, - &gl_type); - - /* Check that the driver can create a texture with that size */ - if (!_cogl_texture_driver_size_supported_3d (GL_TEXTURE_3D, - gl_intformat, - gl_type, - width, - height, - depth)) - { - g_set_error (error, - COGL_ERROR, - COGL_ERROR_UNSUPPORTED, - "The requested dimensions are not supported by the GPU"); - return FALSE; - } - - return TRUE; -} - -CoglHandle -cogl_texture_3d_new_with_size (unsigned int width, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error) -{ - CoglTexture3D *tex_3d; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - /* Since no data, we need some internal format */ - if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - - if (!_cogl_texture_3d_can_create (width, height, depth, - flags, internal_format, - error)) - return COGL_INVALID_HANDLE; - - internal_format = _cogl_pixel_format_to_gl (internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - tex_3d = _cogl_texture_3d_create_base (width, height, depth, - flags, internal_format); - - _cogl_texture_driver_gen (GL_TEXTURE_3D, 1, &tex_3d->gl_texture); - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE); - GE( glTexImage3D (GL_TEXTURE_3D, 0, gl_intformat, - width, height, depth, 0, gl_format, gl_type, NULL) ); - - return _cogl_texture_3d_handle_new (tex_3d); -} - -CoglHandle -_cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error) -{ - CoglTexture3D *tex_3d; - CoglBitmap *dst_bmp; - CoglPixelFormat bmp_format; - unsigned int bmp_width; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - guint8 *data; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - bmp_width = _cogl_bitmap_get_width (bmp); - bmp_format = _cogl_bitmap_get_format (bmp); - - internal_format = _cogl_texture_determine_internal_format (bmp_format, - internal_format); - - if (!_cogl_texture_3d_can_create (bmp_width, height, depth, - flags, internal_format, - error)) - return COGL_INVALID_HANDLE; - - dst_bmp = _cogl_texture_prepare_for_upload (bmp, - internal_format, - &internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - if (dst_bmp == NULL) - { - g_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_FAILED, - "Bitmap conversion failed"); - return COGL_INVALID_HANDLE; - } - - tex_3d = _cogl_texture_3d_create_base (bmp_width, height, depth, - flags, internal_format); - - /* Keep a copy of the first pixel so that if glGenerateMipmap isn't - supported we can fallback to using GL_GENERATE_MIPMAP */ - if (!cogl_features_available (COGL_FEATURE_OFFSCREEN) && - (data = _cogl_bitmap_map (dst_bmp, - COGL_BUFFER_ACCESS_READ, 0))) - { - tex_3d->first_pixel.gl_format = gl_format; - tex_3d->first_pixel.gl_type = gl_type; - memcpy (tex_3d->first_pixel.data, data, - _cogl_get_format_bpp (_cogl_bitmap_get_format (dst_bmp))); - - _cogl_bitmap_unmap (dst_bmp); - } - - _cogl_texture_driver_gen (GL_TEXTURE_3D, 1, &tex_3d->gl_texture); - - _cogl_texture_driver_upload_to_gl_3d (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE, /* is_foreign */ - height, - depth, - dst_bmp, - gl_intformat, - gl_format, - gl_type); - - tex_3d->gl_format = gl_intformat; - - cogl_object_unref (dst_bmp); - - return _cogl_texture_3d_handle_new (tex_3d); -} - -CoglHandle -cogl_texture_3d_new_from_data (unsigned int width, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - unsigned int rowstride, - unsigned int image_stride, - const guint8 *data, - GError **error) -{ - CoglBitmap *bitmap; - CoglHandle ret; - - /* These are considered a programmer errors so we won't set a - GError. It would be nice if this was a g_return_if_fail but the - rest of Cogl isn't using that */ - if (format == COGL_PIXEL_FORMAT_ANY) - return COGL_INVALID_HANDLE; - - if (data == NULL) - return COGL_INVALID_HANDLE; - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * _cogl_get_format_bpp (format); - /* Image stride from height and rowstride if not given */ - if (image_stride == 0) - image_stride = height * rowstride; - - if (image_stride < rowstride * height) - return COGL_INVALID_HANDLE; - - /* GL doesn't support uploading when the image_stride isn't a - multiple of the rowstride. If this happens we'll just pack the - image into a new bitmap. The documentation for this function - recommends avoiding this situation. */ - if (image_stride % rowstride != 0) - { - int z, y; - int bmp_rowstride = _cogl_get_format_bpp (format) * width; - guint8 *bmp_data = g_malloc (bmp_rowstride * height * depth); - - bitmap = _cogl_bitmap_new_from_data (bmp_data, - format, - width, - depth * height, - bmp_rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL /* destroy_fn_data */); - - /* Copy all of the images in */ - for (z = 0; z < depth; z++) - for (y = 0; y < height; y++) - memcpy (bmp_data + (z * bmp_rowstride * height + - bmp_rowstride * y), - data + z * image_stride + rowstride * y, - bmp_rowstride); - } - else - bitmap = _cogl_bitmap_new_from_data ((guint8 *) data, - format, - width, - image_stride / rowstride * depth, - rowstride, - NULL, /* destroy_fn */ - NULL /* destroy_fn_data */); - - ret = _cogl_texture_3d_new_from_bitmap (bitmap, - height, - depth, - flags, - internal_format, - error); - - cogl_object_unref (bitmap); - - return ret; -} - -GQuark -cogl_texture_3d_error_quark (void) -{ - return g_quark_from_static_string ("cogl-texture-3d-error-quark"); -} - -static int -_cogl_texture_3d_get_max_waste (CoglTexture *tex) -{ - return -1; -} - -static gboolean -_cogl_texture_3d_is_sliced (CoglTexture *tex) -{ - return FALSE; -} - -static gboolean -_cogl_texture_3d_can_hardware_repeat (CoglTexture *tex) -{ - return TRUE; -} - -static void -_cogl_texture_3d_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - /* The texture coordinates map directly so we don't need to do - anything */ -} - -static CoglTransformResult -_cogl_texture_3d_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - /* The texture coordinates map directly so we don't need to do - anything other than check for repeats */ - - gboolean need_repeat = FALSE; - int i; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - - return (need_repeat ? COGL_TRANSFORM_HARDWARE_REPEAT - : COGL_TRANSFORM_NO_REPEAT); -} - -static gboolean -_cogl_texture_3d_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - - if (out_gl_handle) - *out_gl_handle = tex_3d->gl_texture; - - if (out_gl_target) - *out_gl_target = GL_TEXTURE_3D; - - return TRUE; -} - -static void -_cogl_texture_3d_set_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - - if (min_filter == tex_3d->min_filter - && mag_filter == tex_3d->mag_filter) - return; - - /* Store new values */ - tex_3d->min_filter = min_filter; - tex_3d->mag_filter = mag_filter; - - /* Apply new filters to the texture */ - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE); - GE( glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, mag_filter) ); - GE( glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, min_filter) ); -} - -static void -_cogl_texture_3d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Only update if the mipmaps are dirty */ - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) && - tex_3d->auto_mipmap && tex_3d->mipmaps_dirty) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE); - /* glGenerateMipmap is defined in the FBO extension. If it's not - available we'll fallback to temporarily enabling - GL_GENERATE_MIPMAP and reuploading the first pixel */ - if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) - _cogl_texture_driver_gl_generate_mipmaps (GL_TEXTURE_3D); -#ifndef HAVE_COGL_GLES2 - else - { - GE( glTexParameteri (GL_TEXTURE_3D, - GL_GENERATE_MIPMAP, - GL_TRUE) ); - GE( glTexSubImage3D (GL_TEXTURE_3D, - 0, /* level */ - 0, /* xoffset */ - 0, /* yoffset */ - 0, /* zoffset */ - 1, /* width */ - 1, /* height */ - 1, /* depth */ - tex_3d->first_pixel.gl_format, - tex_3d->first_pixel.gl_type, - tex_3d->first_pixel.data) ); - GE( glTexParameteri (GL_TEXTURE_3D, - GL_GENERATE_MIPMAP, - GL_FALSE) ); - } -#endif - - tex_3d->mipmaps_dirty = FALSE; - } -} - -static void -_cogl_texture_3d_ensure_non_quad_rendering (CoglTexture *tex) -{ - /* Nothing needs to be done */ -} - -static gboolean -_cogl_texture_3d_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - /* This function doesn't really make sense for 3D textures because - it can't specify which image to upload to */ - return FALSE; -} - -static int -_cogl_texture_3d_get_data (CoglTexture *tex, - CoglPixelFormat format, - unsigned int rowstride, - guint8 *data) -{ - /* FIXME: we could probably implement this by assuming the data is - big enough to hold all of the images and that there is no stride - between the images. However it would be better to have an API - that can provide an image stride and this function probably isn't - particularly useful anyway so for now it just reports failure */ - return 0; -} - -static CoglPixelFormat -_cogl_texture_3d_get_format (CoglTexture *tex) -{ - return COGL_TEXTURE_3D (tex)->format; -} - -static GLenum -_cogl_texture_3d_get_gl_format (CoglTexture *tex) -{ - return COGL_TEXTURE_3D (tex)->gl_format; -} - -static int -_cogl_texture_3d_get_width (CoglTexture *tex) -{ - return COGL_TEXTURE_3D (tex)->width; -} - -static int -_cogl_texture_3d_get_height (CoglTexture *tex) -{ - return COGL_TEXTURE_3D (tex)->height; -} - -static const CoglTextureVtable -cogl_texture_3d_vtable = - { - _cogl_texture_3d_set_region, - _cogl_texture_3d_get_data, - _cogl_texture_3d_foreach_sub_texture_in_region, - _cogl_texture_3d_get_max_waste, - _cogl_texture_3d_is_sliced, - _cogl_texture_3d_can_hardware_repeat, - _cogl_texture_3d_transform_coords_to_gl, - _cogl_texture_3d_transform_quad_coords_to_gl, - _cogl_texture_3d_get_gl_texture, - _cogl_texture_3d_set_filters, - _cogl_texture_3d_pre_paint, - _cogl_texture_3d_ensure_non_quad_rendering, - _cogl_texture_3d_set_wrap_mode_parameters, - _cogl_texture_3d_get_format, - _cogl_texture_3d_get_gl_format, - _cogl_texture_3d_get_width, - _cogl_texture_3d_get_height, - NULL /* is_foreign */ - }; diff --git a/clutter/cogl/cogl/cogl-texture-3d.h b/clutter/cogl/cogl/cogl-texture-3d.h deleted file mode 100644 index 7f14c5e..0000000 --- a/clutter/cogl/cogl/cogl-texture-3d.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Neil Roberts - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_TEXTURE_3D_H -#define __COGL_TEXTURE_3D_H - -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-texture-3d - * @short_description: Fuctions for creating and manipulating 3D textures - * - * These functions allow 3D textures to be used. 3D textures can be - * thought of as layers of 2D images arranged into a cuboid - * shape. When choosing a texel from the texture, Cogl will take into - * account the 'r' texture coordinate to select one of the images. - */ - -/* All of the cogl-texture-3d API is currently experimental so we - * suffix the actual symbols with _EXP so if somone is monitoring for - * ABI changes it will hopefully be clearer to them what's going on if - * any of the symbols dissapear at a later date. - */ -#define cogl_texture_3d_new_with_size cogl_texture_3d_new_with_size_EXP -#define cogl_texture_3d_new_from_data cogl_texture_3d_new_from_data_EXP -#define cogl_is_texture_3d cogl_is_texture_3d_EXP - -/** - * cogl_texture_3d_new_with_size: - * @width: width of the texture in pixels. - * @height: height of the texture in pixels. - * @depth: depth of the texture in pixels. - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat to use for the GPU - * storage of the texture. - * @error: A GError return location. - * - * Creates a new Cogl 3D texture with the specified dimensions and - * pixel format. - * - * Note that this function will throw a #GError if - * %COGL_FEATURE_TEXTURE_3D is not advertised. It can also fail if the - * requested dimensions are not supported by the GPU. - * - * Return value: a new handle to a CoglTexture3D object or - * %COGL_INVALID_HANDLE on failure. - * Since: 1.4 - * Stability: Unstable - */ -CoglHandle -cogl_texture_3d_new_with_size (unsigned int width, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error); - -/** - * cogl_texture_3d_new_from_data: - * @width: width of the texture in pixels. - * @height: height of the texture in pixels. - * @depth: depth of the texture in pixels. - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @internal_format: the #CoglPixelFormat that will be used for storing - * the buffer on the GPU. If COGL_PIXEL_FORMAT_ANY is given then a - * premultiplied format similar to the format of the source data will - * be used. The default blending equations of Cogl expect premultiplied - * color data; the main use of passing a non-premultiplied format here - * is if you have non-premultiplied source data and are going to adjust - * the blend mode (see cogl_material_set_blend()) or use the data for - * something other than straight blending. - * @rowstride: the memory offset in bytes between the starts of - * scanlines in @data or 0 to infer it from the width and format - * @image_stride: the number of bytes from one image to the next. This - * can be used to add padding between the images in a similar way - * that the rowstride can be used to add padding between - * rows. Alternatively 0 can be passed to infer the @image_stride - * from the @height. - * @data: pointer the memory region where the source buffer resides - * @error: A GError return location. - * - * Creates a new 3D texture and initializes it with @data. The data is - * assumed to be packed array of @depth images. There can be padding - * between the images using @image_stride. - * - * Note that this function will throw a #GError if - * %COGL_FEATURE_TEXTURE_3D is not advertised. It can also fail if the - * requested dimensions are not supported by the GPU. - * - * Return value: the newly created texture or %COGL_INVALID_HANDLE if - * there was an error. - * Since: 1.4 - * Stability: Unstable - */ -CoglHandle -cogl_texture_3d_new_from_data (unsigned int width, - unsigned int height, - unsigned int depth, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - unsigned int rowstride, - unsigned int image_stride, - const guint8 *data, - GError **error); - -/** - * cogl_is_texture_3d: - * @handle: a #CoglHandle - * - * Checks whether @handle is a #CoglHandle for a 3D texture. - * - * Return value: %TRUE if the passed handle represents a 3D texture - * and %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_is_texture_3d (CoglHandle handle); - -G_END_DECLS - -#endif /* __COGL_TEXTURE_3D_H */ diff --git a/clutter/cogl/cogl/cogl-texture-driver.h b/clutter/cogl/cogl/cogl-texture-driver.h deleted file mode 100644 index bc1ca63..0000000 --- a/clutter/cogl/cogl/cogl-texture-driver.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_TEXTURE_DRIVER_H -#define __COGL_TEXTURE_DRIVER_H - -/* - * A very small wrapper around glGenTextures() that ensures we default to - * non-mipmap filters when creating textures. This is to save some memory as - * the driver will not allocate room for the mipmap tree. - */ -void -_cogl_texture_driver_gen (GLenum gl_target, - GLsizei n, - GLuint *textures); - -/* - * This sets up the glPixelStore state for an upload to a destination with - * the same size, and with no offset. - */ -/* NB: GLES can't upload a sub region of pixel data from a larger source - * buffer which is why this interface is limited. The GL driver has a more - * flexible version of this function that is uses internally */ -void -_cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride, - int pixels_bpp); - -/* - * This uploads a sub-region from source_bmp to a single GL texture handle (i.e - * a single CoglTexture slice) - * - * It also updates the array of tex->first_pixels[slice_index] if - * dst_{x,y} == 0 - * - * The driver abstraction is in place because GLES doesn't support the pixel - * store options required to source from a subregion, so for GLES we have - * to manually create a transient source bitmap. - * - * XXX: sorry for the ridiculous number of arguments :-( - */ -void -_cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type); - -/* - * Replaces the contents of the GL texture with the entire bitmap. On - * GL this just directly calls glTexImage2D, but under GLES it needs - * to copy the bitmap if the rowstride is not a multiple of a possible - * alignment value because there is no GL_UNPACK_ROW_LENGTH - */ -void -_cogl_texture_driver_upload_to_gl (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type); - -/* - * Replaces the contents of the GL texture with the entire bitmap. The - * width of the texture is inferred from the bitmap. The height and - * depth of the texture is given directly. The 'image_height' (which - * is the number of rows between images) is inferred by dividing the - * height of the bitmap by the depth. - */ -void -_cogl_texture_driver_upload_to_gl_3d (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - GLint height, - GLint depth, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type); - -/* - * This sets up the glPixelStore state for an download to a destination with - * the same size, and with no offset. - */ -/* NB: GLES can't download pixel data into a sub region of a larger destination - * buffer, the GL driver has a more flexible version of this function that it - * uses internally. */ -void -_cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride, - int pixels_bpp); - -/* - * This driver abstraction is in place because GLES doesn't have a sane way to - * download data from a texture so you litterally render the texture to the - * backbuffer, and retrive the data using glReadPixels :-( - */ -gboolean -_cogl_texture_driver_download_from_gl (CoglTexture *tex, - CoglBitmap *target_bmp, - GLuint target_gl_format, - GLuint target_gl_type); - -/* - * This driver abstraction is needed because GLES doesn't support glGetTexImage - * (). On GLES this currently just returns FALSE which will lead to a generic - * fallback path being used that simply renders the texture and reads it back - * from the framebuffer. (See _cogl_texture_draw_and_read () ) - */ -gboolean -_cogl_texture_driver_gl_get_tex_image (GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - guint8 *dest); - -/* - * It may depend on the driver as to what texture sizes are supported... - */ -gboolean -_cogl_texture_driver_size_supported (GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height); - -gboolean -_cogl_texture_driver_size_supported_3d (GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height, - int depth); - -/* - * This driver abstraction is needed because GLES doesn't support setting - * a texture border color. - */ -void -_cogl_texture_driver_try_setting_gl_border_color ( - GLuint gl_target, - const GLfloat *transparent_color); - -/* - * XXX: this should live in cogl/{gl,gles}/cogl.c - */ -gboolean -_cogl_pixel_format_from_gl_internal (GLenum gl_int_format, - CoglPixelFormat *out_format); - -/* - * XXX: this should live in cogl/{gl,gles}/cogl.c - */ -CoglPixelFormat -_cogl_pixel_format_to_gl (CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype); - -/* - * It may depend on the driver as to what texture targets may be used when - * creating a foreign texture. E.g. OpenGL supports ARB_texture_rectangle - * but GLES doesn't - */ -gboolean -_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target); - -/* - * glGenerateMipmap semantics may need to be emulated for some drivers. E.g. by - * enabling auto mipmap generation an re-loading a number of known texels. - */ -void -_cogl_texture_driver_gl_generate_mipmaps (GLenum texture_target); - -/* - * The driver may impose constraints on what formats can be used to store - * texture data read from textures. For example GLES currently only supports - * RGBA_8888, and so we need to manually convert the data if the final - * destination has another format. - */ -CoglPixelFormat -_cogl_texture_driver_find_best_gl_get_data_format ( - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type); - -#endif /* __COGL_TEXTURE_DRIVER_H */ - diff --git a/clutter/cogl/cogl/cogl-texture-private.h b/clutter/cogl/cogl/cogl-texture-private.h deleted file mode 100644 index 57093cb..0000000 --- a/clutter/cogl/cogl/cogl-texture-private.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_TEXTURE_PRIVATE_H -#define __COGL_TEXTURE_PRIVATE_H - -#include "cogl-bitmap-private.h" -#include "cogl-handle.h" -#include "cogl-pipeline-private.h" - -#define COGL_TEXTURE(tex) ((CoglTexture *)(tex)) - -typedef struct _CoglTexture CoglTexture; -typedef struct _CoglTextureVtable CoglTextureVtable; - -typedef void (*CoglTextureSliceCallback) (CoglHandle handle, - const float *slice_coords, - const float *virtual_coords, - void *user_data); - -typedef void (* CoglTextureManualRepeatCallback) (const float *coords, - void *user_data); - -/* Encodes three possibiloities result of transforming a quad */ -typedef enum { - /* quad doesn't cross the boundaries of a texture */ - COGL_TRANSFORM_NO_REPEAT, - /* quad crosses boundaries, hardware wrap mode can handle */ - COGL_TRANSFORM_HARDWARE_REPEAT, - /* quad crosses boundaries, needs software fallback; - * for a sliced texture, this might not actually involve - * repeating, just a quad crossing multiple slices */ - COGL_TRANSFORM_SOFTWARE_REPEAT, -} CoglTransformResult; - -/* Flags given to the pre_paint method */ -typedef enum { - /* The texture is going to be used with filters that require - mipmapping. This gives the texture the opportunity to - automatically update the mipmap tree */ - COGL_TEXTURE_NEEDS_MIPMAP = 1 -} CoglTexturePrePaintFlags; - -struct _CoglTextureVtable -{ - /* Virtual functions that must be implemented for a texture - backend */ - - /* This should update the specified sub region of the texture with a - sub region of the given bitmap. The bitmap will have first been - converted to a suitable format for uploading if neccessary. */ - gboolean (* set_region) (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bitmap); - - /* This should copy the image data of the texture into @data. The - requested format will have been first passed through - _cogl_texture_driver_find_best_gl_get_data_format so it should - always be a format that is valid for GL (ie, no conversion should - be necessary). */ - gboolean (* get_data) (CoglTexture *tex, - CoglPixelFormat format, - unsigned int rowstride, - guint8 *data); - - void (* foreach_sub_texture_in_region) (CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data); - - int (* get_max_waste) (CoglTexture *tex); - - gboolean (* is_sliced) (CoglTexture *tex); - - gboolean (* can_hardware_repeat) (CoglTexture *tex); - - void (* transform_coords_to_gl) (CoglTexture *tex, - float *s, - float *t); - CoglTransformResult (* transform_quad_coords_to_gl) (CoglTexture *tex, - float *coords); - - gboolean (* get_gl_texture) (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target); - - void (* set_filters) (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter); - - void (* pre_paint) (CoglTexture *tex, CoglTexturePrePaintFlags flags); - void (* ensure_non_quad_rendering) (CoglTexture *tex); - - void (* set_wrap_mode_parameters) (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p); - - CoglPixelFormat (* get_format) (CoglTexture *tex); - GLenum (* get_gl_format) (CoglTexture *tex); - int (* get_width) (CoglTexture *tex); - int (* get_height) (CoglTexture *tex); - - gboolean (* is_foreign) (CoglTexture *tex); -}; - -struct _CoglTexture -{ - CoglHandleObject _parent; - GList *framebuffers; - const CoglTextureVtable *vtable; -}; - -typedef enum _CoglTextureChangeFlags -{ - /* Whenever the internals of a texture are changed such that the - * underlying GL textures that represent the CoglTexture change then - * we notify cogl-material.c via - * _cogl_pipeline_texture_pre_change_notify - */ - COGL_TEXTURE_CHANGE_GL_TEXTURES - -} CoglTextureChangeFlags; - -typedef struct _CoglTexturePixel CoglTexturePixel; - -/* This is used by the texture backends to store the first pixel of - each GL texture. This is only used when glGenerateMipmap is not - available so that we can temporarily set GL_GENERATE_MIPMAP and - reupload a pixel */ -struct _CoglTexturePixel -{ - /* We need to store the format of the pixel because we store the - data in the source format which might end up being different for - each slice if a subregion is updated with a different format */ - GLenum gl_format; - GLenum gl_type; - guint8 data[4]; -}; - -void -_cogl_texture_init (CoglTexture *texture, - const CoglTextureVtable *vtable); - -void -_cogl_texture_free (CoglTexture *texture); - -/* This is used to register a type to the list of handle types that - will be considered a texture in cogl_is_texture() */ -void -_cogl_texture_register_texture_type (GQuark type); - -#define COGL_TEXTURE_DEFINE(TypeName, type_name) \ - COGL_HANDLE_DEFINE_WITH_CODE \ - (TypeName, type_name, \ - _cogl_texture_register_texture_type (_cogl_handle_ \ - ## type_name ## _get_type ())) - -#define COGL_TEXTURE_INTERNAL_DEFINE(TypeName, type_name) \ - COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE \ - (TypeName, type_name, \ - _cogl_texture_register_texture_type (_cogl_handle_ \ - ## type_name ## _get_type ())) - -void -_cogl_texture_foreach_sub_texture_in_region (CoglHandle handle, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data); - -gboolean -_cogl_texture_can_hardware_repeat (CoglHandle handle); - -void -_cogl_texture_transform_coords_to_gl (CoglHandle handle, - float *s, - float *t); -CoglTransformResult -_cogl_texture_transform_quad_coords_to_gl (CoglHandle handle, - float *coords); - -GLenum -_cogl_texture_get_gl_format (CoglHandle handle); - -void -_cogl_texture_set_wrap_mode_parameters (CoglHandle handle, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p); - - -void -_cogl_texture_set_filters (CoglHandle handle, - GLenum min_filter, - GLenum mag_filter); - -void -_cogl_texture_pre_paint (CoglHandle handle, CoglTexturePrePaintFlags flags); - -void -_cogl_texture_ensure_non_quad_rendering (CoglHandle handle); - -/* Utility function to determine which pixel format to use when - dst_format is COGL_PIXEL_FORMAT_ANY. If dst_format is not ANY then - it will just be returned directly */ -CoglPixelFormat -_cogl_texture_determine_internal_format (CoglPixelFormat src_format, - CoglPixelFormat dst_format); - -/* Utility function to help uploading a bitmap. If the bitmap needs - premult conversion then it will be copied and *copied_bitmap will - be set to TRUE. Otherwise dst_bmp will be set to a shallow copy of - src_bmp. The GLenums needed for uploading are returned */ - -CoglBitmap * -_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp, - CoglPixelFormat dst_format, - CoglPixelFormat *dst_format_out, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype); - -void -_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride); - -void -_cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride); - -/* Utility function for implementing manual repeating. Even texture - backends that always support hardware repeating need this because - when foreach_sub_texture_in_region is invoked Cogl will set the - wrap mode to GL_CLAMP_TO_EDGE so hardware repeating can't be - done */ -void -_cogl_texture_iterate_manual_repeats (CoglTextureManualRepeatCallback callback, - float tx_1, float ty_1, - float tx_2, float ty_2, - void *user_data); - -/* Utility function to use as a fallback for getting the data of any - texture via the framebuffer */ - -gboolean -_cogl_texture_draw_and_read (CoglHandle handle, - CoglBitmap *target_bmp, - GLuint target_gl_format, - GLuint target_gl_type); - -gboolean -_cogl_texture_is_foreign (CoglHandle handle); - -gboolean -_cogl_texture_set_region_from_bitmap (CoglHandle handle, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp); - -void -_cogl_texture_associate_framebuffer (CoglHandle handle, - CoglFramebuffer *framebuffer); - -const GList * -_cogl_texture_get_associated_framebuffers (CoglHandle handle); - -void -_cogl_texture_flush_journal_rendering (CoglHandle handle); - -#endif /* __COGL_TEXTURE_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-texture-rectangle-private.h b/clutter/cogl/cogl/cogl-texture-rectangle-private.h deleted file mode 100644 index 9a0dca2..0000000 --- a/clutter/cogl/cogl/cogl-texture-rectangle-private.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_TEXTURE_RECTANGLE_H -#define __COGL_TEXTURE_RECTANGLE_H - -#include "cogl-handle.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" - -#define COGL_TEXTURE_RECTANGLE(tex) ((CoglTextureRectangle *) tex) - -typedef struct _CoglTextureRectangle CoglTextureRectangle; - -struct _CoglTextureRectangle -{ - CoglTexture _parent; - - /* The internal format of the GL texture represented as a - CoglPixelFormat */ - CoglPixelFormat format; - /* The internal format of the GL texture represented as a GL enum */ - GLenum gl_format; - /* The texture object number */ - GLuint gl_texture; - int width; - int height; - GLenum min_filter; - GLenum mag_filter; - GLint wrap_mode_s; - GLint wrap_mode_t; - gboolean is_foreign; -}; - -GQuark -_cogl_handle_texture_rectangle_get_type (void); - -CoglHandle -_cogl_texture_rectangle_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -CoglHandle -_cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -CoglHandle -_cogl_texture_rectangle_new_from_foreign (GLuint gl_handle, - GLuint width, - GLuint height, - CoglPixelFormat format); - -#endif /* __COGL_TEXTURE_RECTANGLE_H */ diff --git a/clutter/cogl/cogl/cogl-texture-rectangle.c b/clutter/cogl/cogl/cogl-texture-rectangle.c deleted file mode 100644 index 37bc93d..0000000 --- a/clutter/cogl/cogl/cogl-texture-rectangle.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-texture-rectangle-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" - -#include -#include - -/* These aren't defined under GLES */ -#ifndef GL_TEXTURE_RECTANGLE_ARB -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#endif -#ifndef GL_CLAMP -#define GL_CLAMP 0x2900 -#endif -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812D -#endif - -static void _cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect); - -COGL_TEXTURE_INTERNAL_DEFINE (TextureRectangle, texture_rectangle); - -static const CoglTextureVtable cogl_texture_rectangle_vtable; - -typedef struct _CoglTextureRectangleManualRepeatData -{ - CoglTextureRectangle *tex_rect; - CoglTextureSliceCallback callback; - void *user_data; -} CoglTextureRectangleManualRepeatData; - -static void -_cogl_texture_rectangle_wrap_coords (float t_1, float t_2, - float *out_t_1, float *out_t_2) -{ - float int_part; - - /* Wrap t_1 and t_2 to the range [0,1] */ - - modff (t_1 < t_2 ? t_1 : t_2, &int_part); - t_1 -= int_part; - t_2 -= int_part; - if (cogl_util_float_signbit (int_part)) - { - *out_t_1 = 1.0f + t_1; - *out_t_2 = 1.0f + t_2; - } - else - { - *out_t_1 = t_1; - *out_t_2 = t_2; - } -} - -static void -_cogl_texture_rectangle_manual_repeat_cb (const float *coords, - void *user_data) -{ - CoglTextureRectangleManualRepeatData *data = user_data; - float slice_coords[4]; - - _cogl_texture_rectangle_wrap_coords (coords[0], coords[2], - slice_coords + 0, slice_coords + 2); - _cogl_texture_rectangle_wrap_coords (coords[1], coords[3], - slice_coords + 1, slice_coords + 3); - - slice_coords[0] *= data->tex_rect->width; - slice_coords[1] *= data->tex_rect->height; - slice_coords[2] *= data->tex_rect->width; - slice_coords[3] *= data->tex_rect->height; - - data->callback (COGL_TEXTURE (data->tex_rect), - slice_coords, - coords, - data->user_data); -} - -static void -_cogl_texture_rectangle_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - CoglTextureRectangleManualRepeatData data; - - data.tex_rect = tex_rect; - data.callback = callback; - data.user_data = user_data; - - /* We need to implement manual repeating because if Cogl is calling - this function then it will set the wrap mode to GL_CLAMP_TO_EDGE - and hardware repeating can't be done */ - _cogl_texture_iterate_manual_repeats - (_cogl_texture_rectangle_manual_repeat_cb, - virtual_tx_1, virtual_ty_1, virtual_tx_2, virtual_ty_2, - &data); -} - -static gboolean -can_use_wrap_mode (GLenum wrap_mode) -{ - return (wrap_mode == GL_CLAMP || - wrap_mode == GL_CLAMP_TO_EDGE || - wrap_mode == GL_CLAMP_TO_BORDER); -} - -static void -_cogl_texture_rectangle_set_wrap_mode_parameters (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - - /* Only set the wrap mode if it's different from the current value - to avoid too many GL calls. Texture rectangle doesn't make use of - the r coordinate so we can ignore its wrap mode */ - if (tex_rect->wrap_mode_s != wrap_mode_s || - tex_rect->wrap_mode_t != wrap_mode_t) - { - g_assert (can_use_wrap_mode (wrap_mode_s)); - g_assert (can_use_wrap_mode (wrap_mode_t)); - - GE( _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - tex_rect->is_foreign) ); - GE( glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_WRAP_S, wrap_mode_s) ); - GE( glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_WRAP_T, wrap_mode_t) ); - - tex_rect->wrap_mode_s = wrap_mode_s; - tex_rect->wrap_mode_t = wrap_mode_t; - } -} - -static void -_cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect) -{ - if (!tex_rect->is_foreign) - _cogl_delete_gl_texture (tex_rect->gl_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_rect)); -} - -static gboolean -_cogl_texture_rectangle_can_create (unsigned int width, - unsigned int height, - CoglPixelFormat internal_format) -{ - GLenum gl_intformat; - GLenum gl_type; - - if (!cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE)) - return FALSE; - - _cogl_pixel_format_to_gl (internal_format, - &gl_intformat, - NULL, - &gl_type); - - /* Check that the driver can create a texture with that size */ - if (!_cogl_texture_driver_size_supported (GL_TEXTURE_RECTANGLE_ARB, - gl_intformat, - gl_type, - width, - height)) - return FALSE; - - return TRUE; -} - -static CoglTextureRectangle * -_cogl_texture_rectangle_create_base (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTextureRectangle *tex_rect = g_new (CoglTextureRectangle, 1); - CoglTexture *tex = COGL_TEXTURE (tex_rect); - - _cogl_texture_init (tex, &cogl_texture_rectangle_vtable); - - tex_rect->width = width; - tex_rect->height = height; - - /* We default to GL_LINEAR for both filters */ - tex_rect->min_filter = GL_LINEAR; - tex_rect->mag_filter = GL_LINEAR; - - /* Wrap mode not yet set */ - tex_rect->wrap_mode_s = GL_FALSE; - tex_rect->wrap_mode_t = GL_FALSE; - - tex_rect->format = internal_format; - - return tex_rect; -} - -CoglHandle -_cogl_texture_rectangle_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTextureRectangle *tex_rect; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - /* Since no data, we need some internal format */ - if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - - if (!_cogl_texture_rectangle_can_create (width, height, internal_format)) - return COGL_INVALID_HANDLE; - - internal_format = _cogl_pixel_format_to_gl (internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - tex_rect = _cogl_texture_rectangle_create_base (width, height, flags, - internal_format); - - _cogl_texture_driver_gen (GL_TEXTURE_RECTANGLE_ARB, 1, &tex_rect->gl_texture); - GE( _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - tex_rect->is_foreign) ); - GE( glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat, - width, height, 0, gl_format, gl_type, NULL) ); - - return _cogl_texture_rectangle_handle_new (tex_rect); -} - -CoglHandle -_cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTextureRectangle *tex_rect; - CoglBitmap *dst_bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - g_return_val_if_fail (cogl_is_bitmap (bmp), COGL_INVALID_HANDLE); - - internal_format = - _cogl_texture_determine_internal_format (_cogl_bitmap_get_format (bmp), - internal_format); - - if (!_cogl_texture_rectangle_can_create (_cogl_bitmap_get_width (bmp), - _cogl_bitmap_get_height (bmp), - internal_format)) - return COGL_INVALID_HANDLE; - - dst_bmp = _cogl_texture_prepare_for_upload (bmp, - internal_format, - &internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - if (dst_bmp == NULL) - return COGL_INVALID_HANDLE; - - tex_rect = _cogl_texture_rectangle_create_base (_cogl_bitmap_get_width (bmp), - _cogl_bitmap_get_height (bmp), - flags, - internal_format); - - _cogl_texture_driver_gen (GL_TEXTURE_RECTANGLE_ARB, 1, &tex_rect->gl_texture); - _cogl_texture_driver_upload_to_gl (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - FALSE, - dst_bmp, - gl_intformat, - gl_format, - gl_type); - - tex_rect->gl_format = gl_intformat; - - cogl_object_unref (dst_bmp); - - return _cogl_texture_rectangle_handle_new (tex_rect); -} - -CoglHandle -_cogl_texture_rectangle_new_from_foreign (GLuint gl_handle, - GLuint width, - GLuint height, - CoglPixelFormat format) -{ - /* NOTE: width, height and internal format are not queriable - * in GLES, hence such a function prototype. - */ - - GLenum gl_error = 0; - GLint gl_compressed = GL_FALSE; - GLenum gl_int_format = 0; - CoglTextureRectangle *tex_rect; - - if (!_cogl_texture_driver_allows_foreign_gl_target (GL_TEXTURE_RECTANGLE_ARB)) - return COGL_INVALID_HANDLE; - - /* Make sure it is a valid GL texture object */ - if (!glIsTexture (gl_handle)) - return COGL_INVALID_HANDLE; - - /* Make sure binding succeeds */ - while ((gl_error = glGetError ()) != GL_NO_ERROR) - ; - - _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, gl_handle, TRUE); - if (glGetError () != GL_NO_ERROR) - return COGL_INVALID_HANDLE; - - /* Obtain texture parameters */ - -#if HAVE_COGL_GL - - GE( glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0, - GL_TEXTURE_COMPRESSED, - &gl_compressed) ); - - { - GLint val; - - GE( glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0, - GL_TEXTURE_INTERNAL_FORMAT, - &val) ); - - gl_int_format = val; - } - - /* If we can query GL for the actual pixel format then we'll ignore - the passed in format and use that. */ - if (!_cogl_pixel_format_from_gl_internal (gl_int_format, &format)) - return COGL_INVALID_HANDLE; - -#else - - /* Otherwise we'll assume we can derive the GL format from the - passed in format */ - _cogl_pixel_format_to_gl (format, - &gl_int_format, - NULL, - NULL); - -#endif - - /* Note: We always trust the given width and height without querying - * the texture object because the user may be creating a Cogl - * texture for a texture_from_pixmap object where glTexImage2D may - * not have been called and the texture_from_pixmap spec doesn't - * clarify that it is reliable to query back the size from OpenGL. - */ - - /* Validate width and height */ - if (width <= 0 || height <= 0) - return COGL_INVALID_HANDLE; - - /* Compressed texture images not supported */ - if (gl_compressed == GL_TRUE) - return COGL_INVALID_HANDLE; - - /* Create new texture */ - tex_rect = _cogl_texture_rectangle_create_base (width, height, - COGL_TEXTURE_NO_AUTO_MIPMAP, - format); - - /* Setup bitmap info */ - tex_rect->is_foreign = TRUE; - - tex_rect->format = format; - - tex_rect->gl_texture = gl_handle; - tex_rect->gl_format = gl_int_format; - - /* Unknown filter */ - tex_rect->min_filter = GL_FALSE; - tex_rect->mag_filter = GL_FALSE; - - return _cogl_texture_rectangle_handle_new (tex_rect); -} - -static int -_cogl_texture_rectangle_get_max_waste (CoglTexture *tex) -{ - return -1; -} - -static gboolean -_cogl_texture_rectangle_is_sliced (CoglTexture *tex) -{ - return FALSE; -} - -static gboolean -_cogl_texture_rectangle_can_hardware_repeat (CoglTexture *tex) -{ - return FALSE; -} - -static void -_cogl_texture_rectangle_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - - *s *= tex_rect->width; - *t *= tex_rect->height; -} - -static CoglTransformResult -_cogl_texture_rectangle_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - gboolean need_repeat = FALSE; - int i; - - for (i = 0; i < 4; i++) - { - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - coords[i] *= (i & 1) ? tex_rect->height : tex_rect->width; - } - - return (need_repeat ? COGL_TRANSFORM_SOFTWARE_REPEAT - : COGL_TRANSFORM_NO_REPEAT); -} - -static gboolean -_cogl_texture_rectangle_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - - if (out_gl_handle) - *out_gl_handle = tex_rect->gl_texture; - - if (out_gl_target) - *out_gl_target = GL_TEXTURE_RECTANGLE_ARB; - - return TRUE; -} - -static void -_cogl_texture_rectangle_set_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - - if (min_filter == tex_rect->min_filter - && mag_filter == tex_rect->mag_filter) - return; - - /* Rectangle textures don't support mipmapping */ - g_assert (min_filter == GL_LINEAR || min_filter == GL_NEAREST); - - /* Store new values */ - tex_rect->min_filter = min_filter; - tex_rect->mag_filter = mag_filter; - - /* Apply new filters to the texture */ - GE( _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - tex_rect->is_foreign) ); - GE( glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, - mag_filter) ); - GE( glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, - min_filter) ); -} - -static void -_cogl_texture_rectangle_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Rectangle textures don't support mipmaps */ - g_assert ((flags & COGL_TEXTURE_NEEDS_MIPMAP) == 0); -} - -static void -_cogl_texture_rectangle_ensure_non_quad_rendering (CoglTexture *tex) -{ - /* Nothing needs to be done */ -} - -static gboolean -_cogl_texture_rectangle_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - GLenum gl_format; - GLenum gl_type; - - _cogl_pixel_format_to_gl (_cogl_bitmap_get_format (bmp), - NULL, /* internal format */ - &gl_format, - &gl_type); - - /* Send data to GL */ - _cogl_texture_driver_upload_subregion_to_gl (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - FALSE, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - bmp, - gl_format, - gl_type); - - return TRUE; -} - -static gboolean -_cogl_texture_rectangle_get_data (CoglTexture *tex, - CoglPixelFormat format, - unsigned int rowstride, - guint8 *data) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - int bpp; - GLenum gl_format; - GLenum gl_type; - - bpp = _cogl_get_format_bpp (format); - - _cogl_pixel_format_to_gl (format, - NULL, /* internal format */ - &gl_format, - &gl_type); - - _cogl_texture_driver_prep_gl_for_pixels_download (rowstride, bpp); - - GE( _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - tex_rect->is_foreign) ); - return _cogl_texture_driver_gl_get_tex_image (GL_TEXTURE_RECTANGLE_ARB, - gl_format, - gl_type, - data); -} - -static CoglPixelFormat -_cogl_texture_rectangle_get_format (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->format; -} - -static GLenum -_cogl_texture_rectangle_get_gl_format (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->gl_format; -} - -static int -_cogl_texture_rectangle_get_width (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->width; -} - -static int -_cogl_texture_rectangle_get_height (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->height; -} - -static gboolean -_cogl_texture_rectangle_is_foreign (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->is_foreign; -} - -static const CoglTextureVtable -cogl_texture_rectangle_vtable = - { - _cogl_texture_rectangle_set_region, - _cogl_texture_rectangle_get_data, - _cogl_texture_rectangle_foreach_sub_texture_in_region, - _cogl_texture_rectangle_get_max_waste, - _cogl_texture_rectangle_is_sliced, - _cogl_texture_rectangle_can_hardware_repeat, - _cogl_texture_rectangle_transform_coords_to_gl, - _cogl_texture_rectangle_transform_quad_coords_to_gl, - _cogl_texture_rectangle_get_gl_texture, - _cogl_texture_rectangle_set_filters, - _cogl_texture_rectangle_pre_paint, - _cogl_texture_rectangle_ensure_non_quad_rendering, - _cogl_texture_rectangle_set_wrap_mode_parameters, - _cogl_texture_rectangle_get_format, - _cogl_texture_rectangle_get_gl_format, - _cogl_texture_rectangle_get_width, - _cogl_texture_rectangle_get_height, - _cogl_texture_rectangle_is_foreign - }; diff --git a/clutter/cogl/cogl/cogl-texture.c b/clutter/cogl/cogl/cogl-texture.c deleted file mode 100644 index 4bf58ae..0000000 --- a/clutter/cogl/cogl/cogl-texture.c +++ /dev/null @@ -1,1533 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * Copyright (C) 2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-buffer-private.h" -#include "cogl-pixel-array-private.h" -#include "cogl-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-driver.h" -#include "cogl-texture-2d-sliced-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-rectangle-private.h" -#include "cogl-sub-texture-private.h" -#include "cogl-atlas-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-object-private.h" -#include "cogl-primitives.h" -#include "cogl-framebuffer-private.h" - -#include -#include -#include - -/* XXX: - * The CoglHandle macros don't support any form of inheritance, so for - * now we implement the CoglHandle support for the CoglTexture - * abstract class manually. - */ - -void -_cogl_texture_register_texture_type (GQuark type) -{ - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - ctxt->texture_types = g_slist_prepend (ctxt->texture_types, - GINT_TO_POINTER (type)); -} - -gboolean -cogl_is_texture (CoglHandle handle) -{ - CoglHandleObject *obj = (CoglHandleObject *)handle; - GSList *l; - - _COGL_GET_CONTEXT (ctxt, FALSE); - - if (handle == COGL_INVALID_HANDLE) - return FALSE; - - for (l = ctxt->texture_types; l; l = l->next) - if (GPOINTER_TO_INT (l->data) == obj->klass->type) - return TRUE; - - return FALSE; -} - -CoglHandle -cogl_texture_ref (CoglHandle handle) -{ - if (!cogl_is_texture (handle)) - return COGL_INVALID_HANDLE; - - _COGL_HANDLE_DEBUG_REF (CoglTexture, handle); - - cogl_handle_ref (handle); - - return handle; -} - -void -cogl_texture_unref (CoglHandle handle) -{ - if (!cogl_is_texture (handle)) - { - g_warning (G_STRINGIFY (cogl_texture_unref) - ": Ignoring unref of Cogl handle " - "due to type mismatch"); - return; - } - - _COGL_HANDLE_DEBUG_UNREF (CoglTexture, handle); - - cogl_handle_unref (handle); -} - -void -_cogl_texture_init (CoglTexture *texture, - const CoglTextureVtable *vtable) -{ - texture->vtable = vtable; - texture->framebuffers = NULL; -} - -void -_cogl_texture_free (CoglTexture *texture) -{ - g_free (texture); -} - -static gboolean -_cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, - CoglPixelFormat dst_format) -{ - return ((src_format & dst_format & COGL_A_BIT) && - src_format != COGL_PIXEL_FORMAT_A_8 && - dst_format != COGL_PIXEL_FORMAT_A_8 && - (src_format & COGL_PREMULT_BIT) != - (dst_format & COGL_PREMULT_BIT)); -} - -CoglPixelFormat -_cogl_texture_determine_internal_format (CoglPixelFormat src_format, - CoglPixelFormat dst_format) -{ - /* If the application hasn't specified a specific format then we'll - * pick the most appropriate. By default Cogl will use a - * premultiplied internal format. Later we will add control over - * this. */ - if (dst_format == COGL_PIXEL_FORMAT_ANY) - { - if ((src_format & COGL_A_BIT) && - src_format != COGL_PIXEL_FORMAT_A_8) - return src_format | COGL_PREMULT_BIT; - else - return src_format; - } - else - return dst_format; -} - -CoglBitmap * -_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp, - CoglPixelFormat dst_format, - CoglPixelFormat *dst_format_out, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - CoglPixelFormat src_format = _cogl_bitmap_get_format (src_bmp); - CoglBitmap *dst_bmp; - - dst_format = _cogl_texture_determine_internal_format (src_format, - dst_format); - - /* OpenGL supports specifying a different format for the internal - format when uploading texture data. We should use this to convert - formats because it is likely to be faster and support more types - than the Cogl bitmap code. However under GLES the internal format - must be the same as the bitmap format and it only supports a - limited number of formats so we must convert using the Cogl - bitmap code instead */ - -#ifdef HAVE_COGL_GL - - /* If the source format does not have the same premult flag as the - dst format then we need to copy and convert it */ - if (_cogl_texture_needs_premult_conversion (src_format, - dst_format)) - { - dst_bmp = _cogl_bitmap_copy (src_bmp); - - if (!_cogl_bitmap_convert_premult_status (dst_bmp, - src_format ^ - COGL_PREMULT_BIT)) - { - cogl_object_unref (dst_bmp); - return NULL; - } - } - else - dst_bmp = cogl_object_ref (src_bmp); - - /* Use the source format from the src bitmap type and the internal - format from the dst format type so that GL can do the - conversion */ - _cogl_pixel_format_to_gl (src_format, - NULL, /* internal format */ - out_glformat, - out_gltype); - _cogl_pixel_format_to_gl (dst_format, - out_glintformat, - NULL, - NULL); - -#else /* HAVE_COGL_GL */ - { - CoglPixelFormat closest_format; - - closest_format = _cogl_pixel_format_to_gl (dst_format, - out_glintformat, - out_glformat, - out_gltype); - - if (closest_format != src_format) - dst_bmp = _cogl_bitmap_convert_format_and_premult (src_bmp, - closest_format); - else - dst_bmp = cogl_object_ref (src_bmp); - } -#endif /* HAVE_COGL_GL */ - - if (dst_format_out) - *dst_format_out = dst_format; - - return dst_bmp; -} - -void -_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride) -{ - if (!(pixels_rowstride & 0x7)) - GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 8) ); - else if (!(pixels_rowstride & 0x3)) - GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 4) ); - else if (!(pixels_rowstride & 0x1)) - GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 2) ); - else - GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 1) ); -} - -void -_cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride) -{ - if (!(pixels_rowstride & 0x7)) - GE( glPixelStorei (GL_PACK_ALIGNMENT, 8) ); - else if (!(pixels_rowstride & 0x3)) - GE( glPixelStorei (GL_PACK_ALIGNMENT, 4) ); - else if (!(pixels_rowstride & 0x1)) - GE( glPixelStorei (GL_PACK_ALIGNMENT, 2) ); - else - GE( glPixelStorei (GL_PACK_ALIGNMENT, 1) ); -} - -/* FIXME: wrap modes should be set on pipelines not textures */ -void -_cogl_texture_set_wrap_mode_parameters (CoglHandle handle, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - - tex->vtable->set_wrap_mode_parameters (tex, - wrap_mode_s, - wrap_mode_t, - wrap_mode_p); -} - -/* This is like CoglSpanIter except it deals with floats and it - effectively assumes there is only one span from 0.0 to 1.0 */ -typedef struct _CoglTextureIter -{ - float pos, end, next_pos; - gboolean flipped; - float t_1, t_2; -} CoglTextureIter; - -static void -_cogl_texture_iter_update (CoglTextureIter *iter) -{ - float t_2; - float frac_part; - - frac_part = modff (iter->pos, &iter->next_pos); - - /* modff rounds the int part towards zero so we need to add one if - we're meant to be heading away from zero */ - if (iter->pos >= 0.0f || frac_part == 0.0f) - iter->next_pos += 1.0f; - - if (iter->next_pos > iter->end) - t_2 = iter->end; - else - t_2 = iter->next_pos; - - if (iter->flipped) - { - iter->t_1 = t_2; - iter->t_2 = iter->pos; - } - else - { - iter->t_1 = iter->pos; - iter->t_2 = t_2; - } -} - -static void -_cogl_texture_iter_begin (CoglTextureIter *iter, - float t_1, float t_2) -{ - if (t_1 <= t_2) - { - iter->pos = t_1; - iter->end = t_2; - iter->flipped = FALSE; - } - else - { - iter->pos = t_2; - iter->end = t_1; - iter->flipped = TRUE; - } - - _cogl_texture_iter_update (iter); -} - -static void -_cogl_texture_iter_next (CoglTextureIter *iter) -{ - iter->pos = iter->next_pos; - _cogl_texture_iter_update (iter); -} - -static gboolean -_cogl_texture_iter_end (CoglTextureIter *iter) -{ - return iter->pos >= iter->end; -} - -/* This invokes the callback with enough quads to cover the manually - repeated range specified by the virtual texture coordinates without - emitting coordinates outside the range [0,1] */ -void -_cogl_texture_iterate_manual_repeats (CoglTextureManualRepeatCallback callback, - float tx_1, float ty_1, - float tx_2, float ty_2, - void *user_data) -{ - CoglTextureIter x_iter, y_iter; - - for (_cogl_texture_iter_begin (&y_iter, ty_1, ty_2); - !_cogl_texture_iter_end (&y_iter); - _cogl_texture_iter_next (&y_iter)) - for (_cogl_texture_iter_begin (&x_iter, tx_1, tx_2); - !_cogl_texture_iter_end (&x_iter); - _cogl_texture_iter_next (&x_iter)) - { - float coords[4] = { x_iter.t_1, y_iter.t_1, x_iter.t_2, y_iter.t_2 }; - callback (coords, user_data); - } -} - -CoglHandle -cogl_texture_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglHandle tex; - - /* First try creating a fast-path non-sliced texture */ - tex = _cogl_texture_2d_new_with_size (width, height, flags, internal_format); - - /* If it fails resort to sliced textures */ - if (tex == COGL_INVALID_HANDLE) - tex = _cogl_texture_2d_sliced_new_with_size (width, - height, - flags, - internal_format); - - return tex; -} - -CoglHandle -cogl_texture_new_from_data (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - unsigned int rowstride, - const guint8 *data) -{ - CoglBitmap *bmp; - CoglHandle tex; - - if (format == COGL_PIXEL_FORMAT_ANY) - return COGL_INVALID_HANDLE; - - if (data == NULL) - return COGL_INVALID_HANDLE; - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * _cogl_get_format_bpp (format); - - /* Wrap the data into a bitmap */ - bmp = _cogl_bitmap_new_from_data ((guint8 *) data, - format, - width, - height, - rowstride, - NULL, NULL); - - tex = cogl_texture_new_from_bitmap (bmp, flags, internal_format); - - cogl_object_unref (bmp); - - return tex; -} - -CoglHandle -cogl_texture_new_from_bitmap (CoglHandle bmp_handle, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglHandle tex; - - /* First try putting the texture in the atlas */ - if ((tex = _cogl_atlas_texture_new_from_bitmap (bmp_handle, - flags, - internal_format))) - return tex; - - /* If that doesn't work try a fast path 2D texture */ - if ((tex = _cogl_texture_2d_new_from_bitmap (bmp_handle, - flags, - internal_format))) - return tex; - - /* Otherwise create a sliced texture */ - return _cogl_texture_2d_sliced_new_from_bitmap (bmp_handle, - flags, - internal_format); -} - -CoglHandle -cogl_texture_new_from_file (const char *filename, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error) -{ - CoglBitmap *bmp; - CoglHandle handle = COGL_INVALID_HANDLE; - CoglPixelFormat src_format; - - g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE); - - bmp = cogl_bitmap_new_from_file (filename, error); - if (bmp == NULL) - return COGL_INVALID_HANDLE; - - src_format = _cogl_bitmap_get_format (bmp); - - /* We know that the bitmap data is solely owned by this function so - we can do the premult conversion in place. This avoids having to - copy the bitmap which will otherwise happen in - _cogl_texture_prepare_for_upload */ - internal_format = - _cogl_texture_determine_internal_format (src_format, internal_format); - if (!_cogl_texture_needs_premult_conversion (src_format, internal_format) || - _cogl_bitmap_convert_premult_status (bmp, src_format ^ COGL_PREMULT_BIT)) - handle = cogl_texture_new_from_bitmap (bmp, flags, internal_format); - - cogl_object_unref (bmp); - - return handle; -} - -CoglHandle -cogl_texture_new_from_foreign (GLuint gl_handle, - GLenum gl_target, - GLuint width, - GLuint height, - GLuint x_pot_waste, - GLuint y_pot_waste, - CoglPixelFormat format) -{ -#if HAVE_COGL_GL - if (gl_target == GL_TEXTURE_RECTANGLE_ARB) - { - if (x_pot_waste != 0 || y_pot_waste != 0) - { - /* It shouldn't be necessary to have waste in this case since - * the texture isn't limited to power of two sizes. */ - g_warning ("You can't create a foreign GL_TEXTURE_RECTANGLE cogl " - "texture with waste\n"); - return COGL_INVALID_HANDLE; - } - - return _cogl_texture_rectangle_new_from_foreign (gl_handle, - width, - height, - format); - } -#endif - - if (x_pot_waste != 0 || y_pot_waste != 0) - return _cogl_texture_2d_sliced_new_from_foreign (gl_handle, - gl_target, - width, - height, - x_pot_waste, - y_pot_waste, - format); - else - return _cogl_texture_2d_new_from_foreign (gl_handle, - width, - height, - format); -} - -gboolean -_cogl_texture_is_foreign (CoglHandle handle) -{ - CoglTexture *tex; - - g_return_val_if_fail (cogl_is_texture (handle), FALSE); - - tex = COGL_TEXTURE (handle); - - if (tex->vtable->is_foreign) - return tex->vtable->is_foreign (tex); - else - return FALSE; -} - -CoglHandle -cogl_texture_new_from_sub_texture (CoglHandle full_texture, - int sub_x, - int sub_y, - int sub_width, - int sub_height) -{ - return _cogl_sub_texture_new (full_texture, sub_x, sub_y, - sub_width, sub_height); -} - -CoglHandle -cogl_texture_new_from_buffer_EXP (CoglHandle buffer, - unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - unsigned int rowstride, - const unsigned int offset) -{ - CoglHandle texture; - CoglBuffer *cogl_buffer; - CoglPixelArray *pixel_array; - CoglBitmap *bmp; - - g_return_val_if_fail (cogl_is_buffer (buffer), COGL_INVALID_HANDLE); - - if (format == COGL_PIXEL_FORMAT_ANY) - return COGL_INVALID_HANDLE; - - cogl_buffer = COGL_BUFFER (buffer); - pixel_array = COGL_PIXEL_ARRAY (buffer); - - /* Rowstride from CoglBuffer or even width * bpp if not given */ - if (rowstride == 0) - rowstride = pixel_array->stride; - if (rowstride == 0) - rowstride = width * _cogl_get_format_bpp (format); - - /* use the CoglBuffer height and width as last resort */ - if (width == 0) - width = pixel_array->width; - if (height == 0) - height = pixel_array->height; - if (width == 0 || height == 0) - { - /* no width or height specified, neither at creation time (because the - * array was created by cogl_pixel_array_new()) nor when calling this - * function */ - return COGL_INVALID_HANDLE; - } - - /* Wrap the buffer into a bitmap */ - bmp = _cogl_bitmap_new_from_buffer (cogl_buffer, - format, - width, height, - rowstride, - offset); - - texture = cogl_texture_new_from_bitmap (bmp, flags, internal_format); - - cogl_object_unref (bmp); - - return texture; -} - -unsigned int -cogl_texture_get_width (CoglHandle handle) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return 0; - - tex = COGL_TEXTURE (handle); - - return tex->vtable->get_width (tex); -} - -unsigned int -cogl_texture_get_height (CoglHandle handle) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return 0; - - tex = COGL_TEXTURE (handle); - - return tex->vtable->get_height (tex); -} - -CoglPixelFormat -cogl_texture_get_format (CoglHandle handle) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return COGL_PIXEL_FORMAT_ANY; - - tex = COGL_TEXTURE (handle); - - return tex->vtable->get_format (tex); -} - -unsigned int -cogl_texture_get_rowstride (CoglHandle handle) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return 0; - - /* FIXME: This function should go away. It previously just returned - the rowstride that was used to upload the data as far as I can - tell. This is not helpful */ - - tex = COGL_TEXTURE (handle); - - /* Just guess at a suitable rowstride */ - return (_cogl_get_format_bpp (cogl_texture_get_format (tex)) - * cogl_texture_get_width (tex)); -} - -int -cogl_texture_get_max_waste (CoglHandle handle) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return 0; - - tex = COGL_TEXTURE (handle); - - return tex->vtable->get_max_waste (tex); -} - -gboolean -cogl_texture_is_sliced (CoglHandle handle) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return FALSE; - - tex = COGL_TEXTURE (handle); - - return tex->vtable->is_sliced (tex); -} - -/* Some CoglTextures, notably sliced textures or atlas textures when repeating - * is used, will need to divide the coordinate space into multiple GL textures - * (or rather; in the case of atlases duplicate a single texture in multiple - * positions to handle repeating) - * - * This function helps you implement primitives using such textures by - * invoking a callback once for each sub texture that intersects a given - * region specified in texture coordinates. - */ -void -_cogl_texture_foreach_sub_texture_in_region (CoglHandle handle, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - - tex->vtable->foreach_sub_texture_in_region (tex, - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - callback, - user_data); -} - -/* If this returns FALSE, that implies _foreach_sub_texture_in_region - * will be needed to iterate over multiple sub textures for regions whos - * texture coordinates extend out of the range [0,1] - */ -gboolean -_cogl_texture_can_hardware_repeat (CoglHandle handle) -{ - CoglTexture *tex = (CoglTexture *)handle; - - return tex->vtable->can_hardware_repeat (tex); -} - -/* NB: You can't use this with textures comprised of multiple sub textures (use - * cogl_texture_is_sliced() to check) since coordinate transformation for such - * textures will be different for each slice. */ -void -_cogl_texture_transform_coords_to_gl (CoglHandle handle, - float *s, - float *t) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - - tex->vtable->transform_coords_to_gl (tex, s, t); -} - -CoglTransformResult -_cogl_texture_transform_quad_coords_to_gl (CoglHandle handle, - float *coords) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - - return tex->vtable->transform_quad_coords_to_gl (tex, coords); -} - -GLenum -_cogl_texture_get_gl_format (CoglHandle handle) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - - return tex->vtable->get_gl_format (tex); -} - -gboolean -cogl_texture_get_gl_texture (CoglHandle handle, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return FALSE; - - tex = COGL_TEXTURE (handle); - - return tex->vtable->get_gl_texture (tex, out_gl_handle, out_gl_target); -} - -void -_cogl_texture_set_filters (CoglHandle handle, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return; - - tex = COGL_TEXTURE (handle); - - tex->vtable->set_filters (tex, min_filter, mag_filter); -} - -void -_cogl_texture_pre_paint (CoglHandle handle, CoglTexturePrePaintFlags flags) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return; - - tex = COGL_TEXTURE (handle); - - tex->vtable->pre_paint (tex, flags); -} - -void -_cogl_texture_ensure_non_quad_rendering (CoglHandle handle) -{ - CoglTexture *tex; - - if (!cogl_is_texture (handle)) - return; - - tex = COGL_TEXTURE (handle); - - tex->vtable->ensure_non_quad_rendering (tex); -} - -gboolean -_cogl_texture_set_region_from_bitmap (CoglHandle handle, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - GLenum closest_gl_format; - GLenum closest_gl_type; - gboolean ret; - - /* Shortcut out early if the image is empty */ - if (dst_width == 0 || dst_height == 0) - return TRUE; - - /* Prepare the bitmap so that it will do the premultiplication - conversion */ - bmp = _cogl_texture_prepare_for_upload (bmp, - cogl_texture_get_format (handle), - NULL, - NULL, - &closest_gl_format, - &closest_gl_type); - - ret = tex->vtable->set_region (handle, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - bmp); - - cogl_object_unref (bmp); - - return ret; -} - -gboolean -cogl_texture_set_region (CoglHandle handle, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - int width, - int height, - CoglPixelFormat format, - unsigned int rowstride, - const guint8 *data) -{ - CoglBitmap *source_bmp; - gboolean ret; - - /* Check for valid format */ - if (format == COGL_PIXEL_FORMAT_ANY) - return FALSE; - - /* Rowstride from width if none specified */ - if (rowstride == 0) - rowstride = _cogl_get_format_bpp (format) * width; - - /* Init source bitmap */ - source_bmp = _cogl_bitmap_new_from_data ((guint8 *) data, - format, - width, - height, - rowstride, - NULL, /* destroy_fn */ - NULL); /* destroy_fn_data */ - - ret = _cogl_texture_set_region_from_bitmap (handle, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - source_bmp); - - cogl_object_unref (source_bmp); - - return ret; -} - -/* Reads back the contents of a texture by rendering it to the framebuffer - * and reading back the resulting pixels. - * - * It will perform multiple renders if the texture is larger than the - * current glViewport. - * - * It assumes the projection and modelview have already been setup so - * that rendering to 0,0 with the same width and height of the viewport - * will exactly cover the viewport. - * - * NB: Normally this approach isn't normally used since we can just use - * glGetTexImage, but may be used as a fallback in some circumstances. - */ -static void -do_texture_draw_and_read (CoglHandle handle, - CoglBitmap *target_bmp, - float *viewport) -{ - int bpp; - float rx1, ry1; - float rx2, ry2; - float tx1, ty1; - float tx2, ty2; - int bw, bh; - CoglBitmap *rect_bmp; - unsigned int tex_width, tex_height; - - bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888); - - tex_width = cogl_texture_get_width (handle); - tex_height = cogl_texture_get_height (handle); - - ry2 = 0; - ty2 = 0; - - /* Walk Y axis until whole bitmap height consumed */ - for (bh = tex_height; bh > 0; bh -= viewport[3]) - { - /* Rectangle Y coords */ - ry1 = ry2; - ry2 += (bh < viewport[3]) ? bh : viewport[3]; - - /* Normalized texture Y coords */ - ty1 = ty2; - ty2 = (ry2 / (float) tex_height); - - rx2 = 0; - tx2 = 0; - - /* Walk X axis until whole bitmap width consumed */ - for (bw = tex_width; bw > 0; bw-=viewport[2]) - { - int width; - int height; - int rowstride; - guint8 *data; - - /* Rectangle X coords */ - rx1 = rx2; - rx2 += (bw < viewport[2]) ? bw : viewport[2]; - - width = rx2 - rx1; - height = ry2 - ry1; - rowstride = width * bpp; - - /* Normalized texture X coords */ - tx1 = tx2; - tx2 = (rx2 / (float) tex_width); - - /* Draw a portion of texture */ - cogl_rectangle_with_texture_coords (0, 0, - rx2 - rx1, - ry2 - ry1, - tx1, ty1, - tx2, ty2); - - data = g_malloc (height * rowstride); - - /* Read into a temporary bitmap */ - rect_bmp = - _cogl_bitmap_new_from_data (data, - COGL_PIXEL_FORMAT_RGBA_8888, - width, - height, - rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); - - cogl_read_pixels (viewport[0], viewport[1], - width, - height, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - data); - - /* Copy to target bitmap */ - _cogl_bitmap_copy_subregion (rect_bmp, - target_bmp, - 0,0, - rx1,ry1, - width, - height); - - /* Free temp bitmap */ - cogl_object_unref (rect_bmp); - } - } -} - -/* Reads back the contents of a texture by rendering it to the framebuffer - * and reading back the resulting pixels. - * - * NB: Normally this approach isn't normally used since we can just use - * glGetTexImage, but may be used as a fallback in some circumstances. - */ -gboolean -_cogl_texture_draw_and_read (CoglHandle handle, - CoglBitmap *target_bmp, - GLuint target_gl_format, - GLuint target_gl_type) -{ - int bpp; - CoglFramebuffer *framebuffer; - float viewport[4]; - CoglBitmap *alpha_bmp; - CoglMatrixStack *projection_stack; - CoglMatrixStack *modelview_stack; - int target_width = _cogl_bitmap_get_width (target_bmp); - int target_height = _cogl_bitmap_get_height (target_bmp); - int target_rowstride = _cogl_bitmap_get_rowstride (target_bmp); - - _COGL_GET_CONTEXT (ctx, FALSE); - - bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888); - - framebuffer = cogl_get_draw_framebuffer (); - /* Viewport needs to have some size and be inside the window for this */ - _cogl_framebuffer_get_viewport4fv (framebuffer, viewport); - if (viewport[0] < 0 || viewport[1] < 0 || - viewport[2] <= 0 || viewport[3] <= 0) - return FALSE; - - /* Setup orthographic projection into current viewport (0,0 in top-left - * corner to draw the texture upside-down so we match the way cogl_read_pixels - * works) - */ - - projection_stack = _cogl_framebuffer_get_projection_stack (framebuffer); - _cogl_matrix_stack_push (projection_stack); - _cogl_matrix_stack_load_identity (projection_stack); - _cogl_matrix_stack_ortho (projection_stack, - 0, viewport[2], - viewport[3], 0, - 0, - 100); - - modelview_stack = _cogl_framebuffer_get_modelview_stack (framebuffer); - _cogl_matrix_stack_push (modelview_stack); - _cogl_matrix_stack_load_identity (modelview_stack); - - /* Direct copy operation */ - - if (ctx->texture_download_pipeline == COGL_INVALID_HANDLE) - { - ctx->texture_download_pipeline = cogl_pipeline_new (); - cogl_pipeline_set_blend (ctx->texture_download_pipeline, - "RGBA = ADD (SRC_COLOR, 0)", - NULL); - } - - cogl_push_source (ctx->texture_download_pipeline); - - cogl_pipeline_set_layer_texture (ctx->texture_download_pipeline, 0, handle); - - cogl_pipeline_set_layer_combine (ctx->texture_download_pipeline, - 0, /* layer */ - "RGBA = REPLACE (TEXTURE)", - NULL); - - cogl_pipeline_set_layer_filters (ctx->texture_download_pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - do_texture_draw_and_read (handle, target_bmp, viewport); - - /* Check whether texture has alpha and framebuffer not */ - /* FIXME: For some reason even if ALPHA_BITS is 8, the framebuffer - still doesn't seem to have an alpha buffer. This might be just - a PowerVR issue. - GLint r_bits, g_bits, b_bits, a_bits; - GE( glGetIntegerv (GL_ALPHA_BITS, &a_bits) ); - GE( glGetIntegerv (GL_RED_BITS, &r_bits) ); - GE( glGetIntegerv (GL_GREEN_BITS, &g_bits) ); - GE( glGetIntegerv (GL_BLUE_BITS, &b_bits) ); - printf ("R bits: %d\n", r_bits); - printf ("G bits: %d\n", g_bits); - printf ("B bits: %d\n", b_bits); - printf ("A bits: %d\n", a_bits); */ - if ((cogl_texture_get_format (handle) & COGL_A_BIT)/* && a_bits == 0*/) - { - guint8 *srcdata; - guint8 *dstdata; - guint8 *srcpixel; - guint8 *dstpixel; - int x,y; - int alpha_rowstride = bpp * target_width; - - if ((dstdata = _cogl_bitmap_map (target_bmp, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD)) == NULL) - return FALSE; - - srcdata = g_malloc (alpha_rowstride * target_height); - - /* Create temp bitmap for alpha values */ - alpha_bmp = _cogl_bitmap_new_from_data (srcdata, - COGL_PIXEL_FORMAT_RGBA_8888, - target_width, target_height, - alpha_rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); - - /* Draw alpha values into RGB channels */ - cogl_pipeline_set_layer_combine (ctx->texture_download_pipeline, - 0, /* layer */ - "RGBA = REPLACE (TEXTURE[A])", - NULL); - - do_texture_draw_and_read (handle, alpha_bmp, viewport); - - /* Copy temp R to target A */ - - for (y=0; yvtable->get_data (tex, - dst_format, - full_rowstride, - full_bits)) - { - guint8 *dst = dst_bits; - guint8 *src = full_bits + x * bpp + y * full_rowstride; - int i; - - for (i = 0; i < height; i++) - { - memcpy (dst, src, bpp * width); - dst += dst_rowstride; - src += full_rowstride; - } - } - else - ret = FALSE; - - g_free (full_bits); - - return ret; -} - -typedef struct -{ - int orig_width; - int orig_height; - CoglBitmap *target_bmp; - guint8 *target_bits; - gboolean success; -} CoglTextureGetData; - -static void -texture_get_cb (CoglHandle texture_handle, - const float *subtexture_coords, - const float *virtual_coords, - void *user_data) -{ - CoglTexture *tex = COGL_TEXTURE (texture_handle); - CoglTextureGetData *tg_data = user_data; - CoglPixelFormat format = _cogl_bitmap_get_format (tg_data->target_bmp); - int bpp = _cogl_get_format_bpp (format); - unsigned int rowstride = _cogl_bitmap_get_rowstride (tg_data->target_bmp); - int subtexture_width = cogl_texture_get_width (texture_handle); - int subtexture_height = cogl_texture_get_height (texture_handle); - - int x_in_subtexture = (int) (0.5 + subtexture_width * subtexture_coords[0]); - int y_in_subtexture = (int) (0.5 + subtexture_height * subtexture_coords[1]); - int width = ((int) (0.5 + subtexture_width * subtexture_coords[2]) - - x_in_subtexture); - int height = ((int) (0.5 + subtexture_height * subtexture_coords[3]) - - y_in_subtexture); - int x_in_bitmap = (int) (0.5 + tg_data->orig_width * virtual_coords[0]); - int y_in_bitmap = (int) (0.5 + tg_data->orig_height * virtual_coords[1]); - - guint8 *dst_bits; - - if (!tg_data->success) - return; - - dst_bits = tg_data->target_bits + x_in_bitmap * bpp + y_in_bitmap * rowstride; - - /* If we can read everything as a single slice, then go ahead and do that - * to avoid allocating an FBO. We'll leave it up to the GL implementation to - * do glGetTexImage as efficiently as possible. (GLES doesn't have that, - * so we'll fall through) */ - if (x_in_subtexture == 0 && y_in_subtexture == 0 && - width == subtexture_width && height == subtexture_height) - { - if (tex->vtable->get_data (tex, - format, - rowstride, - dst_bits)) - return; - } - - /* Next best option is a FBO and glReadPixels */ - if (get_texture_bits_via_offscreen (texture_handle, - x_in_subtexture, y_in_subtexture, - width, height, - dst_bits, - rowstride, - format)) - return; - - /* Getting ugly: read the entire texture, copy out the part we want */ - if (get_texture_bits_via_copy (texture_handle, - x_in_subtexture, y_in_subtexture, - width, height, - dst_bits, - rowstride, - format)) - return; - - /* No luck, the caller will fall back to the draw-to-backbuffer and - * read implementation */ - tg_data->success = FALSE; -} - -int -cogl_texture_get_data (CoglHandle handle, - CoglPixelFormat format, - unsigned int rowstride, - guint8 *data) -{ - CoglTexture *tex; - int bpp; - int byte_size; - CoglPixelFormat closest_format; - int closest_bpp; - GLenum closest_gl_format; - GLenum closest_gl_type; - CoglBitmap *target_bmp; - CoglBitmap *new_bmp; - guint8 *src; - guint8 *dst; - int y; - int tex_width; - int tex_height; - - CoglTextureGetData tg_data; - - if (!cogl_is_texture (handle)) - return 0; - - tex = COGL_TEXTURE (handle); - - /* Default to internal format if none specified */ - if (format == COGL_PIXEL_FORMAT_ANY) - format = cogl_texture_get_format (handle); - - tex_width = cogl_texture_get_width (handle); - tex_height = cogl_texture_get_height (handle); - - /* Rowstride from texture width if none specified */ - bpp = _cogl_get_format_bpp (format); - if (rowstride == 0) - rowstride = tex_width * bpp; - - /* Return byte size if only that requested */ - byte_size = tex_height * rowstride; - if (data == NULL) - return byte_size; - - closest_format = - _cogl_texture_driver_find_best_gl_get_data_format (format, - &closest_gl_format, - &closest_gl_type); - closest_bpp = _cogl_get_format_bpp (closest_format); - - /* Is the requested format supported? */ - if (closest_format == format) - /* Target user data directly */ - target_bmp = _cogl_bitmap_new_from_data (data, - format, - tex_width, - tex_height, - rowstride, - NULL, NULL); - else - { - int target_rowstride = tex_width * closest_bpp; - guint8 *target_data = g_malloc (tex_height * target_rowstride); - target_bmp = _cogl_bitmap_new_from_data (target_data, - closest_format, - tex_width, - tex_height, - target_rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); - } - - tg_data.orig_width = tex_width; - tg_data.orig_height = tex_height; - tg_data.target_bmp = target_bmp; - tg_data.target_bits = _cogl_bitmap_map (target_bmp, COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - if (tg_data.target_bits == NULL) - { - cogl_object_unref (target_bmp); - return 0; - } - tg_data.success = TRUE; - - /* Iterating through the subtextures allows piecing together - * the data for a sliced texture, and allows us to do the - * read-from-framebuffer logic here in a simple fashion rather than - * passing offsets down through the code. */ - _cogl_texture_foreach_sub_texture_in_region (handle, - 0, 0, 1, 1, - texture_get_cb, - &tg_data); - - _cogl_bitmap_unmap (target_bmp); - - /* XXX: In some cases _cogl_texture_2d_download_from_gl may fail - * to read back the texture data; such as for GLES which doesn't - * support glGetTexImage, so here we fallback to drawing the - * texture and reading the pixels from the framebuffer. */ - if (!tg_data.success) - _cogl_texture_draw_and_read (tex, target_bmp, - closest_gl_format, - closest_gl_type); - - /* Was intermediate used? */ - if (closest_format != format) - { - guint8 *new_bmp_data; - int new_bmp_rowstride; - - /* Convert to requested format */ - new_bmp = _cogl_bitmap_convert_format_and_premult (target_bmp, - format); - - /* Free intermediate data and return if failed */ - cogl_object_unref (target_bmp); - - if (new_bmp == NULL) - return 0; - - new_bmp_rowstride = _cogl_bitmap_get_rowstride (new_bmp); - new_bmp_data = _cogl_bitmap_map (new_bmp, COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - - if (new_bmp_data == NULL) - { - cogl_object_unref (new_bmp); - return 0; - } - - /* Copy to user buffer */ - for (y = 0; y < tex_height; ++y) - { - src = new_bmp_data + y * new_bmp_rowstride; - dst = data + y * rowstride; - memcpy (dst, src, tex_width * bpp); - } - - _cogl_bitmap_unmap (new_bmp); - - /* Free converted data */ - cogl_object_unref (new_bmp); - } - - return byte_size; -} - -static void -_cogl_texture_framebuffer_destroy_cb (void *user_data, - void *instance) -{ - CoglTexture *tex = user_data; - CoglFramebuffer *framebuffer = instance; - - tex->framebuffers = g_list_remove (tex->framebuffers, framebuffer); -} - -void -_cogl_texture_associate_framebuffer (CoglHandle handle, - CoglFramebuffer *framebuffer) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - static CoglUserDataKey framebuffer_destroy_notify_key; - - /* Note: we don't take a reference on the framebuffer here because - * that would introduce a circular reference. */ - tex->framebuffers = g_list_prepend (tex->framebuffers, framebuffer); - - /* Since we haven't taken a reference on the framebuffer we setup - * some private data so we will be notified if it is destroyed... */ - _cogl_object_set_user_data (COGL_OBJECT (framebuffer), - &framebuffer_destroy_notify_key, - tex, - _cogl_texture_framebuffer_destroy_cb); -} - -const GList * -_cogl_texture_get_associated_framebuffers (CoglHandle handle) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - return tex->framebuffers; -} - -void -_cogl_texture_flush_journal_rendering (CoglHandle handle) -{ - CoglTexture *tex = COGL_TEXTURE (handle); - GList *l; - - /* It could be that a referenced texture is part of a framebuffer - * which has an associated journal that must be flushed before it - * can be sampled from by the current primitive... */ - for (l = tex->framebuffers; l; l = l->next) - _cogl_framebuffer_flush_journal (l->data); -} diff --git a/clutter/cogl/cogl/cogl-texture.h b/clutter/cogl/cogl/cogl-texture.h deleted file mode 100644 index c8968e6..0000000 --- a/clutter/cogl/cogl/cogl-texture.h +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_TEXTURE_H__ -#define __COGL_TEXTURE_H__ - -#include -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-texture - * @short_description: Fuctions for creating and manipulating textures - * - * COGL allows creating and manipulating GL textures using a uniform - * API that tries to hide all the various complexities of creating, - * loading and manipulating textures. - */ - -#define COGL_TEXTURE_MAX_WASTE 127 - -/** - * cogl_texture_new_with_size: - * @width: width of texture in pixels. - * @height: height of texture in pixels. - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture. - * - * Creates a new COGL texture with the specified dimensions and pixel format. - * - * Return value: a #CoglHandle to the newly created texture or - * %COGL_INVALID_HANDLE on failure - * - * Since: 0.8 - */ -CoglHandle -cogl_texture_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -/** - * cogl_texture_new_from_file: - * @filename: the file to load - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied - * format similar to the format of the source data will be used. The - * default blending equations of Cogl expect premultiplied color data; - * the main use of passing a non-premultiplied format here is if you - * have non-premultiplied source data and are going to adjust the blend - * mode (see cogl_material_set_blend()) or use the data for something - * other than straight blending. - * @error: return location for a #GError or %NULL - * - * Creates a COGL texture from an image file. - * - * Return value: a #CoglHandle to the newly created texture or - * %COGL_INVALID_HANDLE on failure - * - * Since: 0.8 - */ -CoglHandle -cogl_texture_new_from_file (const char *filename, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error); - -/** - * cogl_texture_new_from_data: - * @width: width of texture in pixels - * @height: height of texture in pixels - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @internal_format: the #CoglPixelFormat that will be used for storing - * the buffer on the GPU. If COGL_PIXEL_FORMAT_ANY is given then a - * premultiplied format similar to the format of the source data will - * be used. The default blending equations of Cogl expect premultiplied - * color data; the main use of passing a non-premultiplied format here - * is if you have non-premultiplied source data and are going to adjust - * the blend mode (see cogl_material_set_blend()) or use the data for - * something other than straight blending. - * @rowstride: the memory offset in bytes between the starts of - * scanlines in @data - * @data: pointer the memory region where the source buffer resides - * - * Creates a new COGL texture based on data residing in memory. - * - * Return value: a #CoglHandle to the newly created texture or - * %COGL_INVALID_HANDLE on failure - * - * Since: 0.8 - */ -CoglHandle -cogl_texture_new_from_data (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - unsigned int rowstride, - const guint8 *data); - -/** - * cogl_texture_new_from_foreign: - * @gl_handle: opengl handle of foreign texture. - * @gl_target: opengl target type of foreign texture - * @width: width of foreign texture - * @height: height of foreign texture. - * @x_pot_waste: horizontal waste on the right hand edge of the texture. - * @y_pot_waste: vertical waste on the bottom edge of the texture. - * @format: format of the foreign texture. - * - * Creates a COGL texture based on an existing OpenGL texture; the - * width, height and format are passed along since it is not always - * possible to query these from OpenGL. - * - * The waste arguments allow you to create a Cogl texture that maps to - * a region smaller than the real OpenGL texture. For instance if your - * hardware only supports power-of-two textures you may load a - * non-power-of-two image into a larger power-of-two texture and use - * the waste arguments to tell Cogl which region should be mapped to - * the texture coordinate range [0:1]. - * - * Return value: a #CoglHandle to the newly created texture or - * %COGL_INVALID_HANDLE on failure - * - * Since: 0.8 - */ -CoglHandle -cogl_texture_new_from_foreign (GLuint gl_handle, - GLenum gl_target, - GLuint width, - GLuint height, - GLuint x_pot_waste, - GLuint y_pot_waste, - CoglPixelFormat format); - -/** - * cogl_texture_new_from_bitmap: - * @bmp_handle: A CoglBitmap handle - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture - * - * Creates a COGL texture from a CoglBitmap. - * - * Return value: a #CoglHandle to the newly created texture or - * %COGL_INVALID_HANDLE on failure - * - * Since: 1.0 - */ -CoglHandle -cogl_texture_new_from_bitmap (CoglHandle bmp_handle, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -/** - * cogl_is_texture: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing texture object. - * - * Return value: %TRUE if the handle references a texture, and - * %FALSE otherwise - */ -gboolean -cogl_is_texture (CoglHandle handle); - -/** - * cogl_texture_get_width: - * @handle: a #CoglHandle for a texture. - * - * Queries the width of a cogl texture. - * - * Return value: the width of the GPU side texture in pixels - */ -unsigned int -cogl_texture_get_width (CoglHandle handle); - -/** - * cogl_texture_get_height: - * @handle: a #CoglHandle for a texture. - * - * Queries the height of a cogl texture. - * - * Return value: the height of the GPU side texture in pixels - */ -unsigned int -cogl_texture_get_height (CoglHandle handle); - -/** - * cogl_texture_get_format: - * @handle: a #CoglHandle for a texture. - * - * Queries the #CoglPixelFormat of a cogl texture. - * - * Return value: the #CoglPixelFormat of the GPU side texture - */ -CoglPixelFormat -cogl_texture_get_format (CoglHandle handle); - - -/** - * cogl_texture_get_rowstride: - * @handle: a #CoglHandle for a texture. - * - * Queries the rowstride of a cogl texture. - * - * Return value: the offset in bytes between each consequetive row of pixels - */ -unsigned int -cogl_texture_get_rowstride (CoglHandle handle); - -/** - * cogl_texture_get_max_waste: - * @handle: a #CoglHandle for a texture. - * - * Queries the maximum wasted (unused) pixels in one dimension of a GPU side - * texture. - * - * Return value: the maximum waste - */ -int -cogl_texture_get_max_waste (CoglHandle handle); - -/** - * cogl_texture_is_sliced: - * @handle: a #CoglHandle for a texture. - * - * Queries if a texture is sliced (stored as multiple GPU side tecture - * objects). - * - * Return value: %TRUE if the texture is sliced, %FALSE if the texture - * is stored as a single GPU texture - */ -gboolean -cogl_texture_is_sliced (CoglHandle handle); - -/** - * cogl_texture_get_gl_texture: - * @handle: a #CoglHandle for a texture. - * @out_gl_handle: (out) (allow-none): pointer to return location for the - * textures GL handle, or %NULL. - * @out_gl_target: (out) (allow-none): pointer to return location for the - * GL target type, or %NULL. - * - * Queries the GL handles for a GPU side texture through its #CoglHandle. - * - * If the texture is spliced the data for the first sub texture will be - * queried. - * - * Return value: %TRUE if the handle was successfully retrieved, %FALSE - * if the handle was invalid - */ -gboolean -cogl_texture_get_gl_texture (CoglHandle handle, - GLuint *out_gl_handle, - GLenum *out_gl_target); - -/** - * cogl_texture_get_data: - * @handle: a #CoglHandle for a texture. - * @format: the #CoglPixelFormat to store the texture as. - * @rowstride: the rowstride of @data or retrieved from texture if none is - * specified. - * @data: memory location to write contents of buffer, or %NULL if we're - * only querying the data size through the return value. - * - * Copies the pixel data from a cogl texture to system memory. - * - * Return value: the size of the texture data in bytes, or 0 if the texture - * is not valid - */ -int -cogl_texture_get_data (CoglHandle handle, - CoglPixelFormat format, - unsigned int rowstride, - guint8 *data); - -/** - * cogl_texture_set_region: - * @handle: a #CoglHandle. - * @src_x: upper left coordinate to use from source data. - * @src_y: upper left coordinate to use from source data. - * @dst_x: upper left destination horizontal coordinate. - * @dst_y: upper left destination vertical coordinate. - * @dst_width: width of destination region to write. - * @dst_height: height of destination region to write. - * @width: width of source data buffer. - * @height: height of source data buffer. - * @format: the #CoglPixelFormat used in the source buffer. - * @rowstride: rowstride of source buffer (computed from width if none - * specified) - * @data: the actual pixel data. - * - * Sets the pixels in a rectangular subregion of @handle from an in-memory - * buffer containing pixel data. - * - * Return value: %TRUE if the subregion upload was successful, and - * %FALSE otherwise - */ -gboolean -cogl_texture_set_region (CoglHandle handle, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - int width, - int height, - CoglPixelFormat format, - unsigned int rowstride, - const guint8 *data); - -/** - * cogl_texture_new_from_sub_texture: - * @full_texture: a #CoglHandle to an existing texture - * @sub_x: X coordinate of the top-left of the subregion - * @sub_y: Y coordinate of the top-left of the subregion - * @sub_width: Width in pixels of the subregion - * @sub_height: Height in pixels of the subregion - * - * Creates a new texture which represents a subregion of another - * texture. The GL resources will be shared so that no new texture - * data is actually allocated. - * - * Sub textures have undefined behaviour texture coordinates outside - * of the range [0,1] are used. They also do not work with - * CoglVertexBuffers. - * - * The sub texture will keep a reference to the full texture so you do - * not need to keep one separately if you only want to use the sub - * texture. - * - * Return value: a #CoglHandle to the new texture. - * - * Since: 1.2 - */ -CoglHandle -cogl_texture_new_from_sub_texture (CoglHandle full_texture, - int sub_x, - int sub_y, - int sub_width, - int sub_height); - -#if defined (COGL_ENABLE_EXPERIMENTAL_API) - -/** - * cogl_texture_new_from_buffer: - * @buffer: the #CoglHandle of a pixel buffer - * @width: width of texture in pixels or 0 - * @height: height of texture in pixels or 0 - * @flags: optional flags for the texture, or %COGL_TEXTURE_NONE - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @internal_format: the #CoglPixelFormat that will be used for storing - * the buffer on the GPU. If %COGL_PIXEL_FORMAT_ANY is given then a - * premultiplied format similar to the format of the source data will - * be used. The default blending equations of Cogl expect premultiplied - * color data; the main use of passing a non-premultiplied format here - * is if you have non-premultiplied source data and are going to adjust - * the blend mode (see cogl_material_set_blend()) or use the data for - * something other than straight blending - * @rowstride: the memory offset in bytes between the starts of - * scanlines in @data. If 0 is given the row stride will be deduced from - * @width and @format or the stride given by cogl_pixel_buffer_new_for_size() - * @offset: offset in bytes in @buffer from where the texture data starts - * - * Creates a new texture using the buffer specified by @handle. If the buffer - * has been created using cogl_pixel_buffer_new_for_size() it's possible to omit - * the height and width values already specified at creation time. - * - * Return value: a #CoglHandle to the new texture or %COGL_INVALID_HANDLE on - * failure - * - * Since: 1.2 - * Stability: Unstable - */ -CoglHandle -cogl_texture_new_from_buffer (CoglHandle buffer, - unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - unsigned int rowstride, - unsigned int offset); - -/* the function above is experimental, the actual symbol is suffixed by _EXP so - * we can ensure ABI compatibility and leave the cogl_buffer namespace free for - * future use. A bunch of defines translates the symbols documented above into - * the real symbols */ - -CoglHandle -cogl_texture_new_from_buffer_EXP (CoglHandle buffer, - unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - unsigned int rowstride, - unsigned int offset); - -#define cogl_texture_new_from_buffer cogl_texture_new_from_buffer_EXP - -#endif - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_texture_ref: - * @handle: a @CoglHandle. - * - * Increment the reference count for a cogl texture. - * - * Deprecated: 1.2: Use cogl_handle_ref() instead - * - * Return value: the @handle. - */ -CoglHandle -cogl_texture_ref (CoglHandle handle) G_GNUC_DEPRECATED; - -/** - * cogl_texture_unref: - * @handle: a @CoglHandle. - * - * Decrement the reference count for a cogl texture. - * - * Deprecated: 1.2: Use cogl_handle_unref() instead - */ -void -cogl_texture_unref (CoglHandle handle) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -G_END_DECLS - -#endif /* __COGL_TEXTURE_H__ */ diff --git a/clutter/cogl/cogl/cogl-types.h b/clutter/cogl/cogl/cogl-types.h deleted file mode 100644 index 47a17b1..0000000 --- a/clutter/cogl/cogl/cogl-types.h +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_TYPES_H__ -#define __COGL_TYPES_H__ - -#include - -#include -#ifdef COGL_HAS_XLIB -#include -#endif - -G_BEGIN_DECLS - -/* Some structures are meant to be opaque but they have public - definitions because we want the size to be public so they can be - allocated on the stack. This macro is used to ensure that users - don't accidentally access private members */ -#ifdef CLUTTER_COMPILATION -#define COGL_PRIVATE(x) x -#else -#define COGL_PRIVATE(x) private_member_ ## x -#endif - -/** - * CoglHandle: - * - * Type used for storing references to cogl objects, the CoglHandle is - * a fully opaque type without any public data members. - */ -typedef gpointer CoglHandle; - -/** - * COGL_INVALID_HANDLE: - * - * A COGL handle that is not valid, used for unitialized handles as well as - * error conditions. - */ -#define COGL_INVALID_HANDLE NULL - -#define COGL_TYPE_HANDLE (cogl_handle_get_type ()) -GType -cogl_handle_get_type (void) G_GNUC_CONST; - -/** - * cogl_handle_ref: - * @handle: a #CoglHandle - * - * Increases the reference count of @handle by 1 - * - * Return value: (transfer none): the handle, with its reference count increased - */ -CoglHandle -cogl_handle_ref (CoglHandle handle); - -/** - * cogl_handle_unref: - * @handle: a #CoglHandle - * - * Drecreases the reference count of @handle by 1; if the reference - * count reaches 0, the resources allocated by @handle will be freed - */ -void -cogl_handle_unref (CoglHandle handle); - -/** - * cogl_object_ref: (skip) - * @object: a #CoglObject - * - * Increases the reference count of @handle by 1 - * - * Returns: the @object, with its reference count increased - */ -void * -cogl_object_ref (void *object); - -/** - * cogl_object_unref: (skip) - * @object: a #CoglObject - * - * Drecreases the reference count of @object by 1; if the reference - * count reaches 0, the resources allocated by @object will be freed - */ -void -cogl_object_unref (void *object); - -/** - * CoglFuncPtr: - * - * The type used by cogl for function pointers, note that this type - * is used as a generic catch-all cast for function pointers and the - * actual arguments and return type may be different. - */ -typedef void (* CoglFuncPtr) (void); - -/** - * CoglFixed: - * - * Fixed point number using a (16.16) notation. - */ -typedef gint32 CoglFixed; - -#define COGL_TYPE_FIXED (cogl_fixed_get_type ()) -GType -cogl_fixed_get_type (void) G_GNUC_CONST; - -/** - * CoglAngle: - * - * Integer representation of an angle such that 1024 corresponds to - * full circle (i.e., 2 * pi). - * - * Since: 1.0 - */ -typedef gint32 CoglAngle; - -typedef struct _CoglColor CoglColor; -typedef struct _CoglTextureVertex CoglTextureVertex; - -/* Enum declarations */ - -#define COGL_PIXEL_FORMAT_24 2 -#define COGL_PIXEL_FORMAT_32 3 -#define COGL_A_BIT (1 << 4) -#define COGL_BGR_BIT (1 << 5) -#define COGL_AFIRST_BIT (1 << 6) -#define COGL_PREMULT_BIT (1 << 7) -#define COGL_UNORDERED_MASK 0x0F -#define COGL_UNPREMULT_MASK 0x7F - -/** - * CoglPixelFormat: - * @COGL_PIXEL_FORMAT_ANY: Any format - * @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask - * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_YUV: Not currently supported - * @COGL_PIXEL_FORMAT_G_8: Single luminance component - * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits - * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits - * @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits - * - * Pixel formats used by COGL. For the formats with a byte per - * component, the order of the components specify the order in - * increasing memory addresses. So for example - * %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the - * lowest address, green in the next address and blue after that - * regardless of the endinanness of the system. - * - * For the 16-bit formats the component order specifies the order - * within a 16-bit number from most significant bit to least - * significant. So for %COGL_PIXEL_FORMAT_RGB_565, the red component - * would be in bits 11-15, the green component would be in 6-11 and - * the blue component would be in 1-5. Therefore the order in memory - * depends on the endianness of the system. - * - * When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the - * internal format. Cogl will try to pick the best format to use - * internally and convert the texture data if necessary. - * - * Since: 0.8 - */ -typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/ - COGL_PIXEL_FORMAT_ANY = 0, - COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT, - - COGL_PIXEL_FORMAT_RGB_565 = 4, - COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT, - COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT, - COGL_PIXEL_FORMAT_YUV = 7, - COGL_PIXEL_FORMAT_G_8 = 8, - - COGL_PIXEL_FORMAT_RGB_888 = COGL_PIXEL_FORMAT_24, - COGL_PIXEL_FORMAT_BGR_888 = (COGL_PIXEL_FORMAT_24 | COGL_BGR_BIT), - - COGL_PIXEL_FORMAT_RGBA_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRA_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888 = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888_PRE = (COGL_PIXEL_FORMAT_32 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT) -} CoglPixelFormat; - -/** - * CoglFeatureFlags: - * @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support - * @COGL_FEATURE_TEXTURE_NPOT: Non power of two textures are supported - * by the hardware. This is a equivalent to the - * %COGL_FEATURE_TEXTURE_NPOT_BASIC, %COGL_FEATURE_TEXTURE_NPOT_MIPMAP - * and %COGL_FEATURE_TEXTURE_NPOT_REPEAT features combined. - * @COGL_FEATURE_TEXTURE_YUV: ycbcr conversion support - * @COGL_FEATURE_TEXTURE_READ_PIXELS: glReadPixels() support - * @COGL_FEATURE_SHADERS_GLSL: GLSL support - * @COGL_FEATURE_SHADERS_ARBFP: ARBFP support - * @COGL_FEATURE_OFFSCREEN: FBO support - * @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs - * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs - * @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available - * @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support - * @COGL_FEATURE_VBOS: VBO support - * @COGL_FEATURE_PBOS: PBO support - * @COGL_FEATURE_UNSIGNED_INT_INDICES: Set if - * %COGL_INDICES_TYPE_UNSIGNED_INT is supported in - * cogl_vertex_buffer_indices_new(). - * @COGL_FEATURE_DEPTH_RANGE: cogl_material_set_depth_range() support - * @COGL_FEATURE_TEXTURE_NPOT_BASIC: The hardware supports non power - * of two textures, but you also need to check the - * %COGL_FEATURE_TEXTURE_NPOT_MIPMAP and %COGL_FEATURE_TEXTURE_NPOT_REPEAT - * features to know if the hardware supports npot texture mipmaps - * or repeat modes other than - * %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively. - * @COGL_FEATURE_TEXTURE_NPOT_MIPMAP: Mipmapping is supported in - * conjuntion with non power of two textures. - * @COGL_FEATURE_TEXTURE_NPOT_REPEAT: Repeat modes other than - * %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by the - * hardware. - * @COGL_FEATURE_POINT_SPRITE: Whether - * cogl_material_set_layer_point_sprite_coords_enabled() is supported. - * @COGL_FEATURE_TEXTURE_3D: 3D texture support - * @COGL_FEATURE_MAP_BUFFER_FOR_READ: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including read support. - * @COGL_FEATURE_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including write support. - * - * Flags for the supported features. - * - * Since: 0.8 - */ -typedef enum -{ - COGL_FEATURE_TEXTURE_RECTANGLE = (1 << 1), - COGL_FEATURE_TEXTURE_NPOT = (1 << 2), - COGL_FEATURE_TEXTURE_YUV = (1 << 3), - COGL_FEATURE_TEXTURE_READ_PIXELS = (1 << 4), - COGL_FEATURE_SHADERS_GLSL = (1 << 5), - COGL_FEATURE_OFFSCREEN = (1 << 6), - COGL_FEATURE_OFFSCREEN_MULTISAMPLE = (1 << 7), - COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8), - COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9), - COGL_FEATURE_STENCIL_BUFFER = (1 << 10), - COGL_FEATURE_VBOS = (1 << 11), - COGL_FEATURE_PBOS = (1 << 12), - COGL_FEATURE_UNSIGNED_INT_INDICES = (1 << 13), - COGL_FEATURE_DEPTH_RANGE = (1 << 14), - COGL_FEATURE_TEXTURE_NPOT_BASIC = (1 << 15), - COGL_FEATURE_TEXTURE_NPOT_MIPMAP = (1 << 16), - COGL_FEATURE_TEXTURE_NPOT_REPEAT = (1 << 17), - COGL_FEATURE_POINT_SPRITE = (1 << 18), - COGL_FEATURE_TEXTURE_3D = (1 << 19), - COGL_FEATURE_SHADERS_ARBFP = (1 << 20), - COGL_FEATURE_MAP_BUFFER_FOR_READ = (1 << 21), - COGL_FEATURE_MAP_BUFFER_FOR_WRITE = (1 << 22), - COGL_FEATURE_ONSCREEN_MULTIPLE = (1 << 23) -} CoglFeatureFlags; - -/** - * CoglBufferTarget: - * @COGL_WINDOW_BUFFER: FIXME - * @COGL_OFFSCREEN_BUFFER: FIXME - * - * Target flags for FBOs. - * - * Since: 0.8 - */ -typedef enum -{ - COGL_WINDOW_BUFFER = (1 << 1), - COGL_OFFSCREEN_BUFFER = (1 << 2) -} CoglBufferTarget; - -/** - * CoglColor: - * - * A structure for holding a color definition. The contents of - * the CoglColor structure are private and should never by accessed - * directly. - * - * Since: 1.0 - */ -struct _CoglColor -{ - /*< private >*/ - guint8 COGL_PRIVATE (red); - guint8 COGL_PRIVATE (green); - guint8 COGL_PRIVATE (blue); - - guint8 COGL_PRIVATE (alpha); - - /* padding in case we want to change to floats at - * some point */ - guint32 COGL_PRIVATE (padding0); - guint32 COGL_PRIVATE (padding1); - guint32 COGL_PRIVATE (padding2); -}; - -/** - * CoglTextureVertex: - * @x: Model x-coordinate - * @y: Model y-coordinate - * @z: Model z-coordinate - * @tx: Texture x-coordinate - * @ty: Texture y-coordinate - * @color: The color to use at this vertex. This is ignored if - * use_color is %FALSE when calling cogl_polygon() - * - * Used to specify vertex information when calling cogl_polygon() - */ -struct _CoglTextureVertex -{ - float x, y, z; - float tx, ty; - - CoglColor color; -}; - -/** - * CoglTextureFlags: - * @COGL_TEXTURE_NONE: No flags specified - * @COGL_TEXTURE_NO_AUTO_MIPMAP: Disables the automatic generation of - * the mipmap pyramid from the base level image whenever it is - * updated. The mipmaps are only generated when the texture is - * rendered with a mipmap filter so it should be free to leave out - * this flag when using other filtering modes - * @COGL_TEXTURE_NO_SLICING: Disables the slicing of the texture - * @COGL_TEXTURE_NO_ATLAS: Disables the insertion of the texture inside - * the texture atlas used by Cogl - * - * Flags to pass to the cogl_texture_new_* family of functions. - * - * Since: 1.0 - */ -typedef enum { - COGL_TEXTURE_NONE = 0, - COGL_TEXTURE_NO_AUTO_MIPMAP = 1 << 0, - COGL_TEXTURE_NO_SLICING = 1 << 1, - COGL_TEXTURE_NO_ATLAS = 1 << 2 -} CoglTextureFlags; - -/** - * CoglFogMode: - * @COGL_FOG_MODE_LINEAR: Calculates the fog blend factor as: - * |[ - * f = end - eye_distance / end - start - * ]| - * @COGL_FOG_MODE_EXPONENTIAL: Calculates the fog blend factor as: - * |[ - * f = e ^ -(density * eye_distance) - * ]| - * @COGL_FOG_MODE_EXPONENTIAL_SQUARED: Calculates the fog blend factor as: - * |[ - * f = e ^ -(density * eye_distance)^2 - * ]| - * - * The fog mode determines the equation used to calculate the fogging blend - * factor while fogging is enabled. The simplest %COGL_FOG_MODE_LINEAR mode - * determines f as: - * - * |[ - * f = end - eye_distance / end - start - * ]| - * - * Where eye_distance is the distance of the current fragment in eye - * coordinates from the origin. - * - * Since: 1.0 - */ -typedef enum { - COGL_FOG_MODE_LINEAR, - COGL_FOG_MODE_EXPONENTIAL, - COGL_FOG_MODE_EXPONENTIAL_SQUARED -} CoglFogMode; - -/** - * COGL_BLEND_STRING_ERROR: - * - * #GError domain for blend string parser errors - * - * Since: 1.0 - */ -#define COGL_BLEND_STRING_ERROR (cogl_blend_string_error_quark ()) - -/** - * CoglBlendStringError: - * @COGL_BLEND_STRING_ERROR_PARSE_ERROR: Generic parse error - * @COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR: Argument parse error - * @COGL_BLEND_STRING_ERROR_INVALID_ERROR: Internal parser error - * @COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR: Blend string not - * supported by the GPU - * - * Error enumeration for the blend strings parser - * - * Since: 1.0 - */ -typedef enum { /*< prefix=COGL_BLEND_STRING_ERROR >*/ - COGL_BLEND_STRING_ERROR_PARSE_ERROR, - COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, - COGL_BLEND_STRING_ERROR_INVALID_ERROR, - COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR -} CoglBlendStringError; - -GQuark -cogl_blend_string_error_quark (void); - -#define COGL_ERROR (_cogl_error_quark ()) - -/** - * CoglError: - * @COGL_ERROR_UNSUPPORTED: You tried to use a feature or - * configuration not currently available. - * - * Error enumeration for Cogl - * - * The @COGL_ERROR_UNSUPPORTED error can be thrown for a variety of - * reasons. For example: - * - * - * You've tried to use a feature that is not - * advertised by cogl_get_features(). This could happen if you create - * a non-sliced texture with a non-power-of-two size when - * %COGL_FEATURE_TEXTURE_NPOT is not advertised. - * The GPU can not handle the configuration you have - * requested. An example might be if you try to use too many texture - * layers in a single #CoglPipeline - * The driver does not support some - * configuration. - * - * - * Currently this is only used by Cogl API marked as experimental so - * this enum should also be considered experimental. - * - * Since: 1.4 - */ -typedef enum { /*< prefix=COGL_ERROR >*/ - COGL_ERROR_UNSUPPORTED -} CoglError; - -GQuark -_cogl_error_quark (void); - -/** - * CoglAttributeType: - * @COGL_ATTRIBUTE_TYPE_BYTE: Data is the same size of a byte - * @COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE: Data is the same size of an - * unsigned byte - * @COGL_ATTRIBUTE_TYPE_SHORT: Data is the same size of a short integer - * @COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT: Data is the same size of - * an unsigned short integer - * @COGL_ATTRIBUTE_TYPE_FLOAT: Data is the same size of a float - * - * Data types for the components of a vertex attribute. - * - * Since: 1.0 - */ -typedef enum { - COGL_ATTRIBUTE_TYPE_BYTE = 0x1400, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE = 0x1401, - COGL_ATTRIBUTE_TYPE_SHORT = 0x1402, - COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT = 0x1403, - COGL_ATTRIBUTE_TYPE_FLOAT = 0x1406 -} CoglAttributeType; - -/** - * CoglIndicesType: - * @COGL_INDICES_TYPE_UNSIGNED_BYTE: Your indices are unsigned bytes - * @COGL_INDICES_TYPE_UNSIGNED_SHORT: Your indices are unsigned shorts - * @COGL_INDICES_TYPE_UNSIGNED_INT: Your indices are unsigned ints - * - * You should aim to use the smallest data type that gives you enough - * range, since it reduces the size of your index array and can help - * reduce the demand on memory bandwidth. - * - * Note that %COGL_INDICES_TYPE_UNSIGNED_INT is only supported if the - * %COGL_FEATURE_UNSIGNED_INT_INDICES feature is available. This - * should always be available on OpenGL but on OpenGL ES it will only - * be available if the GL_OES_element_index_uint extension is - * advertized. - */ -typedef enum { - COGL_INDICES_TYPE_UNSIGNED_BYTE, - COGL_INDICES_TYPE_UNSIGNED_SHORT, - COGL_INDICES_TYPE_UNSIGNED_INT -} CoglIndicesType; - -/** - * CoglVerticesMode: - * @COGL_VERTICES_MODE_POINTS: FIXME, equivalent to %GL_POINTS - * @COGL_VERTICES_MODE_LINES: FIXME, equivalent to %GL_LINES - * @COGL_VERTICES_MODE_LINE_LOOP: FIXME, equivalent to %GL_LINE_LOOP - * @COGL_VERTICES_MODE_LINE_STRIP: FIXME, equivalent to %GL_LINE_STRIP - * @COGL_VERTICES_MODE_TRIANGLES: FIXME, equivalent to %GL_TRIANGLES - * @COGL_VERTICES_MODE_TRIANGLE_STRIP: FIXME, equivalent to %GL_TRIANGLE_STRIP - * @COGL_VERTICES_MODE_TRIANGLE_FAN: FIXME, equivalent to %GL_TRIANGLE_FAN - * - * Different ways of interpreting vertices when drawing. - * - * Since: 1.0 - */ -typedef enum { - COGL_VERTICES_MODE_POINTS = 0x0000, - COGL_VERTICES_MODE_LINES = 0x0001, - COGL_VERTICES_MODE_LINE_LOOP = 0x0002, - COGL_VERTICES_MODE_LINE_STRIP = 0x0003, - COGL_VERTICES_MODE_TRIANGLES = 0x0004, - COGL_VERTICES_MODE_TRIANGLE_STRIP = 0x0005, - COGL_VERTICES_MODE_TRIANGLE_FAN = 0x0006 -} CoglVerticesMode; - -/* NB: The above definitions are taken from gl.h equivalents */ - - -/* XXX: should this be CoglMaterialDepthTestFunction? - * It makes it very verbose but would be consistent with - * CoglMaterialWrapMode */ - -/** - * CoglDepthTestFunction: - * @COGL_DEPTH_TEST_FUNCTION_NEVER: Never passes. - * @COGL_DEPTH_TEST_FUNCTION_LESS: Passes if the fragment's depth - * value is less than the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_EQUAL: Passes if the fragment's depth - * value is equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_LEQUAL: Passes if the fragment's depth - * value is less or equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_GREATER: Passes if the fragment's depth - * value is greater than the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_NOTEQUAL: Passes if the fragment's depth - * value is not equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_GEQUAL: Passes if the fragment's depth - * value greater than or equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_ALWAYS: Always passes. - * - * When using depth testing one of these functions is used to compare - * the depth of an incoming fragment against the depth value currently - * stored in the depth buffer. The function is changed using - * cogl_material_set_depth_test_function(). - * - * The test is only done when depth testing is explicitly enabled. (See - * cogl_material_set_depth_test_enabled()) - */ -typedef enum -{ - COGL_DEPTH_TEST_FUNCTION_NEVER = 0x0200, - COGL_DEPTH_TEST_FUNCTION_LESS = 0x0201, - COGL_DEPTH_TEST_FUNCTION_EQUAL = 0x0202, - COGL_DEPTH_TEST_FUNCTION_LEQUAL = 0x0203, - COGL_DEPTH_TEST_FUNCTION_GREATER = 0x0204, - COGL_DEPTH_TEST_FUNCTION_NOTEQUAL = 0x0205, - COGL_DEPTH_TEST_FUNCTION_GEQUAL = 0x0206, - COGL_DEPTH_TEST_FUNCTION_ALWAYS = 0x0207 -} CoglDepthTestFunction; -/* NB: The above definitions are taken from gl.h equivalents */ - -typedef enum { /*< prefix=COGL_RENDERER_ERROR >*/ - COGL_RENDERER_ERROR_NOT_FOUND, - COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN -} CoglRendererError; - -/* - * CoglFilterReturn: - * @COGL_FILTER_CONTINUE: The event was not handled, continues the - * processing - * @COGL_FILTER_REMOVE: Remove the event, stops the processing - * - * Return values for the #CoglFilterFunc function. - * - * Stability: Unstable - */ -typedef enum _CoglFilterReturn { /*< prefix=COGL_FILTER >*/ - COGL_FILTER_CONTINUE, - COGL_FILTER_REMOVE -} CoglFilterReturn; - -typedef enum _CoglWinsysFeature -{ - /* Available if the window system can support multiple onscreen - * framebuffers at the same time. */ - COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, - - /* Available if onscreen framebuffer swaps can be automatically - * throttled to the vblank frequency. */ - COGL_WINSYS_FEATURE_SWAP_THROTTLE, - - /* Available if its possible to query a counter that - * increments at each vblank. */ - COGL_WINSYS_FEATURE_VBLANK_COUNTER, - - /* Available if its possible to wait until the next vertical - * blank period */ - COGL_WINSYS_FEATURE_VBLANK_WAIT, - - /* Available if the window system supports mapping native - * pixmaps to textures. */ - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP, - - /* Available if the window system supports reporting an event - * for swap buffer completions. */ - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, - - /* Available if it's possible to swap a list of sub rectangles - * from the back buffer to the front buffer */ - COGL_WINSYS_FEATURE_SWAP_REGION, - - /* Available if swap_region requests can be automatically throttled - * to the vblank frequency. */ - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, - - COGL_WINSYS_FEATURE_N_FEATURES -} CoglWinsysFeature; - -/* XXX: Note these enum types are only referenced by experimental API - * so although they aren't explicitly guarded they are implicitly - * experimental too. */ - -/* - * CoglNativeFilterFunc: - * @native_event: A pointer to the native system event - * @data: The data that was given when the filter was added - * - * A callback function that can be registered with - * cogl_renderer_add_native_filter(). The function should return - * %COGL_FILTER_REMOVE if it wants to prevent further processing or - * %COGL_FILTER_CONTINUE otherwise. - * - * The type that @native_event points to depends on the type of the - * underlying renderer. On xlib based renderers this would point to an - * XEvent struct and on Windows it would point to a MSG struct. - */ -typedef CoglFilterReturn (* CoglNativeFilterFunc) (void *native_event, - void *data); - - -G_END_DECLS - -#endif /* __COGL_TYPES_H__ */ diff --git a/clutter/cogl/cogl/cogl-util.c b/clutter/cogl/cogl/cogl-util.c deleted file mode 100644 index ddee76a..0000000 --- a/clutter/cogl/cogl/cogl-util.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "cogl.h" - -#include "cogl-fixed.h" -#include "cogl-internal.h" -#include "cogl-pipeline.h" -#include "cogl-offscreen.h" -#include "cogl-shader.h" -#include "cogl-texture.h" -#include "cogl-types.h" -#include "cogl-util.h" - -/* - * cogl_util_next_p2: - * @a: Value to get the next power of two - * - * Calculates the next power of two greater than or equal to @a. - * - * Return value: @a if @a is already a power of two, otherwise returns - * the next nearest power of two. - */ -int -_cogl_util_next_p2 (int a) -{ - int rval = 1; - - while (rval < a) - rval <<= 1; - - return rval; -} - -/* gtypes */ - -/* - * CoglFixed - */ - -static GTypeInfo _info = { - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - NULL, -}; - -static GTypeFundamentalInfo _finfo = { 0, }; - -static void -cogl_value_init_fixed (GValue *value) -{ - value->data[0].v_int = 0; -} - -static void -cogl_value_copy_fixed (const GValue *src, - GValue *dest) -{ - dest->data[0].v_int = src->data[0].v_int; -} - -static char * -cogl_value_collect_fixed (GValue *value, - unsigned int n_collect_values, - GTypeCValue *collect_values, - unsigned int collect_flags) -{ - value->data[0].v_int = collect_values[0].v_int; - - return NULL; -} - -static char * -cogl_value_lcopy_fixed (const GValue *value, - unsigned int n_collect_values, - GTypeCValue *collect_values, - unsigned int collect_flags) -{ - gint32 *fixed_p = collect_values[0].v_pointer; - - if (!fixed_p) - return g_strdup_printf ("value location for '%s' passed as NULL", - G_VALUE_TYPE_NAME (value)); - - *fixed_p = value->data[0].v_int; - - return NULL; -} - -static void -cogl_value_transform_fixed_int (const GValue *src, - GValue *dest) -{ - dest->data[0].v_int = COGL_FIXED_TO_INT (src->data[0].v_int); -} - -static void -cogl_value_transform_fixed_double (const GValue *src, - GValue *dest) -{ - dest->data[0].v_double = COGL_FIXED_TO_DOUBLE (src->data[0].v_int); -} - -static void -cogl_value_transform_fixed_float (const GValue *src, - GValue *dest) -{ - dest->data[0].v_float = COGL_FIXED_TO_FLOAT (src->data[0].v_int); -} - -static void -cogl_value_transform_int_fixed (const GValue *src, - GValue *dest) -{ - dest->data[0].v_int = COGL_FIXED_FROM_INT (src->data[0].v_int); -} - -static void -cogl_value_transform_double_fixed (const GValue *src, - GValue *dest) -{ - dest->data[0].v_int = COGL_FIXED_FROM_DOUBLE (src->data[0].v_double); -} - -static void -cogl_value_transform_float_fixed (const GValue *src, - GValue *dest) -{ - dest->data[0].v_int = COGL_FIXED_FROM_FLOAT (src->data[0].v_float); -} - - -static const GTypeValueTable _cogl_fixed_value_table = { - cogl_value_init_fixed, - NULL, - cogl_value_copy_fixed, - NULL, - "i", - cogl_value_collect_fixed, - "p", - cogl_value_lcopy_fixed -}; - -GType -cogl_fixed_get_type (void) -{ - static GType _cogl_fixed_type = 0; - - if (G_UNLIKELY (_cogl_fixed_type == 0)) - { - _info.value_table = & _cogl_fixed_value_table; - _cogl_fixed_type = - g_type_register_fundamental (g_type_fundamental_next (), - g_intern_static_string ("CoglFixed"), - &_info, &_finfo, 0); - - g_value_register_transform_func (_cogl_fixed_type, G_TYPE_INT, - cogl_value_transform_fixed_int); - g_value_register_transform_func (G_TYPE_INT, _cogl_fixed_type, - cogl_value_transform_int_fixed); - - g_value_register_transform_func (_cogl_fixed_type, G_TYPE_FLOAT, - cogl_value_transform_fixed_float); - g_value_register_transform_func (G_TYPE_FLOAT, _cogl_fixed_type, - cogl_value_transform_float_fixed); - - g_value_register_transform_func (_cogl_fixed_type, G_TYPE_DOUBLE, - cogl_value_transform_fixed_double); - g_value_register_transform_func (G_TYPE_DOUBLE, _cogl_fixed_type, - cogl_value_transform_double_fixed); - } - - return _cogl_fixed_type; -} - -unsigned int -_cogl_util_one_at_a_time_mix (unsigned int hash) -{ - hash += ( hash << 3 ); - hash ^= ( hash >> 11 ); - hash += ( hash << 15 ); - - return hash; -} - -/* The 'ffs' function is part of C99 so it isn't always available */ -#ifndef HAVE_FFS - -int -_cogl_util_ffs (int num) -{ - int i = 1; - - if (num == 0) - return 0; - - while ((num & 1) == 0) - { - num >>= 1; - i++; - } - - return i; -} - -#endif /* HAVE_FFS */ diff --git a/clutter/cogl/cogl/cogl-util.h b/clutter/cogl/cogl/cogl-util.h deleted file mode 100644 index e32fcd6..0000000 --- a/clutter/cogl/cogl/cogl-util.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_UTIL_H -#define __COGL_UTIL_H - -#include -#include - -int -_cogl_util_next_p2 (int a); - -/* The signbit macro is defined by ISO C99 so it should be available, - however if it's not we can fallback to an evil hack */ -#ifdef signbit -#define cogl_util_float_signbit(x) signbit(x) -#else -/* This trick was stolen from here: - http://lists.boost.org/Archives/boost/2006/08/108731.php - - It xors the integer reinterpretations of -1.0f and 1.0f. In theory - they should only differ by the signbit so that gives a mask for the - sign which we can just test against the value */ -static inline gboolean -cogl_util_float_signbit (float x) -{ - static const union { float f; guint32 i; } negative_one = { -1.0f }; - static const union { float f; guint32 i; } positive_one = { +1.0f }; - union { float f; guint32 i; } value = { x }; - - return !!((negative_one.i ^ positive_one.i) & value.i); -} -#endif - -/* This is a replacement for the nearbyint function which always - rounds to the nearest integer. nearbyint is apparently a C99 - function so it might not always be available but also it seems in - glibc it is defined as a function call so this macro could end up - faster anyway. We can't just add 0.5f because it will break for - negative numbers. */ -#define COGL_UTIL_NEARBYINT(x) ((int) ((x) < 0.0f ? (x) - 0.5f : (x) + 0.5f)) - -/* Returns whether the given integer is a power of two */ -static inline gboolean -_cogl_util_is_pot (unsigned int num) -{ - /* Make sure there is only one bit set */ - return (num & (num - 1)) == 0; -} - -/* Split Bob Jenkins' One-at-a-Time hash - * - * This uses the One-at-a-Time hash algorithm designed by Bob Jenkins - * but the mixing step is split out so the function can be used in a - * more incremental fashion. - */ -static inline unsigned int -_cogl_util_one_at_a_time_hash (unsigned int hash, - void *key, - size_t bytes) -{ - unsigned char *p = key; - int i; - - for (i = 0; i < bytes; i++) - { - hash += p[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - return hash; -} - -unsigned int -_cogl_util_one_at_a_time_mix (unsigned int hash); - -/* The 'ffs' function is part of C99 so it isn't always available */ -#ifdef HAVE_FFS -#define _cogl_util_ffs ffs -#else -int -_cogl_util_ffs (int num); -#endif - -#endif /* __COGL_UTIL_H */ diff --git a/clutter/cogl/cogl/cogl-vector.c b/clutter/cogl/cogl/cogl-vector.c deleted file mode 100644 index 7436053..0000000 --- a/clutter/cogl/cogl/cogl-vector.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#include -#include - -#include -#include -#include - -void -cogl_vector3_init (CoglVector3 *vector, float x, float y, float z) -{ - vector->x = x; - vector->y = y; - vector->z = z; -} - -void -cogl_vector3_init_zero (CoglVector3 *vector) -{ - memset (vector, 0, sizeof (CoglVector3)); -} - -gboolean -cogl_vector3_equal (gconstpointer v1, gconstpointer v2) -{ - CoglVector3 *vector0 = (CoglVector3 *)v1; - CoglVector3 *vector1 = (CoglVector3 *)v2; - - g_return_val_if_fail (v1 != NULL, FALSE); - g_return_val_if_fail (v2 != NULL, FALSE); - - /* There's no point picking an arbitrary epsilon that's appropriate - * for comparing the components so we just use == that will at least - * consider -0 and 0 to be equal. */ - return - vector0->x == vector1->x && - vector0->y == vector1->y && - vector0->z == vector1->z; -} - -gboolean -cogl_vector3_equal_with_epsilon (const CoglVector3 *vector0, - const CoglVector3 *vector1, - float epsilon) -{ - g_return_val_if_fail (vector0 != NULL, FALSE); - g_return_val_if_fail (vector1 != NULL, FALSE); - - if (fabsf (vector0->x - vector1->x) < epsilon && - fabsf (vector0->y - vector1->y) < epsilon && - fabsf (vector0->z - vector1->z) < epsilon) - return TRUE; - else - return FALSE; -} - -CoglVector3 * -cogl_vector3_copy (const CoglVector3 *vector) -{ - if (vector) - return g_slice_dup (CoglVector3, vector); - return NULL; -} - -void -cogl_vector3_free (CoglVector3 *vector) -{ - g_slice_free (CoglVector3, vector); -} - -void -cogl_vector3_invert (CoglVector3 *vector) -{ - vector->x = -vector->x; - vector->y = -vector->y; - vector->z = -vector->z; -} - -void -cogl_vector3_add (CoglVector3 *result, - const CoglVector3 *a, - const CoglVector3 *b) -{ - result->x = a->x + b->x; - result->y = a->y + b->y; - result->z = a->z + b->z; -} - -void -cogl_vector3_subtract (CoglVector3 *result, - const CoglVector3 *a, - const CoglVector3 *b) -{ - result->x = a->x - b->x; - result->y = a->y - b->y; - result->z = a->z - b->z; -} - -void -cogl_vector3_multiply_scalar (CoglVector3 *vector, - float scalar) -{ - vector->x *= scalar; - vector->y *= scalar; - vector->z *= scalar; -} - -void -cogl_vector3_divide_scalar (CoglVector3 *vector, - float scalar) -{ - float one_over_scalar = 1.0f / scalar; - vector->x *= one_over_scalar; - vector->y *= one_over_scalar; - vector->z *= one_over_scalar; -} - -void -cogl_vector3_normalize (CoglVector3 *vector) -{ - float mag_squared = - vector->x * vector->x + - vector->y * vector->y + - vector->z * vector->z; - - if (mag_squared > 0.0f) - { - float one_over_mag = 1.0f / sqrtf (mag_squared); - vector->x *= one_over_mag; - vector->y *= one_over_mag; - vector->z *= one_over_mag; - } -} - -float -cogl_vector3_magnitude (const CoglVector3 *vector) -{ - return sqrtf (vector->x * vector->x + - vector->y * vector->y + - vector->z * vector->z); -} - -void -cogl_vector3_cross_product (CoglVector3 *result, - const CoglVector3 *a, - const CoglVector3 *b) -{ - CoglVector3 tmp; - - tmp.x = a->y * b->z - a->z * b->y; - tmp.y = a->z * b->x - a->x * b->z; - tmp.z = a->x * b->y - a->y * b->x; - *result = tmp; -} - -float -cogl_vector3_dot_product (const CoglVector3 *a, const CoglVector3 *b) -{ - return a->x * b->x + a->y * b->y + a->z * b->z; -} - -float -cogl_vector3_distance (const CoglVector3 *a, const CoglVector3 *b) -{ - float dx = b->x - a->x; - float dy = b->y - a->y; - float dz = b->z - a->z; - - return sqrtf (dx * dx + dy * dy + dz * dz); -} - -#if 0 -void -cogl_vector4_init (CoglVector4 *vector, float x, float y, float z) -{ - vector->x = x; - vector->y = y; - vector->z = z; - vector->w = w; -} - -void -cogl_vector4_init_zero (CoglVector4 *vector) -{ - memset (vector, 0, sizeof (CoglVector4)); -} - -void -cogl_vector4_init_from_vector4 (CoglVector4 *vector, CoglVector4 *src) -{ - *vector4 = *src; -} - -gboolean -cogl_vector4_equal (gconstpointer *v0, gconstpointer *v1) -{ - g_return_val_if_fail (v1 != NULL, FALSE); - g_return_val_if_fail (v2 != NULL, FALSE); - - return memcmp (v1, v2, sizeof (float) * 4) == 0 ? TRUE : FALSE; -} - -CoglVector4 * -cogl_vector4_copy (CoglVector4 *vector) -{ - if (vector) - return g_slice_dup (CoglVector4, vector); - return NULL; -} - -void -cogl_vector4_free (CoglVector4 *vector) -{ - g_slice_free (CoglVector4, vector); -} - -void -cogl_vector4_invert (CoglVector4 *vector) -{ - vector.x = -vector.x; - vector.y = -vector.y; - vector.z = -vector.z; - vector.w = -vector.w; -} - -void -cogl_vector4_add (CoglVector4 *result, - CoglVector4 *a, - CoglVector4 *b) -{ - result.x = a.x + b.x; - result.y = a.y + b.y; - result.z = a.z + b.z; - result.w = a.w + b.w; -} - -void -cogl_vector4_subtract (CoglVector4 *result, - CoglVector4 *a, - CoglVector4 *b) -{ - result.x = a.x - b.x; - result.y = a.y - b.y; - result.z = a.z - b.z; - result.w = a.w - b.w; -} - -void -cogl_vector4_divide (CoglVector4 *vector, - float scalar) -{ - float one_over_scalar = 1.0f / scalar; - result.x *= one_over_scalar; - result.y *= one_over_scalar; - result.z *= one_over_scalar; - result.w *= one_over_scalar; -} - -#endif diff --git a/clutter/cogl/cogl/cogl-vector.h b/clutter/cogl/cogl/cogl-vector.h deleted file mode 100644 index 22307c5..0000000 --- a/clutter/cogl/cogl/cogl-vector.h +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_VECTOR_H -#define __COGL_VECTOR_H - -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-vector - * @short_description: Functions for handling single precision float - * vectors. - * - * This exposes a utility API that can be used for basic manipulation of 3 - * component float vectors. - */ - -/* All of the cogl-vector API is currently experimental so we - * suffix the actual symbols with _EXP so if somone is monitoring for - * ABI changes it will hopefully be clearer to them what's going on if - * any of the symbols dissapear at a later date. - */ -#define cogl_vector3_init cogl_vector3_init_EXP -#define cogl_vector3_init_zero cogl_vector3_init_zero_EXP -#define cogl_vector3_equal cogl_vector3_equal_EXP -#define cogl_vector3_equal_with_epsilon cogl_vector3_equal_with_epsilon_EXP -#define cogl_vector3_copy cogl_vector3_copy_EXP -#define cogl_vector3_free cogl_vector3_free_EXP -#define cogl_vector3_invert cogl_vector3_invert_EXP -#define cogl_vector3_add cogl_vector3_add_EXP -#define cogl_vector3_subtract cogl_vector3_subtract_EXP -#define cogl_vector3_multiply_scalar cogl_vector3_multiply_scalar_EXP -#define cogl_vector3_divide_scalar cogl_vector3_divide_scalar_EXP -#define cogl_vector3_normalize cogl_vector3_normalize_EXP -#define cogl_vector3_magnitude cogl_vector3_magnitude_EXP -#define cogl_vector3_cross_product cogl_vector3_cross_product_EXP -#define cogl_vector3_dot_product cogl_vector3_dot_product_EXP -#define cogl_vector3_distance cogl_vector3_distance_EXP - -typedef struct -{ - /* FIXME: add sse alignment constraint? */ - float x; - float y; - float z; -} CoglVector3; - -#if 0 -typedef struct -{ - /* FIXME: add sse alignment constraint? */ - float x; - float y; - float z; - float w; -} CoglVector4; -#endif - -/** - * cogl_vector3_init: - * @vector: The CoglVector3 you want to initialize - * @x: The x component - * @y: The y component - * @z: The z component - * - * Initializes a 3 component, single precision float vector which can - * then be manipulated with the cogl_vector convenience APIs. Vectors - * can also be used in places where a "point" is often desired. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_init (CoglVector3 *vector, float x, float y, float z); - -/** - * cogl_vector3_init_zero: - * @vector: The CoglVector3 you want to initialize - * - * Initializes a 3 component, single precision float vector with zero - * for each component. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_init_zero (CoglVector3 *vector); - -/** - * cogl_vector3_equal: - * @v1: The first CoglVector3 you want to compare - * @v2: The second CoglVector3 you want to compare - * - * Compares the components of two vectors and returns TRUE if they are - * the same. - * - * The comparison of the components is done with the '==' operator - * such that -0 is considered equal to 0, but otherwise there is no - * fuzziness such as an epsilon to consider vectors that are - * essentially identical except for some minor precision error - * differences due to the way they have been manipulated. - * - * Returns: TRUE if the vectors are equal else FALSE. - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_vector3_equal (gconstpointer v1, gconstpointer v2); - -/** - * cogl_vector3_equal_with_epsilon: - * @vector0: The first CoglVector3 you want to compare - * @vector1: The second CoglVector3 you want to compare - * @epsilon: The allowable difference between components to still be - * considered equal - * - * Compares the components of two vectors using the given epsilon and - * returns TRUE if they are the same, using an internal epsilon for - * comparing the floats. - * - * Each component is compared against the epsilon value in this way: - * |[ - * if (fabsf (vector0->x - vector1->x) < epsilon) - * ]| - * - * Returns: TRUE if the vectors are equal else FALSE. - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_vector3_equal_with_epsilon (const CoglVector3 *vector0, - const CoglVector3 *vector1, - float epsilon); - -/** - * cogl_vector3_copy: - * @vector: The CoglVector3 you want to copy - * - * Allocates a new #CoglVector3 structure on the heap initializing the - * components from the given @vector and returns a pointer to the newly - * allocated vector. You should free the memory using - * cogl_vector3_free() - * - * Returns: A newly allocated #CoglVector3. - * - * Since: 1.4 - * Stability: Unstable - */ -CoglVector3 * -cogl_vector3_copy (const CoglVector3 *vector); - -/** - * cogl_vector3_free: - * @vector: The CoglVector3 you want to free - * - * Frees a #CoglVector3 that was previously allocated with - * cogl_vector_copy() - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_free (CoglVector3 *vector); - -/** - * cogl_vector3_invert: - * @vector: The CoglVector3 you want to manipulate - * - * Inverts/negates all the components of the given @vector. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_invert (CoglVector3 *vector); - -/** - * cogl_vector3_add: - * @result: Where you want the result written - * @a: The first vector operand - * @b: The second vector operand - * - * Adds each of the corresponding components in vectors @a and @b - * storing the results in @result. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_add (CoglVector3 *result, - const CoglVector3 *a, - const CoglVector3 *b); - -/** - * cogl_vector3_subtract: - * @result: Where you want the result written - * @a: The first vector operand - * @b: The second vector operand - * - * Subtracts each of the corresponding components in vector @b from - * @a storing the results in @result. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_subtract (CoglVector3 *result, - const CoglVector3 *a, - const CoglVector3 *b); - -/** - * cogl_vector3_multiply_scalar: - * @vector: The CoglVector3 you want to manipulate - * @scalar: The scalar you want to multiply the vector components by - * - * Multiplies each of the @vector components by the given scalar. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_multiply_scalar (CoglVector3 *vector, - float scalar); - -/** - * cogl_vector3_divide_scalar: - * @vector: The CoglVector3 you want to manipulate - * @scalar: The scalar you want to divide the vector components by - * - * Divides each of the @vector components by the given scalar. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_divide_scalar (CoglVector3 *vector, - float scalar); - -/** - * cogl_vector3_normalize: - * @vector: The CoglVector3 you want to manipulate - * - * Updates the vector so it is a "unit vector" such that the - * @vectors magnitude or length is equal to 1. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_normalize (CoglVector3 *vector); - -/** - * cogl_vector3_magnitude: - * @vector: The CoglVector3 you want the magnitude for - * - * Calculates the scalar magnitude or length of @vector. - * - * Returns: The magnitude of @vector. - * - * Since: 1.4 - * Stability: Unstable - */ -float -cogl_vector3_magnitude (const CoglVector3 *vector); - -/** - * cogl_vector3_cross_product: - * @result: Where you want the result written - * @u: Your first CoglVector3 - * @v: Your second CoglVector3 - * - * Calculates the cross product between the two vectors @u and @v. - * - * The cross product is a vector perpendicular to both @u and @v. This - * can be useful for calculating the normal of a polygon by creating - * two vectors in its plane using the polygons vertices and taking - * their cross product. - * - * If the two vectors are parallel then the cross product is 0. - * - * You can use a right hand rule to determine which direction the - * perpendicular vector will point: If you place the two vectors tail, - * to tail and imagine grabbing the perpendicular line that extends - * through the common tail with your right hand such that you fingers - * rotate in the direction from @u to @v then the resulting vector - * points along your extended thumb. - * - * Returns: The cross product between two vectors @u and @v. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_cross_product (CoglVector3 *result, - const CoglVector3 *u, - const CoglVector3 *v); - -/** - * cogl_vector3_dot_product: - * @a: Your first CoglVector3 - * @b: Your second CoglVector3 - * - * Calculates the dot product of the two #CoglVector3s. This - * can be used to determine the magnitude of one vector projected onto - * another. (for example a surface normal) - * - * For example if you have a polygon with a given normal vector and - * some other point for which you want to calculate its distance from - * the polygon, you can create a vector between one of the polygon - * vertices and that point and use the dot product to calculate the - * magnitude for that vector but projected onto the normal of the - * polygon. This way you don't just get the distance from the point to - * the edge of the polygon you get the distance from the point to the - * nearest part of the polygon. - * - * If you don't use a unit length normal in the above example - * then you would then also have to divide the result by the magnitude - * of the normal - * - * The dot product is calculated as: - * |[ - * (a->x * b->x + a->y * b->y + a->z * b->z) - * ]| - * - * For reference, the dot product can also be calculated from the - * angle between two vectors as: - * |[ - * |a||b|cos𝜃 - * ]| - * - * Returns: The dot product of two vectors. - * - * Since: 1.4 - * Stability: Unstable - */ -float -cogl_vector3_dot_product (const CoglVector3 *a, const CoglVector3 *b); - -/** - * cogl_vector3_distance: - * @a: The first point - * @b: The second point - * - * If you consider the two given vectors as (x,y,z) points instead - * then this will compute the distance between those two points. - * - * Returns: The distance between two points given as @CoglVector3s - * - * Since: 1.4 - * Stability: Unstable - */ -float -cogl_vector3_distance (const CoglVector3 *a, const CoglVector3 *b); - -G_END_DECLS - -#endif /* __COGL_VECTOR_H */ - diff --git a/clutter/cogl/cogl/cogl-vertex-array-private.h b/clutter/cogl/cogl/cogl-vertex-array-private.h deleted file mode 100644 index f24c7de..0000000 --- a/clutter/cogl/cogl/cogl-vertex-array-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_VERTEX_ARRAY_PRIVATE_H -#define __COGL_VERTEX_ARRAY_PRIVATE_H - -#include "cogl-buffer-private.h" - -struct _CoglVertexArray -{ - CoglBuffer _parent; -}; - -#endif /* __COGL_VERTEX_ARRAY_PRIVATE_H */ - diff --git a/clutter/cogl/cogl/cogl-vertex-array.c b/clutter/cogl/cogl/cogl-vertex-array.c deleted file mode 100644 index 965135c..0000000 --- a/clutter/cogl/cogl/cogl-vertex-array.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-object-private.h" -#include "cogl-vertex-array.h" -#include "cogl-vertex-array-private.h" - -static void _cogl_vertex_array_free (CoglVertexArray *array); - -COGL_BUFFER_DEFINE (VertexArray, vertex_array); - -CoglVertexArray * -cogl_vertex_array_new (gsize bytes, const void *data) -{ - CoglVertexArray *array = g_slice_new (CoglVertexArray); - gboolean use_malloc; - - if (!cogl_features_available (COGL_FEATURE_VBOS)) - use_malloc = TRUE; - else - use_malloc = FALSE; - - /* parent's constructor */ - _cogl_buffer_initialize (COGL_BUFFER (array), - bytes, - use_malloc, - COGL_BUFFER_BIND_TARGET_VERTEX_ARRAY, - COGL_BUFFER_USAGE_HINT_VERTEX_ARRAY, - COGL_BUFFER_UPDATE_HINT_STATIC); - - _cogl_vertex_array_object_new (array); - - if (data) - cogl_buffer_set_data (COGL_BUFFER (array), - 0, - data, - bytes); - return array; -} - -static void -_cogl_vertex_array_free (CoglVertexArray *array) -{ - /* parent's destructor */ - _cogl_buffer_fini (COGL_BUFFER (array)); - - g_slice_free (CoglVertexArray, array); -} - diff --git a/clutter/cogl/cogl/cogl-vertex-array.h b/clutter/cogl/cogl/cogl-vertex-array.h deleted file mode 100644 index 2d8ddbb..0000000 --- a/clutter/cogl/cogl/cogl-vertex-array.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_VERTEX_ARRAY_H__ -#define __COGL_VERTEX_ARRAY_H__ - -G_BEGIN_DECLS - -/** - * SECTION:cogl-vertex-array - * @short_description: Functions for creating and manipulating vertex arrays - * - * FIXME - */ - -typedef struct _CoglVertexArray CoglVertexArray; - -/** - * cogl_vertex_array_new: - * @bytes: The number of bytes to allocate for vertex attribute data. - * @data: An optional pointer to vertex data to upload immediately. - * - * Declares a new #CoglVertexArray of @size bytes to contain arrays of vertex - * attribute data. Once declared, data can be set using cogl_buffer_set_data() - * or by mapping it into the application's address space using cogl_buffer_map(). - * - * If @data isn't %NULL then @size bytes will be read from @data and - * immediately copied into the new buffer. - * - * Since: 1.4 - * Stability: Unstable - */ -CoglVertexArray * -cogl_vertex_array_new (gsize bytes, - const void *data); - -/** - * cogl_is_vertex_array: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglVertexArray. - * - * Returns: %TRUE if the handle references a #CoglVertexArray, - * %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_is_vertex_array (void *object); - -G_END_DECLS - -#endif /* __COGL_VERTEX_ARRAY_H__ */ - diff --git a/clutter/cogl/cogl/cogl-vertex-buffer-private.h b/clutter/cogl/cogl/cogl-vertex-buffer-private.h deleted file mode 100644 index 096c00b..0000000 --- a/clutter/cogl/cogl/cogl-vertex-buffer-private.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_VERTEX_BUFFER_H -#define __COGL_VERTEX_BUFFER_H - -#include "cogl-handle.h" - -#include "cogl-primitive.h" - -#include - -/* Note we put quite a bit into the flags here to help keep - * the down size of the CoglVertexBufferAttrib struct below. */ -typedef enum _CoglVertexBufferAttribFlags -{ - /* Types */ - /* NB: update the _TYPE_MASK below if these are changed */ - COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY = 1<<0, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY = 1<<1, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY = 1<<2, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY = 1<<3, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY = 1<<4, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID = 1<<5, - - COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED = 1<<6, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED = 1<<7, - - /* Usage hints */ - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT = 1<<8, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT = 1<<9, - - /* GL Data types */ - /* NB: Update the _GL_TYPE_MASK below if these are changed */ - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE = 1<<10, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE = 1<<11, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT = 1<<12, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT = 1<<13, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT = 1<<14, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT = 1<<15, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT = 1<<16, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE = 1<<17, - - COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED = 1<<18, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED = 1<<19 - - /* XXX NB: If we need > 24 bits then look at changing the layout - * of struct _CoglVertexBufferAttrib below */ -} CoglVertexBufferAttribFlags; - -#define COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK \ - (COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) - -typedef struct _CoglVertexBufferAttrib -{ - /* TODO: look at breaking up the flags into seperate - * bitfields and seperate enums */ - CoglVertexBufferAttribFlags flags:24; - guint8 id; - GQuark name; - char *name_without_detail; - union _u - { - const void *pointer; - size_t vbo_offset; - } u; - CoglAttributeType type; - size_t span_bytes; - guint16 stride; - guint8 n_components; - guint8 texture_unit; - - int attribute_first; - CoglAttribute *attribute; - -} CoglVertexBufferAttrib; - -typedef enum _CoglVertexBufferVBOFlags -{ - COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED = 1<<0, - COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK = 1<<1, - - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT = 1<<3, - COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT = 1<<4, - - COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED = 1<<5 -} CoglVertexBufferVBOFlags; - -/* - * A CoglVertexBufferVBO represents one or more attributes in a single - * buffer object - */ -typedef struct _CoglVertexBufferVBO -{ - CoglVertexBufferVBOFlags flags; - - CoglVertexArray *array; - size_t array_bytes; - - GList *attributes; -} CoglVertexBufferVBO; - -typedef struct _CoglVertexBufferIndices -{ - CoglHandleObject _parent; - - CoglIndices *indices; -} CoglVertexBufferIndices; - -typedef struct _CoglVertexBuffer -{ - CoglHandleObject _parent; - - int n_vertices; /*!< The number of vertices in the buffer */ - GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ - - /* Note: new_attributes is normally NULL and only valid while - * modifying a buffer. */ - GList *new_attributes; /*!< attributes pending submission */ - - gboolean dirty_attributes; - - CoglPrimitive *primitive; - -} CoglVertexBuffer; - -CoglVertexBuffer * -_cogl_vertex_buffer_pointer_from_handle (CoglHandle handle); - -CoglVertexBufferIndices * -_cogl_vertex_buffer_indices_pointer_from_handle (CoglHandle handle); - -#endif /* __COGL_VERTEX_BUFFER_H */ - diff --git a/clutter/cogl/cogl/cogl-vertex-buffer.c b/clutter/cogl/cogl/cogl-vertex-buffer.c deleted file mode 100644 index 514cb7a..0000000 --- a/clutter/cogl/cogl/cogl-vertex-buffer.c +++ /dev/null @@ -1,1772 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -/* XXX: For an overview of the functionality implemented here, please - * see cogl-vertex-buffer.h, which contains the gtk-doc section overview - * for the Vertex Buffers API. - */ - -/* - * TODO: We need to do a better job of minimizing when we call glVertexPointer - * and pals in enable_state_for_drawing_buffer - * - * We should have an internal 2-tuple cache of (VBO, offset) for each of them - * so we can avoid some GL calls. We could have cogl wrappers for the - * gl*Pointer funcs that look like this: - * - * cogl_vertex_pointer (n_components, gl_type, stride, vbo, offset); - * cogl_color_pointer (n_components, gl_type, stride, vbo, offset); - * - * They would also accept NULL for the VBO handle to support old style vertex - * arrays. - * - * TODO: - * Actually hook this up to the cogl shaders infrastructure. The vertex - * buffer API has been designed to allow adding of arbitrary attributes for use - * with shaders, but this has yet to be actually plumbed together and tested. - * The bits we are missing: - * - cogl_program_use doesn't currently record within ctx-> which program - * is currently in use so a.t.m only Clutter knows the current shader. - * - We don't query the current shader program for the generic vertex indices - * (using glGetAttribLocation) so that we can call glEnableVertexAttribArray - * with those indices. - * (currently we just make up consecutive indices) - * - some dirty flag mechanims to know when the shader program has changed - * so we don't need to re-query it each time we draw a buffer. - * - * TODO - * Expose API that lets developers get back a buffer handle for a particular - * polygon so they may add custom attributes to them. - * - It should be possible to query/modify attributes efficiently, in place, - * avoiding copies. It would not be acceptable to simply require that - * developers must query back the n_vertices of a buffer and then the - * n_components, type and stride etc of each attribute since there - * would be too many combinations to realistically handle. - * - * - In practice, some cases might be best solved with a higher level - * EditableMesh API, (see futher below) but for many cases I think an - * API like this might be appropriate: - * - * cogl_vertex_buffer_foreach_vertex (buffer_handle, - * (AttributesBufferIteratorFunc)callback, - * "gl_Vertex", "gl_Color", NULL); - * static void callback (CoglVertexBufferVertex *vert) - * { - * GLfloat *pos = vert->attrib[0]; - * GLubyte *color = vert->attrib[1]; - * GLfloat *new_attrib = buf[vert->index]; - * - * new_attrib = pos*color; - * } - * - * TODO - * Think about a higher level Mesh API for building/modifying attribute buffers - * - E.g. look at Blender for inspiration here. They can build a mesh from - * "MVert", "MFace" and "MEdge" primitives. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-vertex-buffer-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-pipeline-private.h" -#include "cogl-primitives.h" -#include "cogl-framebuffer-private.h" -#include "cogl-journal-private.h" - -#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \ - (VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1))) - -static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer); -static void _cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices); -static CoglUserDataKey _cogl_vertex_buffer_pipeline_priv_key; - -COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (vertex_buffer); -COGL_HANDLE_DEFINE (VertexBufferIndices, vertex_buffer_indices); - -CoglHandle -cogl_vertex_buffer_new (unsigned int n_vertices) -{ - CoglVertexBuffer *buffer = g_slice_alloc (sizeof (CoglVertexBuffer)); - - buffer->n_vertices = n_vertices; - - buffer->submitted_vbos = NULL; - buffer->new_attributes = NULL; - buffer->primitive = cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLES, - n_vertices, NULL); - - /* return COGL_INVALID_HANDLE; */ - return _cogl_vertex_buffer_handle_new (buffer); -} - -unsigned int -cogl_vertex_buffer_get_n_vertices (CoglHandle handle) -{ - CoglVertexBuffer *buffer; - - if (!cogl_is_vertex_buffer (handle)) - return 0; - - buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - - return buffer->n_vertices; -} - -/* There are a number of standard OpenGL attributes that we deal with - * specially. These attributes are all namespaced with a "gl_" prefix - * so we should catch any typos instead of silently adding a custom - * attribute. - */ -static CoglVertexBufferAttribFlags -validate_gl_attribute (const char *gl_attribute, - guint8 n_components, - guint8 *texture_unit) -{ - CoglVertexBufferAttribFlags type; - char *detail_seperator = NULL; - int name_len; - - detail_seperator = strstr (gl_attribute, "::"); - if (detail_seperator) - name_len = detail_seperator - gl_attribute; - else - name_len = strlen (gl_attribute); - - if (strncmp (gl_attribute, "Vertex", name_len) == 0) - { - if (G_UNLIKELY (n_components == 1)) - g_critical ("glVertexPointer doesn't allow 1 component vertex " - "positions so we currently only support \"gl_Vertex\" " - "attributes where n_components == 2, 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY; - } - else if (strncmp (gl_attribute, "Color", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3 && n_components != 4)) - g_critical ("glColorPointer expects 3 or 4 component colors so we " - "currently only support \"gl_Color\" attributes where " - "n_components == 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY; - } - else if (strncmp (gl_attribute, - "MultiTexCoord", - strlen ("MultiTexCoord")) == 0) - { - unsigned int unit; - - if (sscanf (gl_attribute, "MultiTexCoord%u", &unit) != 1) - { - g_warning ("gl_MultiTexCoord attributes should include a\n" - "texture unit number, E.g. gl_MultiTexCoord0\n"); - unit = 0; - } - /* FIXME: validate any '::' delimiter for this case */ - *texture_unit = unit; - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY; - } - else if (strncmp (gl_attribute, "Normal", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3)) - g_critical ("glNormalPointer expects 3 component normals so we " - "currently only support \"gl_Normal\" attributes where " - "n_components == 3"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY; - } - else - { - g_warning ("Unknown gl_* attribute name gl_%s\n", gl_attribute); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID; - } - - return type; -} - -/* There are a number of standard OpenGL attributes that we deal with - * specially. These attributes are all namespaced with a "gl_" prefix - * so we should catch any typos instead of silently adding a custom - * attribute. - */ -static CoglVertexBufferAttribFlags -validate_cogl_attribute (const char *cogl_attribute, - guint8 n_components, - guint8 *texture_unit) -{ - CoglVertexBufferAttribFlags type; - char *detail_seperator = NULL; - int name_len; - - detail_seperator = strstr (cogl_attribute, "::"); - if (detail_seperator) - name_len = detail_seperator - cogl_attribute; - else - name_len = strlen (cogl_attribute); - - if (strncmp (cogl_attribute, "position_in", name_len) == 0) - { - if (G_UNLIKELY (n_components == 1)) - g_critical ("glVertexPointer doesn't allow 1 component vertex " - "positions so we currently only support " - "\"cogl_position_in\" attributes where " - "n_components == 2, 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY; - } - else if (strncmp (cogl_attribute, "color_in", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3 && n_components != 4)) - g_critical ("glColorPointer expects 3 or 4 component colors so we " - "currently only support \"cogl_color_in\" attributes " - "where n_components == 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY; - } - else if (strncmp (cogl_attribute, - "cogl_tex_coord", - strlen ("cogl_tex_coord")) == 0) - { - unsigned int unit; - - if (strcmp (cogl_attribute, "cogl_tex_coord_in") == 0) - unit = 0; - else if (sscanf (cogl_attribute, "cogl_tex_coord%u_in", &unit) != 1) - { - g_warning ("texture coordinate attributes should either be " - "referenced as \"cogl_tex_coord_in\" or with a" - "texture unit number like \"cogl_tex_coord1_in\""); - unit = 0; - } - /* FIXME: validate any '::' delimiter for this case */ - *texture_unit = unit; - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY; - } - else if (strncmp (cogl_attribute, "normal_in", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3)) - g_critical ("glNormalPointer expects 3 component normals so we " - "currently only support \"cogl_normal_in\" attributes " - "where n_components == 3"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY; - } - else - { - g_warning ("Unknown cogl_* attribute name cogl_%s\n", cogl_attribute); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID; - } - - return type; -} - -/* This validates that a custom attribute name is a valid GLSL variable name - * - * NB: attribute names may have a detail component delimited using '::' E.g. - * custom_attrib::foo or custom_attrib::bar - * - * maybe I should hang a compiled regex somewhere to handle this - */ -static gboolean -validate_custom_attribute_name (const char *attribute_name) -{ - char *detail_seperator = NULL; - int name_len; - int i; - - detail_seperator = strstr (attribute_name, "::"); - if (detail_seperator) - name_len = detail_seperator - attribute_name; - else - name_len = strlen (attribute_name); - - if (name_len == 0 - || !g_ascii_isalpha (attribute_name[0]) - || attribute_name[0] != '_') - return FALSE; - - for (i = 1; i < name_len; i++) - if (!g_ascii_isalnum (attribute_name[i]) || attribute_name[i] != '_') - return FALSE; - - return TRUE; -} - -/* Iterates the CoglVertexBufferVBOs of a buffer and creates a flat list - * of all the submitted attributes - * - * Note: The CoglVertexBufferAttrib structs are deep copied, except the - * internal CoglAttribute pointer is set to NULL. - */ -static GList * -copy_submitted_attributes_list (CoglVertexBuffer *buffer) -{ - GList *tmp; - GList *submitted_attributes = NULL; - - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *attribute = tmp2->data; - CoglVertexBufferAttrib *copy = - g_slice_alloc (sizeof (CoglVertexBufferAttrib)); - *copy = *attribute; - copy->name_without_detail = - g_strdup (attribute->name_without_detail); - copy->attribute = NULL; - submitted_attributes = g_list_prepend (submitted_attributes, copy); - } - } - return submitted_attributes; -} - -static size_t -sizeof_attribute_type (CoglAttributeType type) -{ - switch (type) - { - case COGL_ATTRIBUTE_TYPE_BYTE: - return 1; - case COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_ATTRIBUTE_TYPE_SHORT: - return 2; - case COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_ATTRIBUTE_TYPE_FLOAT: - return 4; - } - g_return_val_if_reached (0); -} - -static size_t -strideof (CoglAttributeType type, int n_components) -{ - return sizeof_attribute_type (type) * n_components; -} - -static char * -canonize_attribute_name (const char *attribute_name) -{ - char *detail_seperator = NULL; - int name_len; - - if (strncmp (attribute_name, "gl_", 3) != 0) - return g_strdup (attribute_name); - - /* skip past the "gl_" */ - attribute_name += 3; - - detail_seperator = strstr (attribute_name, "::"); - if (detail_seperator) - name_len = detail_seperator - attribute_name; - else - { - name_len = strlen (attribute_name); - detail_seperator = ""; - } - - if (strncmp (attribute_name, "Vertex", name_len) == 0) - return g_strconcat ("cogl_position_in", detail_seperator, NULL); - else if (strncmp (attribute_name, "Color", name_len) == 0) - return g_strconcat ("cogl_color_in", detail_seperator, NULL); - else if (strncmp (attribute_name, - "MultiTexCoord", - strlen ("MultiTexCoord")) == 0) - { - unsigned int unit; - - if (sscanf (attribute_name, "MultiTexCoord%u", &unit) != 1) - { - g_warning ("gl_MultiTexCoord attributes should include a\n" - "texture unit number, E.g. gl_MultiTexCoord0\n"); - unit = 0; - } - return g_strdup_printf ("cogl_tex_coord%u_in%s", - unit, detail_seperator); - } - else if (strncmp (attribute_name, "Normal", name_len) == 0) - return g_strconcat ("cogl_normal_in", detail_seperator, NULL); - else - { - g_warning ("Unknown gl_* attribute name gl_%s\n", attribute_name); - return g_strdup (attribute_name); - } -} - -void -cogl_vertex_buffer_add (CoglHandle handle, - const char *attribute_name, - guint8 n_components, - CoglAttributeType type, - gboolean normalized, - guint16 stride, - const void *pointer) -{ - CoglVertexBuffer *buffer; - char *cogl_attribute_name; - GQuark name_quark; - gboolean modifying_an_attrib = FALSE; - CoglVertexBufferAttrib *attribute; - CoglVertexBufferAttribFlags flags = 0; - guint8 texture_unit = 0; - GList *tmp; - char *detail; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - buffer->dirty_attributes = TRUE; - - cogl_attribute_name = canonize_attribute_name (attribute_name); - name_quark = g_quark_from_string (cogl_attribute_name); - - /* The submit function works by diffing between submitted_attributes - * and new_attributes to minimize the upload bandwidth + cost of - * allocating new VBOs, so if there isn't already a list of new_attributes - * we create one: */ - if (!buffer->new_attributes) - buffer->new_attributes = copy_submitted_attributes_list (buffer); - - /* Note: we first look for an existing attribute that we are modifying - * so we may skip needing to validate the name */ - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *submitted_attribute = tmp->data; - if (submitted_attribute->name == name_quark) - { - modifying_an_attrib = TRUE; - - attribute = submitted_attribute; - - /* since we will skip validate_gl/cogl_attribute in this case, we - * need to pluck out the attribute type before overwriting the - * flags: */ - flags |= - attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; - break; - } - } - - if (!modifying_an_attrib) - { - /* Validate the attribute name, is suitable as a variable name */ - if (strncmp (attribute_name, "gl_", 3) == 0) - { - /* Note: we pass the original attribute name here so that - * any warning messages correspond to the users original - * attribute name... */ - flags |= validate_gl_attribute (attribute_name + 3, - n_components, - &texture_unit); - if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) - return; - } - else if (strncmp (attribute_name, "cogl_", 5) == 0) - { - flags |= validate_cogl_attribute (attribute_name + 5, - n_components, - &texture_unit); - if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) - return; - } - else - { - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY; - if (validate_custom_attribute_name (attribute_name)) - return; - } - - attribute = g_slice_alloc0 (sizeof (CoglVertexBufferAttrib)); - } - - attribute->name = name_quark; - detail = strstr (cogl_attribute_name, "::"); - if (detail) - attribute->name_without_detail = g_strndup (cogl_attribute_name, - detail - cogl_attribute_name); - else - attribute->name_without_detail = g_strdup (cogl_attribute_name); - attribute->type = type; - attribute->n_components = n_components; - if (stride == 0) - stride = strideof (type, n_components); - attribute->stride = stride; - attribute->u.pointer = pointer; - attribute->texture_unit = texture_unit; - attribute->attribute = NULL; - - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - - /* Note: We currently just assume, if an attribute is *ever* updated - * then it should be taged as frequently changing. */ - if (modifying_an_attrib) - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT; - else - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT; - - if (normalized) - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED; - attribute->flags = flags; - - attribute->span_bytes = buffer->n_vertices * attribute->stride; - - if (!modifying_an_attrib) - buffer->new_attributes = - g_list_prepend (buffer->new_attributes, attribute); - - g_free (cogl_attribute_name); -} - -static void -_cogl_vertex_buffer_attrib_free (CoglVertexBufferAttrib *attribute) -{ - if (attribute->attribute) - cogl_object_unref (attribute->attribute); - g_free (attribute->name_without_detail); - g_slice_free (CoglVertexBufferAttrib, attribute); -} - -void -cogl_vertex_buffer_delete (CoglHandle handle, - const char *attribute_name) -{ - CoglVertexBuffer *buffer; - char *cogl_attribute_name = canonize_attribute_name (attribute_name); - GQuark name = g_quark_from_string (cogl_attribute_name); - GList *tmp; - - g_free (cogl_attribute_name); - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - buffer->dirty_attributes = TRUE; - - /* The submit function works by diffing between submitted_attributes - * and new_attributes to minimize the upload bandwidth + cost of - * allocating new VBOs, so if there isn't already a list of new_attributes - * we create one: */ - if (!buffer->new_attributes) - buffer->new_attributes = copy_submitted_attributes_list (buffer); - - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *submitted_attribute = tmp->data; - if (submitted_attribute->name == name) - { - buffer->new_attributes = - g_list_delete_link (buffer->new_attributes, tmp); - _cogl_vertex_buffer_attrib_free (submitted_attribute); - return; - } - } - - g_warning ("Failed to find an attribute named %s to delete\n", - attribute_name); -} - -static void -set_attribute_enable (CoglHandle handle, - const char *attribute_name, - gboolean state) -{ - CoglVertexBuffer *buffer; - char *cogl_attribute_name = canonize_attribute_name (attribute_name); - GQuark name_quark = g_quark_from_string (cogl_attribute_name); - GList *tmp; - - g_free (cogl_attribute_name); - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - buffer->dirty_attributes = TRUE; - - /* NB: If a buffer is currently being edited, then there can be two seperate - * lists of attributes; those that are currently submitted and a new list yet - * to be submitted, we need to modify both. */ - - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - if (attribute->name == name_quark) - { - if (state) - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - else - attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - break; - } - } - - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *attribute = tmp2->data; - if (attribute->name == name_quark) - { - if (state) - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - else - attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - return; - } - } - } - - g_warning ("Failed to %s attribute named %s/%s\n", - state == TRUE ? "enable" : "disable", - attribute_name, cogl_attribute_name); -} - -void -cogl_vertex_buffer_enable (CoglHandle handle, - const char *attribute_name) -{ - set_attribute_enable (handle, attribute_name, TRUE); -} - -void -cogl_vertex_buffer_disable (CoglHandle handle, - const char *attribute_name) -{ - set_attribute_enable (handle, attribute_name, FALSE); -} - -/* Given an attribute that we know has already been submitted before, this - * function looks for the existing VBO that contains it. - * - * Note: It will free redundant attribute struct once the corresponding - * VBO has been found. - */ -static void -filter_already_submitted_attribute (CoglVertexBufferAttrib *attribute, - GList **reuse_vbos, - GList **submitted_vbos) -{ - GList *tmp; - - /* First check the cogl_vbos we already know are being reused since we - * are more likley to get a match here */ - for (tmp = *reuse_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - - if (vbo_attribute->name == attribute->name) - { - vbo_attribute->flags &= - ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; - /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in - * cogl_vertex_buffer_submit */ - return; - } - } - } - - for (tmp = *submitted_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - CoglVertexBufferAttrib *reuse_attribute = NULL; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - if (vbo_attribute->name == attribute->name) - { - reuse_attribute = vbo_attribute; - /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in - * cogl_vertex_buffer_submit */ - - *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp); - tmp->next = *reuse_vbos; - *reuse_vbos = tmp; - break; - } - } - - if (!reuse_attribute) - continue; - - /* Mark all but the matched attribute as UNUSED, so that when we - * finish filtering all our attributes any attrributes still - * marked as UNUSED can be removed from their cogl_vbo */ - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - if (vbo_attribute != reuse_attribute) - vbo_attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; - } - - return; - } - - g_critical ("Failed to find the cogl vbo that corresponds to an\n" - "attribute that had apparently already been submitted!"); -} - -/* When we first mark a CoglVertexBufferVBO to be reused, we mark the - * attributes as unsed, so that when filtering of attributes into VBOs is done - * we can then prune the now unsed attributes. */ -static void -remove_unused_attributes (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - GList *next; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - next = tmp->next; - - if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED) - { - cogl_vbo->attributes = - g_list_delete_link (cogl_vbo->attributes, tmp); - g_slice_free (CoglVertexBufferAttrib, attribute); - } - } -} - -/* Give a newly added, strided, attribute, this function looks for a - * CoglVertexBufferVBO that the attribute is interleved with. If it can't - * find one then a new CoglVertexBufferVBO is allocated and added to the - * list of new_strided_vbos. - */ -static void -filter_strided_attribute (CoglVertexBufferAttrib *attribute, - GList **new_vbos) -{ - GList *tmp; - CoglVertexBufferVBO *new_cogl_vbo; - - for (tmp = *new_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - if (!(cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED)) - continue; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - const char *attribute_start = attribute->u.pointer; - const char *vbo_attribute_start = vbo_attribute->u.pointer; - - /* NB: All attributes have buffer->n_vertices values which - * simplifies determining which attributes are interleved - * since we assume they will start no farther than +- a - * stride away from each other: - */ - if (attribute_start <= (vbo_attribute_start - vbo_attribute->stride) - || attribute_start - >= (vbo_attribute_start + vbo_attribute->stride)) - continue; /* Not interleved */ - - cogl_vbo->attributes = - g_list_prepend (cogl_vbo->attributes, attribute); - - if (attribute->flags & - COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) - { - cogl_vbo->flags &= - ~COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; - cogl_vbo->flags |= - COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; - } - return; - } - } - new_cogl_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); - new_cogl_vbo->attributes = NULL; - new_cogl_vbo->attributes = - g_list_prepend (new_cogl_vbo->attributes, attribute); - /* Any one of the interleved attributes will have the same span_bytes */ - new_cogl_vbo->array = NULL; - new_cogl_vbo->array_bytes = attribute->span_bytes; - new_cogl_vbo->flags = COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED; - - if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT) - new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; - else - new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; - - *new_vbos = g_list_prepend (*new_vbos, new_cogl_vbo); - return; -} - -/* This iterates through the list of submitted VBOs looking for one that - * contains attribute. If found the list *link* is removed and returned */ -static GList * -unlink_submitted_vbo_containing_attribute (GList **submitted_vbos, - CoglVertexBufferAttrib *attribute) -{ - GList *tmp; - GList *next = NULL; - - for (tmp = *submitted_vbos; tmp != NULL; tmp = next) - { - CoglVertexBufferVBO *submitted_vbo = tmp->data; - GList *tmp2; - - next = tmp->next; - - for (tmp2 = submitted_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *submitted_attribute = tmp2->data; - - if (submitted_attribute->name == attribute->name) - { - *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp); - return tmp; - } - } - } - - return NULL; -} - -/* Unlinks all the submitted VBOs that conflict with the new cogl_vbo and - * returns them as a list. */ -static GList * -get_submitted_vbo_conflicts (GList **submitted_vbos, - CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - GList *conflicts = NULL; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - GList *link = - unlink_submitted_vbo_containing_attribute (submitted_vbos, - tmp->data); - if (link) - { - /* prepend the link to the list of conflicts: */ - link->next = conflicts; - conflicts = link; - } - } - return conflicts; -} - -/* Any attributes in cogl_vbo gets removed from conflict_vbo */ -static void -disassociate_conflicting_attributes (CoglVertexBufferVBO *conflict_vbo, - CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - - /* NB: The attributes list in conflict_vbo will be shrinking so - * we iterate those in the inner loop. */ - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - GList *tmp2; - for (tmp2 = conflict_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *conflict_attribute = tmp2->data; - - if (conflict_attribute->name == attribute->name) - { - _cogl_vertex_buffer_attrib_free (conflict_attribute); - conflict_vbo->attributes = - g_list_delete_link (conflict_vbo->attributes, tmp2); - break; - } - } - } -} - -static void -cogl_vertex_buffer_vbo_free (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - _cogl_vertex_buffer_attrib_free (tmp->data); - g_list_free (cogl_vbo->attributes); - - if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED) - cogl_object_unref (cogl_vbo->array); - - g_slice_free (CoglVertexBufferVBO, cogl_vbo); -} - -/* This figures out the lowest attribute client pointer. (This pointer is used - * to upload all the interleved attributes). - * - * In the process it also replaces the client pointer with the attributes - * offset, and marks the attribute as submitted. - */ -static const void * -prep_strided_vbo_for_upload (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - const char *lowest_pointer = NULL; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - const char *client_pointer = attribute->u.pointer; - - if (!lowest_pointer || client_pointer < lowest_pointer) - lowest_pointer = client_pointer; - } - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - const char *client_pointer = attribute->u.pointer; - attribute->u.vbo_offset = client_pointer - lowest_pointer; - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; - } - - return lowest_pointer; -} - -static gboolean -upload_multipack_vbo_via_map_buffer (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - unsigned int offset = 0; - guint8 *buf; - - _COGL_GET_CONTEXT (ctx, FALSE); - - buf = cogl_buffer_map (COGL_BUFFER (cogl_vbo->array), - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - if (!buf) - return FALSE; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - gsize attribute_size = attribute->span_bytes; - gsize type_size = sizeof_attribute_type (attribute->type); - - PAD_FOR_ALIGNMENT (offset, type_size); - - memcpy (buf + offset, attribute->u.pointer, attribute_size); - - attribute->u.vbo_offset = offset; - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; - offset += attribute_size; - } - - cogl_buffer_unmap (COGL_BUFFER (cogl_vbo->array)); - - return TRUE; -} - -static void -upload_multipack_vbo_via_buffer_sub_data (CoglVertexBufferVBO *cogl_vbo) -{ - GList *l; - unsigned int offset = 0; - - for (l = cogl_vbo->attributes; l != NULL; l = l->next) - { - CoglVertexBufferAttrib *attribute = l->data; - gsize attribute_size = attribute->span_bytes; - gsize type_size = sizeof_attribute_type (attribute->type); - - PAD_FOR_ALIGNMENT (offset, type_size); - - cogl_buffer_set_data (COGL_BUFFER (cogl_vbo->array), - offset, - attribute->u.pointer, - attribute_size); - - attribute->u.vbo_offset = offset; - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; - offset += attribute_size; - } -} - -static void -upload_attributes (CoglVertexBufferVBO *cogl_vbo) -{ - CoglBufferUpdateHint usage; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT) - usage = COGL_BUFFER_UPDATE_HINT_DYNAMIC; - else - usage = COGL_BUFFER_UPDATE_HINT_STATIC; - cogl_buffer_set_update_hint (COGL_BUFFER (cogl_vbo->array), usage); - - if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED) - { - const void *pointer = prep_strided_vbo_for_upload (cogl_vbo); - cogl_buffer_set_data (COGL_BUFFER (cogl_vbo->array), - 0, /* offset */ - pointer, - cogl_vbo->array_bytes); - } - else /* MULTIPACK */ - { - /* I think it might depend on the specific driver/HW whether its better - * to use glMapBuffer here or glBufferSubData here. There is even a good - * thread about this topic here: - * http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg35004.html - * For now I have gone with glMapBuffer, but the jury is still out. - */ - - if (!upload_multipack_vbo_via_map_buffer (cogl_vbo)) - upload_multipack_vbo_via_buffer_sub_data (cogl_vbo); - } - - cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED; -} - -/* Note: although there ends up being quite a few inner loops involved with - * resolving buffers, the number of attributes will be low so I don't expect - * them to cause a problem. */ -static void -cogl_vertex_buffer_vbo_resolve (CoglVertexBuffer *buffer, - CoglVertexBufferVBO *new_cogl_vbo, - GList **final_vbos) -{ - GList *conflicts; - GList *tmp; - GList *next; - gboolean found_target_vbo = FALSE; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - conflicts = - get_submitted_vbo_conflicts (&buffer->submitted_vbos, new_cogl_vbo); - - for (tmp = conflicts; tmp != NULL; tmp = next) - { - CoglVertexBufferVBO *conflict_vbo = tmp->data; - - next = tmp->next; - - disassociate_conflicting_attributes (conflict_vbo, new_cogl_vbo); - - if (!conflict_vbo->attributes) - { - /* See if we can re-use this now empty VBO: */ - - if (!found_target_vbo - && conflict_vbo->array_bytes == new_cogl_vbo->array_bytes) - { - found_target_vbo = TRUE; - new_cogl_vbo->array = cogl_object_ref (conflict_vbo->array); - cogl_vertex_buffer_vbo_free (conflict_vbo); - - upload_attributes (new_cogl_vbo); - - *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); - } - else - cogl_vertex_buffer_vbo_free (conflict_vbo); - } - else - { - /* Relink the VBO back into buffer->submitted_vbos since it may - * be involved in other conflicts later */ - tmp->next = buffer->submitted_vbos; - tmp->prev = NULL; - buffer->submitted_vbos = tmp; - } - } - - if (!found_target_vbo) - { - new_cogl_vbo->array = cogl_vertex_array_new (new_cogl_vbo->array_bytes, - NULL); - - upload_attributes (new_cogl_vbo); - *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); - } -} - -static void -update_primitive_attributes (CoglVertexBuffer *buffer) -{ - GList *l; - int n_attributes = 0; - CoglAttribute **attributes; - int i; - - if (!buffer->dirty_attributes) - return; - - buffer->dirty_attributes = FALSE; - - for (l = buffer->submitted_vbos; l; l = l->next) - { - CoglVertexBufferVBO *cogl_vbo = l->data; - GList *l2; - - for (l2 = cogl_vbo->attributes; l2; l2 = l2->next, n_attributes++) - ; - } - - g_return_if_fail (n_attributes > 0); - - attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes + 1); - - i = 0; - for (l = buffer->submitted_vbos; l; l = l->next) - { - CoglVertexBufferVBO *cogl_vbo = l->data; - GList *l2; - - for (l2 = cogl_vbo->attributes; l2; l2 = l2->next) - { - CoglVertexBufferAttrib *attribute = l2->data; - if (G_LIKELY (attribute->flags & - COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED)) - { - if (G_UNLIKELY (!attribute->attribute)) - { - attribute->attribute = - cogl_attribute_new (cogl_vbo->array, - attribute->name_without_detail, - attribute->stride, - attribute->u.vbo_offset, - attribute->n_components, - attribute->type); - } - - attributes[i++] = attribute->attribute; - } - } - } - - attributes[i] = NULL; - - cogl_primitive_set_attributes (buffer->primitive, attributes); -} - -static void -cogl_vertex_buffer_submit_real (CoglVertexBuffer *buffer) -{ - GList *tmp; - CoglVertexBufferVBO *new_multipack_vbo; - GList *new_multipack_vbo_link; - GList *new_vbos = NULL; - GList *reuse_vbos = NULL; - GList *final_vbos = NULL; - - if (!buffer->new_attributes) - goto done; - - /* The objective now is to copy the attribute data supplied by the client - * into buffer objects, but it's important to minimize the number of - * redundant data uploads. - * - * We obviously aim to group together the attributes that are interleved so - * that they can be delivered in one go to the driver. - * All BOs for interleved data are created as STATIC_DRAW_ARB. - * - * Non interleved attributes tagged as INFREQUENT_RESUBMIT will be grouped - * together back to back in a single BO created as STATIC_DRAW_ARB - * - * Non interleved attributes tagged as FREQUENT_RESUBMIT will be copied into - * individual buffer objects, and the BO itself created DYNAMIC_DRAW_ARB - * - * If we are modifying a previously submitted CoglVertexBuffer then we are - * carefull not to needlesly delete OpenGL buffer objects and replace with - * new ones, instead we upload new data to the existing buffers. - */ - - /* NB: We must forget attribute->pointer after submitting since the user - * is free to re-use that memory for other purposes now. */ - - /* Pseudo code: - * - * Broadly speaking we start with a list of unsorted attributes, and filter - * those into 'new' and 're-use' CoglVertexBufferVBO (CBO) lists. We then - * take the list of new CBO structs and compare with the CBOs that have - * already been submitted to the GPU (but ignoring those we already know will - * be re-used) to determine what other CBOs can be re-used, due to being - * superseded, and what new GL VBOs need to be created. - * - * We have two kinds of CBOs: - * - Multi Pack CBOs - * These contain multiple attributes tightly packed back to back) - * - Strided CBOs - * These typically contain multiple interleved sets of attributes, - * though they can contain just one attribute with a stride - * - * First create a new-CBOs entry "new-multipack-CBO" - * Tag "new-multipack-CBO" as MULTIPACK + INFREQUENT_RESUBMIT - * For each unsorted attrib: - * if already marked as submitted: - * iterate reuse-CBOs: - * if we find one that contains this attribute: - * free redundant unsorted attrib struct - * remove the UNUSED flag from the attrib found in the reuse-CBO - * continue to next unsorted attrib - * iterate submitted VBOs: - * if we find one that contains this attribute: - * free redundant unsorted attrib struct - * unlink the vbo and move it to the list of reuse-CBOs - * mark all attributes except the one just matched as UNUSED - * assert (found) - * continue to next unsorted attrib - * if strided: - * iterate the new, strided, CBOs, to see if the attribute is - * interleved with one of them, if found: - * add to the matched CBO - * else if not found: - * create a new-CBOs entry tagged STRIDED + INFREQUENT_RESUBMIT - * else if unstrided && tagged with FREQUENT_RESUBMIT: - * create a new-CBOs entry tagged MULTIPACK + FREQUENT_RESUBMIT - * else - * add to the new-multipack-CBO - * free list of unsorted-attribs - * - * Next compare the new list of CBOs with the submitted set and try to - * minimize the memory bandwidth required to upload the attributes and the - * overhead of creating new GL-BOs. - * - * We deal with four sets of CBOs: - * - The "new" CBOs - * (as determined above during filtering) - * - The "re-use" CBOs - * (as determined above during filtering) - * - The "submitted" CBOs - * (I.e. ones currently submitted to the GPU) - * - The "final" CBOs - * (The result of resolving the differences between the above sets) - * - * The re-use CBOs are dealt with first, and we simply delete any remaining - * attributes in these that are still marked as UNUSED, and move them - * to the list of final CBOs. - * - * Next we iterate through the "new" CBOs, searching for conflicts - * with the "submitted" CBOs and commit our decision to the "final" CBOs - * - * When searching for submitted entries we always unlink items from the - * submitted list once we make matches (before we make descisions - * based on the matches). If the CBO node is superseded it is freed, - * if it is modified but may be needed for more descisions later it is - * relinked back into the submitted list and if it's identical to a new - * CBO it will be linked into the final list. - * - * At the end the list of submitted CBOs represents the attributes that were - * deleted from the buffer. - * - * Iterate re-use-CBOs: - * Iterate attribs for each: - * if attrib UNUSED: - * remove the attrib from the CBO + free - * |Note: we could potentially mark this as a re-useable gap - * |if needs be later. - * add re-use CBO to the final-CBOs - * Iterate new-CBOs: - * List submitted CBOs conflicting with the this CBO (Unlinked items) - * found-target-BO=FALSE - * Iterate conflicting CBOs: - * Disassociate conflicting attribs from conflicting CBO struct - * If no attribs remain: - * If found-target-BO!=TRUE - * _AND_ If the total size of the conflicting CBO is compatible: - * |Note: We don't currently consider re-using oversized buffers - * found-target-BO=TRUE - * upload replacement data - * free submitted CBO struct - * add new CBO struct to final-CBOs - * else: - * delete conflict GL-BO - * delete conflict CBO struct - * else: - * relink CBO back into submitted-CBOs - * - * if found-target-BO == FALSE: - * create a new GL-BO - * upload data - * add new CBO struct to final-BOs - * - * Iterate through the remaining "submitted" CBOs: - * delete the submitted GL-BO - * free the submitted CBO struct - */ - - new_multipack_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); - new_multipack_vbo->array = NULL; - new_multipack_vbo->array_bytes = 0; - new_multipack_vbo->flags = - COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK - | COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; - new_multipack_vbo->attributes = NULL; - new_vbos = g_list_prepend (new_vbos, new_multipack_vbo); - /* We save the link pointer here, just so we can do a fast removal later if - * no attributes get added to this vbo. */ - new_multipack_vbo_link = new_vbos; - - /* Start with a list of unsorted attributes, and filter those into - * potential new Cogl BO structs - */ - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - - if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED) - { - /* If the attribute is already marked as submitted, then we need - * to find the existing VBO that contains it so we dont delete it. - * - * NB: this also frees the attribute struct since it's implicitly - * redundant in this case. - */ - filter_already_submitted_attribute (attribute, - &reuse_vbos, - &buffer->submitted_vbos); - } - else if (attribute->stride) - { - /* look for a CoglVertexBufferVBO that the attribute is - * interleved with. If one can't be found then a new - * CoglVertexBufferVBO is allocated and added to the list of - * new_vbos: */ - filter_strided_attribute (attribute, &new_vbos); - } - else if (attribute->flags & - COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) - { - CoglVertexBufferVBO *cogl_vbo = - g_slice_alloc (sizeof (CoglVertexBufferVBO)); - - /* attributes we expect will be frequently resubmitted are placed - * in their own VBO so that updates don't impact other attributes - */ - - cogl_vbo->flags = - COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK - | COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; - cogl_vbo->attributes = NULL; - cogl_vbo->attributes = g_list_prepend (cogl_vbo->attributes, - attribute); - cogl_vbo->array = NULL; - cogl_vbo->array_bytes = attribute->span_bytes; - new_vbos = g_list_prepend (new_vbos, cogl_vbo); - } - else - { - gsize type_size = sizeof_attribute_type (attribute->flags); - - /* Infrequently updated attributes just get packed back to back - * in a single VBO: */ - new_multipack_vbo->attributes = - g_list_prepend (new_multipack_vbo->attributes, - attribute); - - /* Note: we have to ensure that each run of attributes is - * naturally aligned according to its data type, which may - * require some padding bytes: */ - - /* XXX: We also have to be sure that the attributes aren't - * reorderd before being uploaded because the alignment padding - * is based on the adjacent attribute. - */ - - PAD_FOR_ALIGNMENT (new_multipack_vbo->array_bytes, type_size); - - new_multipack_vbo->array_bytes += attribute->span_bytes; - } - } - - /* At this point all buffer->new_attributes have been filtered into - * CoglVertexBufferVBOs... */ - g_list_free (buffer->new_attributes); - buffer->new_attributes = NULL; - - /* If the multipack vbo wasn't needed: */ - if (new_multipack_vbo->attributes == NULL) - { - new_vbos = g_list_delete_link (new_vbos, new_multipack_vbo_link); - g_slice_free (CoglVertexBufferVBO, new_multipack_vbo); - } - - for (tmp = reuse_vbos; tmp != NULL; tmp = tmp->next) - remove_unused_attributes (tmp->data); - final_vbos = g_list_concat (final_vbos, reuse_vbos); - - for (tmp = new_vbos; tmp != NULL; tmp = tmp->next) - cogl_vertex_buffer_vbo_resolve (buffer, tmp->data, &final_vbos); - - /* Anything left corresponds to deleted attributes: */ - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - cogl_vertex_buffer_vbo_free (tmp->data); - g_list_free (buffer->submitted_vbos); - g_list_free (new_vbos); - - buffer->submitted_vbos = final_vbos; - -done: - update_primitive_attributes (buffer); -} - -void -cogl_vertex_buffer_submit (CoglHandle handle) -{ - CoglVertexBuffer *buffer; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - - cogl_vertex_buffer_submit_real (buffer); -} - -typedef struct -{ - /* We have a ref-count on this private structure because we need to - refer to it both from the private data on a pipeline and any weak - pipelines that we create from it. If we didn't have the ref count - then we would depend on the order of destruction of a - CoglPipeline and the weak materials to avoid a crash */ - unsigned int ref_count; - - CoglPipeline *real_source; -} VertexBufferMaterialPrivate; - -static void -unref_pipeline_priv (VertexBufferMaterialPrivate *priv) -{ - if (--priv->ref_count < 1) - g_slice_free (VertexBufferMaterialPrivate, priv); -} - -static void -weak_override_source_destroyed_cb (CoglPipeline *pipeline, - void *user_data) -{ - VertexBufferMaterialPrivate *pipeline_priv = user_data; - pipeline_priv->real_source = NULL; - /* A reference was added when we copied the weak material so we need - to unref it here */ - unref_pipeline_priv (pipeline_priv); -} - -static gboolean -validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - VertexBufferMaterialPrivate *pipeline_priv = user_data; - CoglPipeline *source = pipeline_priv->real_source; - - if (!cogl_pipeline_get_layer_point_sprite_coords_enabled (source, - layer_index)) - { - CoglPipelineWrapMode wrap_s; - CoglPipelineWrapMode wrap_t; - CoglPipelineWrapMode wrap_p; - gboolean need_override_source = FALSE; - - /* By default COGL_PIPELINE_WRAP_MODE_AUTOMATIC becomes - * GL_CLAMP_TO_EDGE but we want GL_REPEAT to maintain - * compatibility with older versions of Cogl so we'll override - * it. We don't want to do this for point sprites because in - * that case the whole texture is drawn so you would usually - * want clamp-to-edge. - */ - wrap_s = cogl_pipeline_get_layer_wrap_mode_s (source, layer_index); - if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - need_override_source = TRUE; - wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - wrap_t = cogl_pipeline_get_layer_wrap_mode_t (source, layer_index); - if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - need_override_source = TRUE; - wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - wrap_p = cogl_pipeline_get_layer_wrap_mode_p (source, layer_index); - if (wrap_p == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - need_override_source = TRUE; - wrap_p = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - - if (need_override_source) - { - if (pipeline_priv->real_source == pipeline) - { - pipeline_priv->ref_count++; - pipeline_priv->real_source = source = - _cogl_pipeline_weak_copy (pipeline, - weak_override_source_destroyed_cb, - pipeline_priv); - } - - cogl_pipeline_set_layer_wrap_mode_s (source, layer_index, wrap_s); - cogl_pipeline_set_layer_wrap_mode_t (source, layer_index, wrap_t); - cogl_pipeline_set_layer_wrap_mode_p (source, layer_index, wrap_p); - } - } - - return TRUE; -} - -static void -destroy_pipeline_priv_cb (void *user_data) -{ - unref_pipeline_priv (user_data); -} - -static void -update_primitive_and_draw (CoglVertexBuffer *buffer, - CoglVerticesMode mode, - int first, - int count, - CoglVertexBufferIndices *buffer_indices) -{ - VertexBufferMaterialPrivate *pipeline_priv; - CoglPipeline *users_source; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_primitive_set_mode (buffer->primitive, mode); - cogl_primitive_set_first_vertex (buffer->primitive, first); - cogl_primitive_set_n_vertices (buffer->primitive, count); - - if (buffer_indices) - cogl_primitive_set_indices (buffer->primitive, buffer_indices->indices); - else - cogl_primitive_set_indices (buffer->primitive, NULL); - - cogl_vertex_buffer_submit_real (buffer); - - users_source = cogl_get_source (); - pipeline_priv = - cogl_object_get_user_data (COGL_OBJECT (users_source), - &_cogl_vertex_buffer_pipeline_priv_key); - if (G_UNLIKELY (!pipeline_priv)) - { - pipeline_priv = g_slice_new0 (VertexBufferMaterialPrivate); - pipeline_priv->ref_count = 1; - cogl_object_set_user_data (COGL_OBJECT (users_source), - &_cogl_vertex_buffer_pipeline_priv_key, - pipeline_priv, - destroy_pipeline_priv_cb); - } - - if (G_UNLIKELY (!pipeline_priv->real_source)) - { - pipeline_priv->real_source = users_source; - cogl_pipeline_foreach_layer (pipeline_priv->real_source, - validate_layer_cb, - pipeline_priv); - } - - cogl_push_source (pipeline_priv->real_source); - - cogl_primitive_draw (buffer->primitive); - - cogl_pop_source (); -} - -void -cogl_vertex_buffer_draw (CoglHandle handle, - CoglVerticesMode mode, - int first, - int count) -{ - CoglVertexBuffer *buffer; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - - update_primitive_and_draw (buffer, mode, first, count, NULL); -} - -static CoglHandle -_cogl_vertex_buffer_indices_new_real (CoglIndices *indices) -{ - CoglVertexBufferIndices *buffer_indices = - g_slice_alloc (sizeof (CoglVertexBufferIndices)); - buffer_indices->indices = indices; - - return _cogl_vertex_buffer_indices_handle_new (buffer_indices); -} - -CoglHandle -cogl_vertex_buffer_indices_new (CoglIndicesType indices_type, - const void *indices_array, - int indices_len) -{ - CoglIndices *indices = - cogl_indices_new (indices_type, indices_array, indices_len); - return _cogl_vertex_buffer_indices_new_real (indices); -} - -CoglIndicesType -cogl_vertex_buffer_indices_get_type (CoglHandle indices_handle) -{ - CoglVertexBufferIndices *buffer_indices = NULL; - - if (!cogl_is_vertex_buffer_indices (indices_handle)) - return COGL_INDICES_TYPE_UNSIGNED_SHORT; - - buffer_indices = - _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle); - - return cogl_indices_get_type (buffer_indices->indices); -} - -void -_cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices) -{ - cogl_object_unref (buffer_indices->indices); - g_slice_free (CoglVertexBufferIndices, buffer_indices); -} - -void -cogl_vertex_buffer_draw_elements (CoglHandle handle, - CoglVerticesMode mode, - CoglHandle indices_handle, - int min_index, - int max_index, - int indices_offset, - int count) -{ - CoglVertexBuffer *buffer; - CoglVertexBufferIndices *buffer_indices; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - - if (!cogl_is_vertex_buffer_indices (indices_handle)) - return; - - buffer_indices = - _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle); - - update_primitive_and_draw (buffer, mode, indices_offset, count, - buffer_indices); -} - -static void -_cogl_vertex_buffer_free (CoglVertexBuffer *buffer) -{ - GList *tmp; - - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - cogl_vertex_buffer_vbo_free (tmp->data); - g_list_free (buffer->submitted_vbos); - - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - _cogl_vertex_buffer_attrib_free (tmp->data); - g_list_free (buffer->new_attributes); - - if (buffer->primitive) - cogl_object_unref (buffer->primitive); - - g_slice_free (CoglVertexBuffer, buffer); -} - -CoglHandle -cogl_vertex_buffer_indices_get_for_quads (unsigned int n_indices) -{ - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - if (n_indices <= 256 / 4 * 6) - { - if (ctx->quad_buffer_indices_byte == COGL_INVALID_HANDLE) - { - /* NB: cogl_get_quad_indices takes n_quads not n_indices... */ - CoglIndices *indices = cogl_get_rectangle_indices (256 / 4); - cogl_object_ref (indices); - ctx->quad_buffer_indices_byte = - _cogl_vertex_buffer_indices_new_real (indices); - } - - return ctx->quad_buffer_indices_byte; - } - else - { - if (ctx->quad_buffer_indices && - ctx->quad_buffer_indices_len < n_indices) - { - cogl_handle_unref (ctx->quad_buffer_indices); - ctx->quad_buffer_indices = COGL_INVALID_HANDLE; - } - - if (ctx->quad_buffer_indices == COGL_INVALID_HANDLE) - { - /* NB: cogl_get_quad_indices takes n_quads not n_indices... */ - CoglIndices *indices = cogl_get_rectangle_indices (n_indices / 6); - cogl_object_ref (indices); - ctx->quad_buffer_indices = - _cogl_vertex_buffer_indices_new_real (indices); - } - - ctx->quad_buffer_indices_len = n_indices; - - return ctx->quad_buffer_indices; - } - - g_return_val_if_reached (NULL); -} - diff --git a/clutter/cogl/cogl/cogl-vertex-buffer.h b/clutter/cogl/cogl/cogl-vertex-buffer.h deleted file mode 100644 index 631ba09..0000000 --- a/clutter/cogl/cogl/cogl-vertex-buffer.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_VERTEX_BUFFER_H__ -#define __COGL_VERTEX_BUFFER_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-vertex-buffer - * @short_description: An API for submitting extensible arrays of vertex - * attributes to be mapped into the GPU for fast drawing. - * - * For example to describe a textured triangle, you could create a new cogl - * vertex buffer with 3 vertices, and then you might add 2 attributes for each - * vertex: - * - * - * a "gl_Position" describing the (x,y,z) position for each vertex. - * - * - * a "gl_MultiTexCoord0" describing the (tx,ty) texture coordinates for each - * vertex. - * - * - * - * The Vertex Buffer API is designed to be a fairly raw mechanism for - * developers to be able to submit geometry to Cogl in a format that can be - * directly consumed by an OpenGL driver and mapped into your GPU for fast - * re-use. It is designed to avoid repeated validation of the attributes by the - * driver; to minimize transport costs (e.g. considering indirect GLX - * use-cases) and to potentially avoid repeated format conversions when - * attributes are supplied in a format that is not natively supported by the - * GPU. - * - * Although this API does allow you to modify attributes after they have been - * submitted to the GPU you should be aware that modification is not that - * cheap, since it implies validating the new data and potentially the - * OpenGL driver will need to reformat it for the GPU. - * - * If at all possible think of tricks that let you re-use static attributes, - * and if you do need to repeatedly update attributes (e.g. for some kind of - * morphing geometry) then only update and re-submit the specific attributes - * that have changed. - */ - -/** - * cogl_vertex_buffer_new: - * @n_vertices: The number of vertices that your attributes will correspond to. - * - * Creates a new vertex buffer that you can use to add attributes. - * - * Return value: a new #CoglHandle - */ -CoglHandle -cogl_vertex_buffer_new (unsigned int n_vertices); - -/** - * cogl_vertex_buffer_get_n_vertices: - * @handle: A vertex buffer handle - * - * Retrieves the number of vertices that @handle represents - * - * Return value: the number of vertices - */ -unsigned int -cogl_vertex_buffer_get_n_vertices (CoglHandle handle); - -/** - * cogl_vertex_buffer_add: - * @handle: A vertex buffer handle - * @attribute_name: The name of your attribute. It should be a valid GLSL - * variable name and standard attribute types must use one of following - * built-in names: (Note: they correspond to the built-in names of GLSL) - * - * "gl_Color" - * "gl_Normal" - * "gl_MultiTexCoord0, gl_MultiTexCoord1, ..." - * "gl_Vertex" - * - * To support adding multiple variations of the same attribute the name - * can have a detail component, E.g. "gl_Color::active" or - * "gl_Color::inactive" - * @n_components: The number of components per attribute and must be 1, 2, - * 3 or 4 - * @type: a #CoglAttributeType specifying the data type of each component. - * @normalized: If %TRUE, this specifies that values stored in an integer - * format should be mapped into the range [-1.0, 1.0] or [0.0, 1.0] - * for unsigned values. If %FALSE they are converted to floats - * directly. - * @stride: This specifies the number of bytes from the start of one attribute - * value to the start of the next value (for the same attribute). So, for - * example, with a position interleved with color like this: - * XYRGBAXYRGBAXYRGBA, then if each letter represents a byte, the - * stride for both attributes is 6. The special value 0 means the - * values are stored sequentially in memory. - * @pointer: This addresses the first attribute in the vertex array. This - * must remain valid until you either call cogl_vertex_buffer_submit() or - * issue a draw call. - * - * Adds an attribute to a buffer, or replaces a previously added - * attribute with the same name. - * - * You either can use one of the built-in names such as "gl_Vertex", or - * "gl_MultiTexCoord0" to add standard attributes, like positions, colors - * and normals, or you can add custom attributes for use in shaders. - * - * The number of vertices declared when calling cogl_vertex_buffer_new() - * determines how many attribute values will be read from the supplied - * @pointer. - * - * The data for your attribute isn't copied anywhere until you call - * cogl_vertex_buffer_submit(), or issue a draw call which automatically - * submits pending attribute changes. so the supplied pointer must remain - * valid until then. If you are updating an existing attribute (done by - * re-adding it) then you still need to re-call cogl_vertex_buffer_submit() - * to commit the changes to the GPU. Be carefull to minimize the number - * of calls to cogl_vertex_buffer_submit(), though. - * - * If you are interleving attributes it is assumed that each interleaved - * attribute starts no farther than +- stride bytes from the other attributes - * it is interleved with. I.e. this is ok: - * - * |-0-0-0-0-0-0-0-0-0-0| - * - * This is not ok: - * - * |- - - - -0-0-0-0-0-0 0 0 0 0| - * - * (Though you can have multiple groups of interleved attributes) - */ -void -cogl_vertex_buffer_add (CoglHandle handle, - const char *attribute_name, - guint8 n_components, - CoglAttributeType type, - gboolean normalized, - guint16 stride, - const void *pointer); - -/** - * cogl_vertex_buffer_delete: - * @handle: A vertex buffer handle - * @attribute_name: The name of a previously added attribute - * - * Deletes an attribute from a buffer. You will need to call - * cogl_vertex_buffer_submit() or issue a draw call to commit this - * change to the GPU. - */ -void -cogl_vertex_buffer_delete (CoglHandle handle, - const char *attribute_name); - -/** - * cogl_vertex_buffer_submit: - * @handle: A vertex buffer handle - * - * Submits all the user added attributes to the GPU; once submitted, the - * attributes can be used for drawing. - * - * You should aim to minimize calls to this function since it implies - * validating your data; it potentially incurs a transport cost (especially if - * you are using GLX indirect rendering) and potentially a format conversion - * cost if the GPU doesn't natively support any of the given attribute formats. - */ -void -cogl_vertex_buffer_submit (CoglHandle handle); - -/** - * cogl_vertex_buffer_disable: - * @handle: A vertex buffer handle - * @attribute_name: The name of the attribute you want to disable - * - * Disables a previosuly added attribute. - * - * Since it can be costly to add and remove new attributes to buffers; to make - * individual buffers more reuseable it is possible to enable and disable - * attributes before using a buffer for drawing. - * - * You don't need to call cogl_vertex_buffer_submit() after using this - * function. - */ -void -cogl_vertex_buffer_disable (CoglHandle handle, - const char *attribute_name); - -/** - * cogl_vertex_buffer_enable: - * @handle: A vertex buffer handle - * @attribute_name: The name of the attribute you want to enable - * - * Enables a previosuly disabled attribute. - * - * Since it can be costly to add and remove new attributes to buffers; to make - * individual buffers more reuseable it is possible to enable and disable - * attributes before using a buffer for drawing. - * - * You don't need to call cogl_vertex_buffer_submit() after using this function - */ -void -cogl_vertex_buffer_enable (CoglHandle handle, - const char *attribute_name); - -/** - * cogl_vertex_buffer_draw: - * @handle: A vertex buffer handle - * @mode: A #CoglVerticesMode specifying how the vertices should be - * interpreted. - * @first: Specifies the index of the first vertex you want to draw with - * @count: Specifies the number of vertices you want to draw. - * - * Allows you to draw geometry using all or a subset of the - * vertices in a vertex buffer. - * - * Any un-submitted attribute changes are automatically submitted before - * drawing. - */ -void -cogl_vertex_buffer_draw (CoglHandle handle, - CoglVerticesMode mode, - int first, - int count); - -/** - * cogl_vertex_buffer_indices_new: - * @indices_type: a #CoglIndicesType specifying the data type used for - * the indices. - * @indices_array: (array length=indices_len): Specifies the address of - * your array of indices - * @indices_len: The number of indices in indices_array - * - * Depending on how much geometry you are submitting it can be worthwhile - * optimizing the number of redundant vertices you submit. Using an index - * array allows you to reference vertices multiple times, for example - * during triangle strips. - * - * Return value: A CoglHandle for the indices which you can pass to - * cogl_vertex_buffer_draw_elements(). - */ -CoglHandle -cogl_vertex_buffer_indices_new (CoglIndicesType indices_type, - const void *indices_array, - int indices_len); - -/** - * cogl_vertex_buffer_indices_get_type: - * @indices: An indices handle - * - * Queries back the data type used for the given indices - * - * Returns: The CoglIndicesType used - */ -CoglIndicesType -cogl_vertex_buffer_indices_get_type (CoglHandle indices); - -/** - * cogl_vertex_buffer_draw_elements: - * @handle: A vertex buffer handle - * @mode: A #CoglVerticesMode specifying how the vertices should be - * interpreted. - * @indices: A CoglHandle for a set of indices allocated via - * cogl_vertex_buffer_indices_new () - * @min_index: Specifies the minimum vertex index contained in indices - * @max_index: Specifies the maximum vertex index contained in indices - * @indices_offset: An offset into named indices. The offset marks the first - * index to use for drawing. - * @count: Specifies the number of vertices you want to draw. - * - * This function lets you use an array of indices to specify the vertices - * within your vertex buffer that you want to draw. The indices themselves - * are created by calling cogl_vertex_buffer_indices_new () - * - * Any un-submitted attribute changes are automatically submitted before - * drawing. - */ -void -cogl_vertex_buffer_draw_elements (CoglHandle handle, - CoglVerticesMode mode, - CoglHandle indices, - int min_index, - int max_index, - int indices_offset, - int count); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_vertex_buffer_ref: - * @handle: a @CoglHandle. - * - * Increment the reference count for a vertex buffer - * - * Return value: the @handle. - * - * Deprecated: 1.2: Use cogl_handle_ref() instead - */ -CoglHandle -cogl_vertex_buffer_ref (CoglHandle handle) G_GNUC_DEPRECATED; - -/** - * cogl_vertex_buffer_unref: - * @handle: a @CoglHandle. - * - * Decrement the reference count for a vertex buffer - * - * Deprecated: 1.2: Use cogl_handle_unref() instead - */ -void -cogl_vertex_buffer_unref (CoglHandle handle) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_vertex_buffer_indices_get_for_quads: - * @n_indices: the number of indices in the vertex buffer. - * - * Creates a vertex buffer containing the indices needed to draw pairs - * of triangles from a list of vertices grouped as quads. There will - * be at least @n_indices entries in the buffer (but there may be - * more). - * - * The indices will follow this pattern: - * - * 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 ... etc - * - * For example, if you submit vertices for a quad like like that shown - * in then you can request 6 - * indices to render two triangles like those shown in . - * - *
- * Example of vertices submitted to form a quad - * - *
- * - *
- * Illustration of the triangle indices that will be generated - * - *
- * - * Returns: A %CoglHandle containing the indices. The handled is - * owned by Cogl and should not be modified or unref'd. - */ -CoglHandle -cogl_vertex_buffer_indices_get_for_quads (unsigned int n_indices); - -/** - * cogl_is_vertex_buffer: - * @handle: a #CoglHandle for a vertex buffer object - * - * Checks whether @handle is a Vertex Buffer Object - * - * Return value: %TRUE if the handle is a VBO, and %FALSE - * otherwise - * - * Since: 1.0 - */ -gboolean -cogl_is_vertex_buffer (CoglHandle handle); - -/** - * cogl_is_vertex_buffer_indices: - * @handle: a #CoglHandle - * - * Checks whether @handle is a handle to the indices for a vertex - * buffer object - * - * Return value: %TRUE if the handle is indices, and %FALSE - * otherwise - * - * Since: 1.4 - */ -gboolean -cogl_is_vertex_buffer_indices (CoglHandle handle); - -G_END_DECLS - -#endif /* __COGL_VERTEX_BUFFER_H__ */ diff --git a/clutter/cogl/cogl/cogl-xlib-private.h b/clutter/cogl/cogl/cogl-xlib-private.h deleted file mode 100644 index 5645439..0000000 --- a/clutter/cogl/cogl/cogl-xlib-private.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * - * - */ - -#ifndef __COGL_XLIB_PRIVATE_H -#define __COGL_XLIB_PRIVATE_H - -#include "cogl/cogl.h" - -#include - -typedef struct _CoglXlibTrapState CoglXlibTrapState; - -struct _CoglXlibTrapState -{ - /* These values are intended to be internal to - * _cogl_xlib_{un,}trap_errors but they need to be in the header so - * that the struct can be allocated on the stack */ - int (* old_error_handler) (Display *, XErrorEvent *); - int trapped_error_code; - CoglXlibTrapState *old_state; -}; - -void -_cogl_xlib_query_damage_extension (void); - -int -_cogl_xlib_get_damage_base (void); - -void -_cogl_xlib_trap_errors (CoglXlibTrapState *state); - -int -_cogl_xlib_untrap_errors (CoglXlibTrapState *state); - -/* - * _cogl_xlib_add_filter: - * - * Adds a callback function that will receive all X11 events. The - * function can stop further processing of the event by return - * %COGL_XLIB_FILTER_REMOVE. - */ -void -_cogl_xlib_add_filter (CoglNativeFilterFunc func, - void *data); - -/* - * _cogl_xlib_remove_filter: - * - * Removes a callback that was previously added with - * _cogl_xlib_add_filter(). - */ -void -_cogl_xlib_remove_filter (CoglNativeFilterFunc func, - void *data); - -#endif /* __COGL_XLIB_PRIVATE_H */ diff --git a/clutter/cogl/cogl/cogl-xlib.c b/clutter/cogl/cogl/cogl-xlib.c deleted file mode 100644 index 51fa715..0000000 --- a/clutter/cogl/cogl/cogl-xlib.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Robert Bragg - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "cogl-xlib.h" - -/* FIXME: when we remove the last X11 based Clutter backend then we - * will get rid of these functions and instead rely on the equivalent - * _cogl_renderer_xlib API - */ - -/* This can't be in the Cogl context because it can be set before - context is created */ -static Display *_cogl_xlib_display = NULL; - -Display * -cogl_xlib_get_display (void) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - if (!ctx->stub_winsys) - return cogl_renderer_xlib_get_display (ctx->display->renderer); - - /* _cogl_xlib_set_display should be called before this function */ - g_assert (_cogl_xlib_display != NULL); - - return _cogl_xlib_display; -} - -void -cogl_xlib_set_display (Display *display) -{ - /* This can only be called once before the Cogl context is created */ - g_assert (_cogl_xlib_display == NULL); - - _cogl_xlib_display = display; -} - -/* These three functions are wrappers around the equivalent renderer - functions. They can be removed once all xlib-based backends in - Clutter know about the renderer */ -CoglFilterReturn -cogl_xlib_handle_event (XEvent *xevent) -{ - _COGL_GET_CONTEXT (ctx, COGL_FILTER_CONTINUE); - - /* Pass the event on to the renderer */ - return cogl_renderer_handle_native_event (ctx->display->renderer, xevent); -} - -void -_cogl_xlib_add_filter (CoglNativeFilterFunc func, - void *data) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_renderer_add_native_filter (ctx->display->renderer, func, data); -} - -void -_cogl_xlib_remove_filter (CoglNativeFilterFunc func, - void *data) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_renderer_remove_native_filter (ctx->display->renderer, func, data); -} - -static int -error_handler (Display *xdpy, - XErrorEvent *error) -{ - _COGL_GET_CONTEXT (ctxt, 0); - - g_assert (ctxt->trap_state); - - ctxt->trap_state->trapped_error_code = error->error_code; - - return 0; -} - -void -_cogl_xlib_trap_errors (CoglXlibTrapState *state) -{ - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - if (!ctxt->stub_winsys) - { - _cogl_renderer_xlib_trap_errors (ctxt->display->renderer, state); - return; - } - - state->trapped_error_code = 0; - state->old_error_handler = XSetErrorHandler (error_handler); - - state->old_state = ctxt->trap_state; - ctxt->trap_state = state; -} - -int -_cogl_xlib_untrap_errors (CoglXlibTrapState *state) -{ - _COGL_GET_CONTEXT (ctxt, 0); - - if (!ctxt->stub_winsys) - { - return _cogl_renderer_xlib_untrap_errors (ctxt->display->renderer, state); - } - - g_assert (state == ctxt->trap_state); - - XSetErrorHandler (state->old_error_handler); - - ctxt->trap_state = state->old_state; - - return state->trapped_error_code; -} - -void -_cogl_xlib_query_damage_extension (void) -{ - int damage_error; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - /* Check whether damage events are supported on this display */ - if (!XDamageQueryExtension (cogl_xlib_get_display (), - &ctxt->damage_base, - &damage_error)) - ctxt->damage_base = -1; -} - -int -_cogl_xlib_get_damage_base (void) -{ - _COGL_GET_CONTEXT (ctxt, -1); - - if (!ctxt->stub_winsys) - { - CoglRendererX11 *x11_renderer = ctxt->display->renderer->winsys; - return x11_renderer->damage_base; - } - else - return ctxt->damage_base; -} diff --git a/clutter/cogl/cogl/cogl-xlib.h b/clutter/cogl/cogl/cogl-xlib.h deleted file mode 100644 index d088dc9..0000000 --- a/clutter/cogl/cogl/cogl-xlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_XLIB_H__ -#define __COGL_XLIB_H__ - -#include - -#include - -G_BEGIN_DECLS - -/* - * cogl_xlib_get_display: - * - * Return value: the Xlib display that will be used by the Xlib winsys - * backend. The display needs to be set with _cogl_xlib_set_display() - * before this function is called. - * - * Stability: Unstable - */ -#define cogl_xlib_get_display cogl_xlib_get_display_EXP -Display * -cogl_xlib_get_display (void); - -/* - * cogl_xlib_set_display: - * - * Sets the Xlib display that Cogl will use for the Xlib winsys - * backend. This function should eventually go away when Cogl gains a - * more complete winsys abstraction. - * - * Stability: Unstable - */ -#define cogl_xlib_set_display cogl_xlib_set_display_EXP -void -cogl_xlib_set_display (Display *display); - -/* - * cogl_xlib_handle_event: - * @xevent: pointer to XEvent structure - * - * This function processes a single X event; it can be used to hook - * into external X event retrieval (for example that done by Clutter - * or GDK). - * - * Return value: #CoglXlibFilterReturn. %COGL_XLIB_FILTER_REMOVE - * indicates that Cogl has internally handled the event and the - * caller should do no further processing. %COGL_XLIB_FILTER_CONTINUE - * indicates that Cogl is either not interested in the event, - * or has used the event to update internal state without taking - * any exclusive action. - * - * Stability: Unstable - */ -#define cogl_xlib_handle_event cogl_xlib_handle_event_EXP -CoglFilterReturn -cogl_xlib_handle_event (XEvent *xevent); - -#endif /* __COGL_XLIB_H__ */ diff --git a/clutter/cogl/cogl/cogl.c b/clutter/cogl/cogl/cogl.c deleted file mode 100644 index 6592221..0000000 --- a/clutter/cogl/cogl/cogl.c +++ /dev/null @@ -1,1114 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" - -#include -#include -#include -#include - -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-winsys-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-matrix-private.h" -#include "cogl-journal-private.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-driver.h" -#include "cogl-attribute-private.h" -#include "cogl-framebuffer-private.h" - -#ifdef HAVE_COGL_GL -#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture -#endif - -#ifdef COGL_GL_DEBUG -/* GL error to string conversion */ -static const struct { - GLuint error_code; - const char *error_string; -} gl_errors[] = { - { GL_NO_ERROR, "No error" }, - { GL_INVALID_ENUM, "Invalid enumeration value" }, - { GL_INVALID_VALUE, "Invalid value" }, - { GL_INVALID_OPERATION, "Invalid operation" }, -#ifdef HAVE_COGL_GL - { GL_STACK_OVERFLOW, "Stack overflow" }, - { GL_STACK_UNDERFLOW, "Stack underflow" }, -#endif - { GL_OUT_OF_MEMORY, "Out of memory" }, - -#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT - { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "Invalid framebuffer operation" } -#endif -}; - -static const unsigned int n_gl_errors = G_N_ELEMENTS (gl_errors); - -const char * -cogl_gl_error_to_string (GLenum error_code) -{ - int i; - - for (i = 0; i < n_gl_errors; i++) - { - if (gl_errors[i].error_code == error_code) - return gl_errors[i].error_string; - } - - return "Unknown GL error"; -} -#endif /* COGL_GL_DEBUG */ - -CoglFuncPtr -cogl_get_proc_address (const char* name) -{ - void *address; - static GModule *module = NULL; -#ifdef COGL_HAS_FULL_WINSYS - const CoglWinsysVtable *winsys; - - _COGL_GET_CONTEXT (ctx, NULL); - - winsys = _cogl_context_get_winsys (ctx); - - address = winsys->get_proc_address (name); -#else - address = _cogl_winsys_get_proc_address (name); -#endif - if (address) - return address; - - /* this should find the right function if the program is linked against a - * library providing it */ - if (G_UNLIKELY (module == NULL)) - module = g_module_open (NULL, 0); - - if (module) - { - gpointer symbol; - - if (g_module_symbol (module, name, &symbol)) - return symbol; - } - - return NULL; -} - -gboolean -_cogl_check_extension (const char *name, const gchar *ext) -{ - char *end; - int name_len, n; - - if (name == NULL || ext == NULL) - return FALSE; - - end = (char*)(ext + strlen(ext)); - - name_len = strlen(name); - - while (ext < end) - { - n = strcspn(ext, " "); - - if ((name_len == n) && (!strncmp(name, ext, n))) - return TRUE; - ext += (n + 1); - } - - return FALSE; -} - -/* XXX: This has been deprecated as public API */ -gboolean -cogl_check_extension (const char *name, const char *ext) -{ - return _cogl_check_extension (name, ext); -} - -/* XXX: it's expected that we'll deprecated this with - * cogl_framebuffer_clear at some point. */ -void -cogl_clear (const CoglColor *color, unsigned long buffers) -{ - _cogl_framebuffer_clear (cogl_get_draw_framebuffer (), buffers, color); -} - -static gboolean -toggle_flag (CoglContext *ctx, - unsigned long new_flags, - unsigned long flag, - GLenum gl_flag) -{ - /* Toggles and caches a single enable flag on or off - * by comparing to current state - */ - if (new_flags & flag) - { - if (!(ctx->enable_flags & flag)) - { - GE( glEnable (gl_flag) ); - ctx->enable_flags |= flag; - return TRUE; - } - } - else if (ctx->enable_flags & flag) - { - GE( glDisable (gl_flag) ); - ctx->enable_flags &= ~flag; - } - - return FALSE; -} - -#ifdef HAVE_COGL_GLES2 - -/* Under GLES2 there are no builtin client flags so toggle_client_flag - should never be reached */ - -#define toggle_client_flag(ctx, new_flags, flag, gl_flag) \ - g_assert (((new_flags) & (flag)) == 0) - -#else /* HAVE_COGL_GLES2 */ - -static gboolean -toggle_client_flag (CoglContext *ctx, - unsigned long new_flags, - unsigned long flag, - GLenum gl_flag) -{ - /* Toggles and caches a single client-side enable flag - * on or off by comparing to current state - */ - if (new_flags & flag) - { - if (!(ctx->enable_flags & flag)) - { - GE( glEnableClientState (gl_flag) ); - ctx->enable_flags |= flag; - return TRUE; - } - } - else if (ctx->enable_flags & flag) - { - GE( glDisableClientState (gl_flag) ); - ctx->enable_flags &= ~flag; - } - - return FALSE; -} - -#endif /* HAVE_COGL_GLES2 */ - -void -_cogl_enable (unsigned long flags) -{ - /* This function essentially caches glEnable state() in the - * hope of lessening number GL traffic. - */ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - toggle_flag (ctx, flags, - COGL_ENABLE_BACKFACE_CULLING, - GL_CULL_FACE); - - toggle_client_flag (ctx, flags, - COGL_ENABLE_VERTEX_ARRAY, - GL_VERTEX_ARRAY); - - toggle_client_flag (ctx, flags, - COGL_ENABLE_COLOR_ARRAY, - GL_COLOR_ARRAY); -} - -unsigned long -_cogl_get_enable (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - return ctx->enable_flags; -} - -/* XXX: This API has been deprecated */ -void -cogl_set_depth_test_enabled (gboolean setting) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->legacy_depth_test_enabled == setting) - return; - - ctx->legacy_depth_test_enabled = setting; - if (ctx->legacy_depth_test_enabled) - ctx->legacy_state_set++; - else - ctx->legacy_state_set--; -} - -/* XXX: This API has been deprecated */ -gboolean -cogl_get_depth_test_enabled (void) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - return ctx->legacy_depth_test_enabled; -} - -void -cogl_set_backface_culling_enabled (gboolean setting) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->enable_backface_culling == setting) - return; - - /* Currently the journal can't track changes to backface culling state... */ - _cogl_framebuffer_flush_journal (cogl_get_draw_framebuffer ()); - - ctx->enable_backface_culling = setting; -} - -gboolean -cogl_get_backface_culling_enabled (void) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - return ctx->enable_backface_culling; -} - -void -_cogl_flush_face_winding (void) -{ - CoglFrontWinding winding; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* The front face winding doesn't matter if we aren't performing any - * backface culling... */ - if (!ctx->enable_backface_culling) - return; - - /* NB: We use a clockwise face winding order when drawing offscreen because - * all offscreen rendering is done upside down resulting in reversed winding - * for all triangles. - */ - if (cogl_is_offscreen (cogl_get_draw_framebuffer ())) - winding = COGL_FRONT_WINDING_CLOCKWISE; - else - winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE; - - if (winding != ctx->flushed_front_winding) - { - - if (winding == COGL_FRONT_WINDING_CLOCKWISE) - GE (glFrontFace (GL_CW)); - else - GE (glFrontFace (GL_CCW)); - ctx->flushed_front_winding = winding; - } -} - -void -cogl_set_source_color (const CoglColor *color) -{ - CoglPipeline *pipeline; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (cogl_color_get_alpha_byte (color) == 0xff) - { - cogl_pipeline_set_color (ctx->opaque_color_pipeline, color); - pipeline = ctx->opaque_color_pipeline; - } - else - { - CoglColor premultiplied = *color; - cogl_color_premultiply (&premultiplied); - cogl_pipeline_set_color (ctx->blended_color_pipeline, &premultiplied); - pipeline = ctx->blended_color_pipeline; - } - - cogl_set_source (pipeline); -} - -void -cogl_set_viewport (int x, - int y, - int width, - int height) -{ - CoglFramebuffer *framebuffer; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - - _cogl_framebuffer_set_viewport (framebuffer, - x, - y, - width, - height); -} - -/* XXX: This should be deprecated, and we should expose a way to also - * specify an x and y viewport offset */ -void -cogl_viewport (unsigned int width, - unsigned int height) -{ - cogl_set_viewport (0, 0, width, height); -} - -CoglFeatureFlags -cogl_get_features (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - return ctx->feature_flags; -} - -gboolean -cogl_features_available (CoglFeatureFlags features) -{ - _COGL_GET_CONTEXT (ctx, 0); - - return (ctx->feature_flags & features) == features; -} - -/* XXX: This function should either be replaced with one returning - * integers, or removed/deprecated and make the - * _cogl_framebuffer_get_viewport* functions public. - */ -void -cogl_get_viewport (float viewport[4]) -{ - CoglFramebuffer *framebuffer; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - _cogl_framebuffer_get_viewport4fv (framebuffer, viewport); -} - -void -cogl_get_bitmasks (int *red, - int *green, - int *blue, - int *alpha) -{ - CoglFramebuffer *framebuffer; - - framebuffer = cogl_get_draw_framebuffer (); - - if (red) - *red = _cogl_framebuffer_get_red_bits (framebuffer); - - if (green) - *green = _cogl_framebuffer_get_green_bits (framebuffer); - - if (blue) - *blue = _cogl_framebuffer_get_blue_bits (framebuffer); - - if (alpha) - *alpha = _cogl_framebuffer_get_alpha_bits (framebuffer); -} - -void -cogl_set_fog (const CoglColor *fog_color, - CoglFogMode mode, - float density, - float z_near, - float z_far) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->legacy_fog_state.enabled == FALSE) - ctx->legacy_state_set++; - - ctx->legacy_fog_state.enabled = TRUE; - ctx->legacy_fog_state.color = *fog_color; - ctx->legacy_fog_state.mode = mode; - ctx->legacy_fog_state.density = density; - ctx->legacy_fog_state.z_near = z_near; - ctx->legacy_fog_state.z_far = z_far; -} - -void -cogl_disable_fog (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->legacy_fog_state.enabled == TRUE) - ctx->legacy_state_set--; - - ctx->legacy_fog_state.enabled = FALSE; -} - -void -cogl_flush (void) -{ - GList *l; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (l = ctx->framebuffers; l; l = l->next) - _cogl_framebuffer_flush_journal (l->data); -} - -void -_cogl_read_pixels_with_rowstride (int x, - int y, - int width, - int height, - CoglReadPixelsFlags source, - CoglPixelFormat format, - guint8 *pixels, - int rowstride) -{ - CoglFramebuffer *framebuffer = _cogl_get_read_framebuffer (); - int framebuffer_height; - int bpp; - CoglBitmap *bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - CoglPixelFormat bmp_format; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (source == COGL_READ_PIXELS_COLOR_BUFFER); - - if (width == 1 && height == 1 && !framebuffer->clear_clip_dirty) - { - /* If everything drawn so far for this frame is still in the - * Journal then if all of the rectangles only have a flat - * opaque color we have a fast-path for reading a single pixel - * that avoids the relatively high cost of flushing primitives - * to be drawn on the GPU (considering how simple the geometry - * is in this case) and then blocking on the long GPU pipelines - * for the result. - */ - if (_cogl_framebuffer_try_fast_read_pixel (framebuffer, - x, y, source, format, - pixels)) - return; - } - - /* make sure any batched primitives get emitted to the GL driver - * before issuing our read pixels... - * - * XXX: Note we currently use cogl_flush to ensure *all* journals - * are flushed here and not _cogl_journal_flush because we don't - * track the dependencies between framebuffers so we don't know if - * the current framebuffer depends on the contents of other - * framebuffers which could also have associated journal entries. - */ - cogl_flush (); - - _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), - framebuffer, - 0); - - framebuffer_height = cogl_framebuffer_get_height (framebuffer); - - /* The y co-ordinate should be given in OpenGL's coordinate system - * so 0 is the bottom row - * - * NB: all offscreen rendering is done upside down so no conversion - * is necissary in this case. - */ - if (!cogl_is_offscreen (framebuffer)) - y = framebuffer_height - y - height; - - /* Initialise the CoglBitmap */ - bpp = _cogl_get_format_bpp (format); - bmp_format = format; - - if ((format & COGL_A_BIT)) - { - /* We match the premultiplied state of the target buffer to the - * premultiplied state of the framebuffer so that it will get - * converted to the right format below */ - - if ((framebuffer->format & COGL_PREMULT_BIT)) - bmp_format |= COGL_PREMULT_BIT; - else - bmp_format &= ~COGL_PREMULT_BIT; - } - - bmp = _cogl_bitmap_new_from_data (pixels, - bmp_format, width, height, rowstride, - NULL, NULL); - - _cogl_pixel_format_to_gl (format, &gl_intformat, &gl_format, &gl_type); - - /* Under GLES only GL_RGBA with GL_UNSIGNED_BYTE as well as an - implementation specific format under - GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES and - GL_IMPLEMENTATION_COLOR_READ_TYPE_OES is supported. We could try - to be more clever and check if the requested type matches that - but we would need some reliable functions to convert from GL - types to Cogl types. For now, lets just always read in - GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary. We also need - to use this intermediate buffer if the rowstride has padding - because GLES does not support setting GL_ROW_LENGTH */ -#ifndef COGL_HAS_GL - if (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE || - rowstride != 4 * width) - { - CoglBitmap *tmp_bmp, *dst_bmp; - guint8 *tmp_data = g_malloc (width * height * 4); - - tmp_bmp = _cogl_bitmap_new_from_data (tmp_data, - COGL_PIXEL_FORMAT_RGBA_8888 | - (bmp_format & COGL_PREMULT_BIT), - width, height, 4 * width, - (CoglBitmapDestroyNotify) g_free, - NULL); - - _cogl_texture_driver_prep_gl_for_pixels_download (4 * width, 4); - - GE( glReadPixels (x, y, width, height, - GL_RGBA, GL_UNSIGNED_BYTE, - tmp_data) ); - - /* CoglBitmap doesn't currently have a way to convert without - allocating its own buffer so we have to copy the data - again */ - if ((dst_bmp = _cogl_bitmap_convert_format_and_premult (tmp_bmp, - format))) - { - _cogl_bitmap_copy_subregion (dst_bmp, - bmp, - 0, 0, - 0, 0, - width, height); - cogl_object_unref (dst_bmp); - } - else - { - /* FIXME: there's no way to report an error here so we'll - just have to leave the data initialised */ - } - - cogl_object_unref (tmp_bmp); - } - else -#endif - { - _cogl_texture_driver_prep_gl_for_pixels_download (rowstride, bpp); - - GE( glReadPixels (x, y, width, height, gl_format, gl_type, pixels) ); - - /* Convert to the premult format specified by the caller - in-place. This will do nothing if the premult status is already - correct. */ - _cogl_bitmap_convert_premult_status (bmp, format); - } - - /* NB: All offscreen rendering is done upside down so there is no need - * to flip in this case... */ - if (!cogl_is_offscreen (framebuffer)) - { - guint8 *temprow = g_alloca (rowstride * sizeof (guint8)); - - /* TODO: consider using the GL_MESA_pack_invert extension in the future - * to avoid this flip... */ - - /* vertically flip the buffer in-place */ - for (y = 0; y < height / 2; y++) - { - if (y != height - y - 1) /* skip center row */ - { - memcpy (temprow, - pixels + y * rowstride, rowstride); - memcpy (pixels + y * rowstride, - pixels + (height - y - 1) * rowstride, rowstride); - memcpy (pixels + (height - y - 1) * rowstride, - temprow, - rowstride); - } - } - } - - cogl_object_unref (bmp); -} - -void -cogl_read_pixels (int x, - int y, - int width, - int height, - CoglReadPixelsFlags source, - CoglPixelFormat format, - guint8 *pixels) -{ - _cogl_read_pixels_with_rowstride (x, y, width, height, - source, format, pixels, - /* rowstride */ - _cogl_get_format_bpp (format) * width); -} - -void -cogl_begin_gl (void) -{ - unsigned long enable_flags = 0; - CoglPipeline *pipeline; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->in_begin_gl_block) - { - static gboolean shown = FALSE; - if (!shown) - g_warning ("You should not nest cogl_begin_gl/cogl_end_gl blocks"); - shown = TRUE; - return; - } - ctx->in_begin_gl_block = TRUE; - - /* Flush all batched primitives */ - cogl_flush (); - - /* Flush framebuffer state, including clip state, modelview and - * projection matrix state - * - * NB: _cogl_framebuffer_flush_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. */ - _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), - _cogl_get_read_framebuffer (), - 0); - - /* Setup the state for the current pipeline */ - - /* We considered flushing a specific, minimal pipeline here to try and - * simplify the GL state, but decided to avoid special cases and second - * guessing what would be actually helpful. - * - * A user should instead call cogl_set_source_color4ub() before - * cogl_begin_gl() to simplify the state flushed. - * - * XXX: note defining n_tex_coord_attribs using - * cogl_pipeline_get_n_layers is a hack, but the problem is that - * n_tex_coord_attribs is usually defined when drawing a primitive - * which isn't happening here. - * - * Maybe it would be more useful if this code did flush the - * opaque_color_pipeline and then call into cogl-pipeline-opengl.c to then - * restore all state for the material's backend back to default OpenGL - * values. - */ - pipeline = cogl_get_source (); - _cogl_pipeline_flush_gl_state (pipeline, - FALSE, - cogl_pipeline_get_n_layers (pipeline)); - - if (ctx->enable_backface_culling) - enable_flags |= COGL_ENABLE_BACKFACE_CULLING; - - _cogl_enable (enable_flags); - _cogl_flush_face_winding (); - - /* Disable any cached vertex arrays */ - _cogl_attribute_disable_cached_arrays (); -} - -void -cogl_end_gl (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!ctx->in_begin_gl_block) - { - static gboolean shown = FALSE; - if (!shown) - g_warning ("cogl_end_gl is being called before cogl_begin_gl"); - shown = TRUE; - return; - } - ctx->in_begin_gl_block = FALSE; -} - -void -cogl_push_matrix (void) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_push (modelview_stack); -} - -void -cogl_pop_matrix (void) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_pop (modelview_stack); -} - -void -cogl_scale (float x, float y, float z) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_scale (modelview_stack, x, y, z); -} - -void -cogl_translate (float x, float y, float z) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_translate (modelview_stack, x, y, z); -} - -void -cogl_rotate (float angle, float x, float y, float z) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_rotate (modelview_stack, angle, x, y, z); -} - -void -cogl_transform (const CoglMatrix *matrix) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_multiply (modelview_stack, matrix); -} - -void -cogl_perspective (float fov_y, - float aspect, - float z_near, - float z_far) -{ - float ymax = z_near * tanf (fov_y * G_PI / 360.0); - - cogl_frustum (-ymax * aspect, /* left */ - ymax * aspect, /* right */ - -ymax, /* bottom */ - ymax, /* top */ - z_near, - z_far); -} - -void -cogl_frustum (float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (cogl_get_draw_framebuffer ()); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_matrix_stack_load_identity (projection_stack); - - _cogl_matrix_stack_frustum (projection_stack, - left, - right, - bottom, - top, - z_near, - z_far); -} - -void -cogl_ortho (float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglMatrix ortho; - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (cogl_get_draw_framebuffer ()); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_matrix_init_identity (&ortho); - cogl_matrix_ortho (&ortho, left, right, bottom, top, z_near, z_far); - _cogl_matrix_stack_set (projection_stack, &ortho); -} - -void -cogl_get_modelview_matrix (CoglMatrix *matrix) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_get (modelview_stack, matrix); - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_set_modelview_matrix (CoglMatrix *matrix) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_set (modelview_stack, matrix); - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_get_projection_matrix (CoglMatrix *matrix) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_get (projection_stack, matrix); - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -void -cogl_set_projection_matrix (CoglMatrix *matrix) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (cogl_get_draw_framebuffer ()); - _cogl_matrix_stack_set (projection_stack, matrix); - - /* FIXME: Update the inverse projection matrix!! Presumably use - * of clip planes must currently be broken if this API is used. */ - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - -CoglClipState * -_cogl_get_clip_state (void) -{ - CoglFramebuffer *framebuffer; - - framebuffer = cogl_get_draw_framebuffer (); - return _cogl_framebuffer_get_clip_state (framebuffer); -} - -GQuark -_cogl_driver_error_quark (void) -{ - return g_quark_from_static_string ("cogl-driver-error-quark"); -} - -typedef struct _CoglSourceState -{ - CoglPipeline *pipeline; - int push_count; -} CoglSourceState; - -static void -_push_source_real (CoglPipeline *pipeline) -{ - CoglSourceState *top = g_slice_new (CoglSourceState); - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - top->pipeline = cogl_object_ref (pipeline); - top->push_count = 1; - - ctx->source_stack = g_list_prepend (ctx->source_stack, top); -} - -/* FIXME: This should take a context pointer for Cogl 2.0 Technically - * we could make it so we can retrieve a context reference from the - * pipeline, but this would not by symmetric with cogl_pop_source. */ -void -cogl_push_source (void *material_or_pipeline) -{ - CoglSourceState *top; - CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - if (ctx->source_stack) - { - top = ctx->source_stack->data; - if (top->pipeline == pipeline) - { - top->push_count++; - return; - } - else - _push_source_real (pipeline); - } - else - _push_source_real (pipeline); -} - -/* FIXME: This needs to take a context pointer for Cogl 2.0 */ -void -cogl_pop_source (void) -{ - CoglSourceState *top; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (ctx->source_stack); - - top = ctx->source_stack->data; - top->push_count--; - if (top->push_count == 0) - { - cogl_object_unref (top->pipeline); - g_slice_free (CoglSourceState, top); - ctx->source_stack = g_list_delete_link (ctx->source_stack, - ctx->source_stack); - } -} - -/* FIXME: This needs to take a context pointer for Cogl 2.0 */ -void * -cogl_get_source (void) -{ - CoglSourceState *top; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (ctx->source_stack, NULL); - - top = ctx->source_stack->data; - return top->pipeline; -} - -void -cogl_set_source (void *material_or_pipeline) -{ - CoglSourceState *top; - CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - g_return_if_fail (ctx->source_stack); - - top = ctx->source_stack->data; - if (top->pipeline == pipeline) - return; - - if (top->push_count == 1) - { - /* NB: top->pipeline may be only thing keeping pipeline - * alive currently so ref pipeline first... */ - cogl_object_ref (pipeline); - cogl_object_unref (top->pipeline); - top->pipeline = pipeline; - } - else - { - top->push_count--; - cogl_push_source (pipeline); - } -} - -void -cogl_set_source_texture (CoglHandle texture_handle) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (texture_handle != NULL); - - cogl_pipeline_set_layer_texture (ctx->texture_pipeline, 0, texture_handle); - cogl_set_source (ctx->texture_pipeline); -} - -void -cogl_set_source_color4ub (guint8 red, - guint8 green, - guint8 blue, - guint8 alpha) -{ - CoglColor c = { 0, }; - - cogl_color_init_from_4ub (&c, red, green, blue, alpha); - cogl_set_source_color (&c); -} - -void -cogl_set_source_color4f (float red, - float green, - float blue, - float alpha) -{ - CoglColor c = { 0, }; - - cogl_color_init_from_4f (&c, red, green, blue, alpha); - cogl_set_source_color (&c); -} - -/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) - * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with - * (0,0) being top left. */ -#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \ - ( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) ) -/* Note: for Y we first flip all coordinates around the X axis while in - * normalized device coodinates */ -#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \ - ( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) ) - -/* Transform a homogeneous vertex position from model space to Cogl - * window coordinates (with 0,0 being top left) */ -void -_cogl_transform_point (const CoglMatrix *matrix_mv, - const CoglMatrix *matrix_p, - const float *viewport, - float *x, - float *y) -{ - float z = 0; - float w = 1; - - /* Apply the modelview matrix transform */ - cogl_matrix_transform_point (matrix_mv, x, y, &z, &w); - - /* Apply the projection matrix transform */ - cogl_matrix_transform_point (matrix_p, x, y, &z, &w); - - /* Perform perspective division */ - *x /= w; - *y /= w; - - /* Apply viewport transform */ - *x = VIEWPORT_TRANSFORM_X (*x, viewport[0], viewport[2]); - *y = VIEWPORT_TRANSFORM_Y (*y, viewport[1], viewport[3]); -} - -#undef VIEWPORT_TRANSFORM_X -#undef VIEWPORT_TRANSFORM_Y - -GQuark -_cogl_error_quark (void) -{ - return g_quark_from_static_string ("cogl-error-quark"); -} diff --git a/clutter/cogl/cogl/cogl.h b/clutter/cogl/cogl/cogl.h deleted file mode 100644 index cbd2d0c..0000000 --- a/clutter/cogl/cogl/cogl.h +++ /dev/null @@ -1,1262 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_H__ -#define __COGL_H__ - -#include - -#define __COGL_H_INSIDE__ - -#ifdef COGL_ENABLE_EXPERIMENTAL_2_0_API -#ifndef COGL_ENABLE_EXPERIMENTAL_API -#define COGL_ENABLE_EXPERIMENTAL_API -#endif -#endif - -/* We currently keep gtype integration delimited in case we eventually - * want to split it out into a separate utility library when Cogl - * becomes a standalone project. (like cairo-gobject.so) - */ -#define _COGL_SUPPORTS_GTYPE_INTEGRATION - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef COGL_ENABLE_EXPERIMENTAL_2_0_API -#include -#include -#else -#include -#include -#endif -#include -#include -#include -#include - -#include - -#include - -typedef struct _CoglFramebuffer CoglFramebuffer; - -#if defined (COGL_ENABLE_EXPERIMENTAL_API) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef COGL_HAS_XLIB -#include -#endif -/* XXX: This will definitly go away once all the Clutter winsys - * code has been migrated down into Cogl! */ -#include -#endif - -G_BEGIN_DECLS - -/** - * SECTION:cogl - * @short_description: General purpose API - * - * General utility functions for COGL. - */ - -/** - * cogl_get_option_group: - * - * Retrieves the #GOptionGroup used by COGL to parse the command - * line options. Clutter uses this to handle the COGL command line - * options during its initialization process. - * - * Return value: a #GOptionGroup - * - * Since: 1.0 - */ -GOptionGroup * -cogl_get_option_group (void); - -/* Misc */ -/** - * cogl_get_features: - * - * Returns all of the features supported by COGL. - * - * Return value: A logical OR of all the supported COGL features. - * - * Since: 0.8 - */ -CoglFeatureFlags -cogl_get_features (void); - -/** - * cogl_features_available: - * @features: A bitmask of features to check for - * - * Checks whether the given COGL features are available. Multiple - * features can be checked for by or-ing them together with the '|' - * operator. %TRUE is only returned if all of the requested features - * are available. - * - * Return value: %TRUE if the features are available, %FALSE otherwise. - */ -gboolean -cogl_features_available (CoglFeatureFlags features); - -/** - * cogl_get_proc_address: - * @name: the name of the function. - * - * Gets a pointer to a given GL or GL ES extension function. This acts - * as a wrapper around glXGetProcAddress() or whatever is the - * appropriate function for the current backend. - * - * Return value: a pointer to the requested function or %NULL if the - * function is not available. - */ -CoglFuncPtr -cogl_get_proc_address (const char *name); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_check_extension: - * @name: extension to check for - * @ext: list of extensions - * - * Check whether @name occurs in list of extensions in @ext. - * - * Return value: %TRUE if the extension occurs in the list, %FALSE otherwise. - * - * Deprecated: 1.2: OpenGL is an implementation detail for Cogl and so it's - * not appropriate to expose OpenGL extensions through the Cogl API. This - * function can be replaced by the following equivalent code: - * |[ - * gboolean retval = (strstr (ext, name) != NULL) ? TRUE : FALSE; - * ]| - */ -gboolean -cogl_check_extension (const char *name, - const char *ext) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_get_bitmasks: - * @red: (out): Return location for the number of red bits or %NULL - * @green: (out): Return location for the number of green bits or %NULL - * @blue: (out): Return location for the number of blue bits or %NULL - * @alpha: (out): Return location for the number of alpha bits or %NULL - * - * Gets the number of bitplanes used for each of the color components - * in the color buffer. Pass %NULL for any of the arguments if the - * value is not required. - */ -void -cogl_get_bitmasks (int *red, - int *green, - int *blue, - int *alpha); - -/* - * _cogl_framebuffer_get_red_bits: - * @framebuffer: a handle for a framebuffer - * - * Retrieves the number of red bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.4 - */ -int -_cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer); - -/* - * _cogl_framebuffer_get_green_bits: - * @framebuffer: a handle for a framebuffer - * - * Retrieves the number of green bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.4 - */ -int -_cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer); - -/* - * _cogl_framebuffer_get_blue_bits: - * @framebuffer: a handle for a framebuffer - * - * Retrieves the number of blue bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.4 - */ -int -_cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer); - -/* - * _cogl_framebuffer_get_alpha_bits: - * @framebuffer: a handle for a framebuffer - * - * Retrieves the number of alpha bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.4 - */ -int -_cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_perspective: - * @fovy: Vertical of view angle in degrees. - * @aspect: Aspect ratio of diesplay - * @z_near: Nearest visible point - * @z_far: Furthest visible point along the z-axis - * - * Replaces the current projection matrix with a perspective matrix - * based on the provided values. - */ -void -cogl_perspective (float fovy, - float aspect, - float z_near, - float z_far); - -/** - * cogl_frustum: - * @left: Left clipping plane - * @right: Right clipping plane - * @bottom: Bottom clipping plane - * @top: Top clipping plane - * @z_near: Nearest visible point - * @z_far: Furthest visible point along the z-axis - * - * Replaces the current projection matrix with a perspective matrix - * for the given viewing frustum. - * - * Since: 0.8.2 - */ -void -cogl_frustum (float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -/** - * cogl_ortho: - * @left: The coordinate for the left clipping plane - * @right: The coordinate for the right clipping plane - * @bottom: The coordinate for the bottom clipping plane - * @top: The coordinate for the top clipping plane - * @near: The distance to the near clipping - * plane (negative if the plane is behind the viewer) - * @far: The distance for the far clipping - * plane (negative if the plane is behind the viewer) - * - * Replaces the current projection matrix with an orthographic projection - * matrix. See to see how the matrix is - * calculated. - * - *
- * - * - *
- * - * This function copies the arguments from OpenGL's glOrtho() even - * though they are unnecessarily confusing due to the z near and z far - * arguments actually being a "distance" from the origin, where - * negative values are behind the viewer, instead of coordinates for - * the z clipping planes which would have been consistent with the - * left, right bottom and top arguments. - * - * Since: 1.0 - */ -void -cogl_ortho (float left, - float right, - float bottom, - float top, - float near, - float far); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_viewport: - * @width: Width of the viewport - * @height: Height of the viewport - * - * Replace the current viewport with the given values. - * - * Since: 0.8.2 - * - * Deprecated: 1.2: Use cogl_set_viewport() instead - */ -void -cogl_viewport (unsigned int width, - unsigned int height) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_set_viewport: - * @x: X offset of the viewport - * @y: Y offset of the viewport - * @width: Width of the viewport - * @height: Height of the viewport - * - * Replaces the current viewport with the given values. - * - * Since: 1.2 - */ -void -cogl_set_viewport (int x, - int y, - int width, - int height); - -/** - * cogl_push_matrix: - * - * Stores the current model-view matrix on the matrix stack. The matrix - * can later be restored with cogl_pop_matrix(). - */ -void -cogl_push_matrix (void); - -/** - * cogl_pop_matrix: - * - * Restores the current model-view matrix from the matrix stack. - */ -void -cogl_pop_matrix (void); - -/** - * cogl_scale: - * @x: Amount to scale along the x-axis - * @y: Amount to scale along the y-axis - * @z: Amount to scale along the z-axis - * - * Multiplies the current model-view matrix by one that scales the x, - * y and z axes by the given values. - */ -void -cogl_scale (float x, - float y, - float z); - -/** - * cogl_translate: - * @x: Distance to translate along the x-axis - * @y: Distance to translate along the y-axis - * @z: Distance to translate along the z-axis - * - * Multiplies the current model-view matrix by one that translates the - * model along all three axes according to the given values. - */ -void -cogl_translate (float x, - float y, - float z); - -/** - * cogl_rotate: - * @angle: Angle in degrees to rotate. - * @x: X-component of vertex to rotate around. - * @y: Y-component of vertex to rotate around. - * @z: Z-component of vertex to rotate around. - * - * Multiplies the current model-view matrix by one that rotates the - * model around the vertex specified by @x, @y and @z. The rotation - * follows the right-hand thumb rule so for example rotating by 10 - * degrees about the vertex (0, 0, 1) causes a small counter-clockwise - * rotation. - */ -void -cogl_rotate (float angle, - float x, - float y, - float z); - -/** - * cogl_transform: - * @matrix: the matrix to multiply with the current model-view - * - * Multiplies the current model-view matrix by the given matrix. - * - * Since: 1.4 - */ -void -cogl_transform (const CoglMatrix *matrix); - -/** - * cogl_get_modelview_matrix: - * @matrix: (out): return location for the model-view matrix - * - * Stores the current model-view matrix in @matrix. - */ -void -cogl_get_modelview_matrix (CoglMatrix *matrix); - -/** - * cogl_set_modelview_matrix: - * @matrix: the new model-view matrix - * - * Loads @matrix as the new model-view matrix. - */ -void -cogl_set_modelview_matrix (CoglMatrix *matrix); - -/** - * cogl_get_projection_matrix: - * @matrix: (out): return location for the projection matrix - * - * Stores the current projection matrix in @matrix. - */ -void -cogl_get_projection_matrix (CoglMatrix *matrix); - -/** - * cogl_set_projection_matrix: - * @matrix: the new projection matrix - * - * Loads matrix as the new projection matrix. - */ -void -cogl_set_projection_matrix (CoglMatrix *matrix); - -/** - * cogl_get_viewport: - * @v: (out) (array fixed-size=4): pointer to a 4 element array - * of #floats to receive the viewport dimensions. - * - * Stores the current viewport in @v. @v[0] and @v[1] get the x and y - * position of the viewport and @v[2] and @v[3] get the width and - * height. - */ -void -cogl_get_viewport (float v[4]); - -/** - * cogl_set_depth_test_enabled: - * @setting: %TRUE to enable depth testing or %FALSE to disable. - * - * Sets whether depth testing is enabled. If it is disabled then the - * order that actors are layered on the screen depends solely on the - * order specified using clutter_actor_raise() and - * clutter_actor_lower(), otherwise it will also take into account the - * actor's depth. Depth testing is disabled by default. - * - * Deprecated: 1.4: Use cogl_material_set_depth_test_enabled() - * instead. - */ -void -cogl_set_depth_test_enabled (gboolean setting); - -/** - * cogl_get_depth_test_enabled: - * - * Queries if depth testing has been enabled via cogl_set_depth_test_enable() - * - * Return value: %TRUE if depth testing is enabled, and %FALSE otherwise - * - * Deprecated: 1.4: Use cogl_material_get_depth_test_enabled() - * instead. - */ -gboolean -cogl_get_depth_test_enabled (void); - -/** - * cogl_set_backface_culling_enabled: - * @setting: %TRUE to enable backface culling or %FALSE to disable. - * - * Sets whether textures positioned so that their backface is showing - * should be hidden. This can be used to efficiently draw two-sided - * textures or fully closed cubes without enabling depth testing. This - * only affects calls to the cogl_rectangle* family of functions and - * cogl_vertex_buffer_draw*. Backface culling is disabled by default. - */ -void -cogl_set_backface_culling_enabled (gboolean setting); - -/** - * cogl_get_backface_culling_enabled: - * - * Queries if backface culling has been enabled via - * cogl_set_backface_culling_enabled() - * - * Return value: %TRUE if backface culling is enabled, and %FALSE otherwise - */ -gboolean -cogl_get_backface_culling_enabled (void); - -/** - * cogl_set_fog: - * @fog_color: The color of the fog - * @mode: A #CoglFogMode that determines the equation used to calculate the - * fogging blend factor. - * @density: Used by %COGL_FOG_MODE_EXPONENTIAL and by - * %COGL_FOG_MODE_EXPONENTIAL_SQUARED equations. - * @z_near: Position along Z axis where no fogging should be applied - * @z_far: Position along Z axis where full fogging should be applied - * - * Enables fogging. Fogging causes vertices that are further away from the eye - * to be rendered with a different color. The color is determined according to - * the chosen fog mode; at it's simplest the color is linearly interpolated so - * that vertices at @z_near are drawn fully with their original color and - * vertices at @z_far are drawn fully with @fog_color. Fogging will remain - * enabled until you call cogl_disable_fog(). - * - * The fogging functions only work correctly when primitives use - * unmultiplied alpha colors. By default Cogl will premultiply textures - * and cogl_set_source_color() will premultiply colors, so unless you - * explicitly load your textures requesting an unmultiplied internal format - * and use cogl_material_set_color() you can only use fogging with fully - * opaque primitives. This might improve in the future when we can depend - * on fragment shaders. - */ -void -cogl_set_fog (const CoglColor *fog_color, - CoglFogMode mode, - float density, - float z_near, - float z_far); - -/** - * cogl_disable_fog: - * - * This function disables fogging, so primitives drawn afterwards will not be - * blended with any previously set fog color. - */ -void -cogl_disable_fog (void); - -/** - * CoglBufferBit: - * @COGL_BUFFER_BIT_COLOR: Selects the primary color buffer - * @COGL_BUFFER_BIT_DEPTH: Selects the depth buffer - * @COGL_BUFFER_BIT_STENCIL: Selects the stencil buffer - * - * Types of auxiliary buffers - * - * Since: 1.0 - */ -typedef enum { - COGL_BUFFER_BIT_COLOR = 1L<<0, - COGL_BUFFER_BIT_DEPTH = 1L<<1, - COGL_BUFFER_BIT_STENCIL = 1L<<2 -} CoglBufferBit; - -/** - * cogl_clear: - * @color: Background color to clear to - * @buffers: A mask of #CoglBufferBit's identifying which auxiliary - * buffers to clear - * - * Clears all the auxiliary buffers identified in the @buffers mask, and if - * that includes the color buffer then the specified @color is used. - */ -void -cogl_clear (const CoglColor *color, - unsigned long buffers); - -/** - * cogl_set_source: - * @material: A #CoglMaterial - * - * This function changes the material at the top of the source stack. - * The material at the top of this stack defines the GPU state used to - * process subsequent primitives, such as rectangles drawn with - * cogl_rectangle() or vertices drawn using cogl_vertex_buffer_draw(). - * - * Since: 1.0 - */ -void -cogl_set_source (void *material); - -/** - * cogl_get_source: - * - * Returns the current source material as previously set using - * cogl_set_source(). - * - * You should typically consider the returned material immutable - * and not try to change any of its properties unless you own a - * reference to that material. At times you may be able to get a - * reference to an internally managed materials and the result of - * modifying such materials is undefined. - * - * Return value: The current source material. - * - * Since: 1.6 - */ -void * -cogl_get_source (void); - -/** - * cogl_push_source: - * @material: A #CoglMaterial - * - * Pushes the given @material to the top of the source stack. The - * material at the top of this stack defines the GPU state used to - * process later primitives as defined by cogl_set_source(). - * - * Since: 1.6 - */ -void -cogl_push_source (void *material); - -/** - * cogl_pop_source: - * - * Removes the material at the top of the source stack. The material - * at the top of this stack defines the GPU state used to process - * later primitives as defined by cogl_set_source(). - * - * Since: 1.6 - */ -void -cogl_pop_source (void); - -/** - * cogl_set_source_color: - * @color: a #CoglColor - * - * This is a convenience function for creating a solid fill source material - * from the given color. This color will be used for any subsequent drawing - * operation. - * - * The color will be premultiplied by Cogl, so the color should be - * non-premultiplied. For example: use (1.0, 0.0, 0.0, 0.5) for - * semi-transparent red. - * - * See also cogl_set_source_color4ub() and cogl_set_source_color4f() - * if you already have the color components. - * - * Since: 1.0 - */ -void -cogl_set_source_color (const CoglColor *color); - -/** - * cogl_set_source_color4ub: - * @red: value of the red channel, between 0 and 255 - * @green: value of the green channel, between 0 and 255 - * @blue: value of the blue channel, between 0 and 255 - * @alpha: value of the alpha channel, between 0 and 255 - * - * This is a convenience function for creating a solid fill source material - * from the given color using unsigned bytes for each component. This - * color will be used for any subsequent drawing operation. - * - * The value for each component is an unsigned byte in the range - * between 0 and 255. - * - * Since: 1.0 - */ -void -cogl_set_source_color4ub (guint8 red, - guint8 green, - guint8 blue, - guint8 alpha); - -/** - * cogl_set_source_color4f: - * @red: value of the red channel, between 0 and %1.0 - * @green: value of the green channel, between 0 and %1.0 - * @blue: value of the blue channel, between 0 and %1.0 - * @alpha: value of the alpha channel, between 0 and %1.0 - * - * This is a convenience function for creating a solid fill source material - * from the given color using normalized values for each component. This color - * will be used for any subsequent drawing operation. - * - * The value for each component is a fixed point number in the range - * between 0 and %1.0. If the values passed in are outside that - * range, they will be clamped. - * - * Since: 1.0 - */ -void -cogl_set_source_color4f (float red, - float green, - float blue, - float alpha); - -/** - * cogl_set_source_texture: - * @texture_handle: The Cogl texture you want as your source - * - * This is a convenience function for creating a material with the first - * layer set to #texture_handle and setting that material as the source with - * cogl_set_source. - * - * Note: There is no interaction between calls to cogl_set_source_color - * and cogl_set_source_texture. If you need to blend a texture with a color then - * you can create a simple material like this: - * - * material = cogl_material_new (); - * cogl_material_set_color4ub (material, 0xff, 0x00, 0x00, 0x80); - * cogl_material_set_layer (material, 0, tex_handle); - * cogl_set_source (material); - * - * - * Since: 1.0 - */ -void -cogl_set_source_texture (CoglHandle texture_handle); - -/** - * SECTION:cogl-clipping - * @short_description: Fuctions for manipulating a stack of clipping regions - * - * To support clipping your geometry to rectangles or paths Cogl exposes a - * stack based API whereby each clip region you push onto the stack is - * intersected with the previous region. - */ - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_clip_push_window_rect: - * @x_offset: left edge of the clip rectangle in window coordinates - * @y_offset: top edge of the clip rectangle in window coordinates - * @width: width of the clip rectangle - * @height: height of the clip rectangle - * - * Specifies a rectangular clipping area for all subsequent drawing - * operations. Any drawing commands that extend outside the rectangle - * will be clipped so that only the portion inside the rectangle will - * be displayed. The rectangle dimensions are not transformed by the - * current model-view matrix. - * - * The rectangle is intersected with the current clip region. To undo - * the effect of this function, call cogl_clip_pop(). - * - * Deprecated: 1.2: Use cogl_clip_push_window_rectangle() instead - */ -void -cogl_clip_push_window_rect (float x_offset, - float y_offset, - float width, - float height) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_clip_push_window_rectangle: - * @x_offset: left edge of the clip rectangle in window coordinates - * @y_offset: top edge of the clip rectangle in window coordinates - * @width: width of the clip rectangle - * @height: height of the clip rectangle - * - * Specifies a rectangular clipping area for all subsequent drawing - * operations. Any drawing commands that extend outside the rectangle - * will be clipped so that only the portion inside the rectangle will - * be displayed. The rectangle dimensions are not transformed by the - * current model-view matrix. - * - * The rectangle is intersected with the current clip region. To undo - * the effect of this function, call cogl_clip_pop(). - * - * Since: 1.2 - */ -void -cogl_clip_push_window_rectangle (int x_offset, - int y_offset, - int width, - int height); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_clip_push: - * @x_offset: left edge of the clip rectangle - * @y_offset: top edge of the clip rectangle - * @width: width of the clip rectangle - * @height: height of the clip rectangle - * - * Specifies a rectangular clipping area for all subsequent drawing - * operations. Any drawing commands that extend outside the rectangle - * will be clipped so that only the portion inside the rectangle will - * be displayed. The rectangle dimensions are transformed by the - * current model-view matrix. - * - * The rectangle is intersected with the current clip region. To undo - * the effect of this function, call cogl_clip_pop(). - * - * Deprecated: 1.2: The x, y, width, height arguments are inconsistent - * with other API that specify rectangles in model space, and when used - * with a coordinate space that puts the origin at the center and y+ - * extending up, it's awkward to use. Please use cogl_clip_push_rectangle() - * instead - */ -void -cogl_clip_push (float x_offset, - float y_offset, - float width, - float height) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_clip_push_rectangle: - * @x0: x coordinate for top left corner of the clip rectangle - * @y0: y coordinate for top left corner of the clip rectangle - * @x1: x coordinate for bottom right corner of the clip rectangle - * @y1: y coordinate for bottom right corner of the clip rectangle - * - * Specifies a rectangular clipping area for all subsequent drawing - * operations. Any drawing commands that extend outside the rectangle - * will be clipped so that only the portion inside the rectangle will - * be displayed. The rectangle dimensions are transformed by the - * current model-view matrix. - * - * The rectangle is intersected with the current clip region. To undo - * the effect of this function, call cogl_clip_pop(). - * - * Since: 1.2 - */ -void -cogl_clip_push_rectangle (float x0, - float y0, - float x1, - float y1); - -/** - * cogl_clip_push_from_path_preserve: - * - * Sets a new clipping area using the current path. The current path - * is then cleared. The clipping area is intersected with the previous - * clipping area. To restore the previous clipping area, call - * cogl_clip_pop(). - * - * Since: 1.0 - */ -void -cogl_clip_push_from_path_preserve (void); - -/** - * cogl_clip_pop: - * - * Reverts the clipping region to the state before the last call to - * cogl_clip_push(). - */ -void -cogl_clip_pop (void); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_clip_ensure: - * - * Ensures that the current clipping region has been set in GL. This - * will automatically be called before any Cogl primitives but it - * maybe be neccessary to call if you are using raw GL calls with - * clipping. - * - * Deprecated: 1.2: Calling this function has no effect - * - * Since: 1.0 - */ -void -cogl_clip_ensure (void) G_GNUC_DEPRECATED; - -/** - * cogl_clip_stack_save: - * - * Save the entire state of the clipping stack and then clear all - * clipping. The previous state can be returned to with - * cogl_clip_stack_restore(). Each call to cogl_clip_push() after this - * must be matched by a call to cogl_clip_pop() before calling - * cogl_clip_stack_restore(). - * - * Deprecated: 1.2: This was originally added to allow us to save the - * clip stack when switching to an offscreen framebuffer, but it's - * not necessary anymore given that framebuffers now own separate - * clip stacks which will be automatically switched between when a - * new buffer is set. Calling this function has no effect - * - * Since: 0.8.2 - */ -void -cogl_clip_stack_save (void) G_GNUC_DEPRECATED; - -/** - * cogl_clip_stack_restore: - * - * Restore the state of the clipping stack that was previously saved - * by cogl_clip_stack_save(). - * - * Deprecated: 1.2: This was originally added to allow us to restore - * the clip stack when switching back from an offscreen framebuffer, - * but it's not necessary anymore given that framebuffers now own - * separate clip stacks which will be automatically switched between - * when a new buffer is set. Calling this function has no effect - * - * Since: 0.8.2 - */ -void -cogl_clip_stack_restore (void) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * cogl_set_framebuffer: - * @buffer: A #CoglFramebuffer object, either onscreen or offscreen. - * - * This redirects all subsequent drawing to the specified framebuffer. This can - * either be an offscreen buffer created with cogl_offscreen_new_to_texture () - * or in the future it may be an onscreen framebuffers too. - * - * Since: 1.2 - */ -void -cogl_set_framebuffer (CoglFramebuffer *buffer); - -/** - * cogl_push_framebuffer: - * @buffer: A #CoglFramebuffer object, either onscreen or offscreen. - * - * Redirects all subsequent drawing to the specified framebuffer. This can - * either be an offscreen buffer created with cogl_offscreen_new_to_texture () - * or in the future it may be an onscreen framebuffer too. - * - * You should understand that a framebuffer owns the following state: - * - * The projection matrix - * The modelview matrix stack - * The viewport - * The clip stack - * - * So these items will automatically be saved and restored when you - * push and pop between different framebuffers. - * - * Also remember a newly allocated framebuffer will have an identity matrix for - * the projection and modelview matrices which gives you a coordinate space - * like OpenGL with (-1, -1) corresponding to the top left of the viewport, - * (1, 1) corresponding to the bottom right and +z coming out towards the - * viewer. - * - * If you want to set up a coordinate space like Clutter does with (0, 0) - * corresponding to the top left and (framebuffer_width, framebuffer_height) - * corresponding to the bottom right you can do so like this: - * - * |[ - * static void - * setup_viewport (unsigned int width, - * unsigned int height, - * float fovy, - * float aspect, - * float z_near, - * float z_far) - * { - * float z_camera; - * CoglMatrix projection_matrix; - * CoglMatrix mv_matrix; - * - * cogl_set_viewport (0, 0, width, height); - * cogl_perspective (fovy, aspect, z_near, z_far); - * - * cogl_get_projection_matrix (&projection_matrix); - * z_camera = 0.5 * projection_matrix.xx; - * - * cogl_matrix_init_identity (&mv_matrix); - * cogl_matrix_translate (&mv_matrix, -0.5f, -0.5f, -z_camera); - * cogl_matrix_scale (&mv_matrix, 1.0f / width, -1.0f / height, 1.0f / width); - * cogl_matrix_translate (&mv_matrix, 0.0f, -1.0 * height, 0.0f); - * cogl_set_modelview_matrix (&mv_matrix); - * } - * - * static void - * my_init_framebuffer (ClutterStage *stage, - * CoglFramebuffer *framebuffer, - * unsigned int framebuffer_width, - * unsigned int framebuffer_height) - * { - * ClutterPerspective perspective; - * - * clutter_stage_get_perspective (stage, &perspective); - * - * cogl_push_framebuffer (framebuffer); - * setup_viewport (framebuffer_width, - * framebuffer_height, - * perspective.fovy, - * perspective.aspect, - * perspective.z_near, - * perspective.z_far); - * } - * ]| - * - * The previous framebuffer can be restored by calling cogl_pop_framebuffer() - * - * Since: 1.2 - */ -void -cogl_push_framebuffer (CoglFramebuffer *buffer); - -/** - * cogl_pop_framebuffer: - * - * Restores the framebuffer that was previously at the top of the stack. - * All subsequent drawing will be redirected to this framebuffer. - * - * Since: 1.2 - */ -void -cogl_pop_framebuffer (void); - -#ifndef COGL_DISABLE_DEPRECATED - -/** - * cogl_set_draw_buffer: - * @target: A #CoglBufferTarget that specifies what kind of framebuffer you - * are setting as the render target. - * @offscreen: If you are setting a framebuffer of type COGL_OFFSCREEN_BUFFER - * then this is a CoglHandle for the offscreen buffer. - * - * Redirects all subsequent drawing to the specified framebuffer. This - * can either be an offscreen buffer created with - * cogl_offscreen_new_to_texture () or you can revert to your original - * on screen window buffer. - * - * Deprecated: 1.2: The target argument was redundant since we could look at - * the type of CoglHandle given instead. - */ -void -cogl_set_draw_buffer (CoglBufferTarget target, - CoglHandle offscreen) G_GNUC_DEPRECATED; - -/** - * cogl_push_draw_buffer: - * - * Save cogl_set_draw_buffer() state. - * - * Deprecated: 1.2: The draw buffer API was replaced with a framebuffer API - */ -void -cogl_push_draw_buffer (void) G_GNUC_DEPRECATED; - -/** - * cogl_pop_draw_buffer: - * - * Restore cogl_set_draw_buffer() state. - * - * Deprecated: 1.2: The draw buffer API was replaced with a framebuffer API - */ -void -cogl_pop_draw_buffer (void) G_GNUC_DEPRECATED; - -#endif /* COGL_DISABLE_DEPRECATED */ - -/** - * CoglReadPixelsFlags: - * @COGL_READ_PIXELS_COLOR_BUFFER: Read from the color buffer - * - * Flags for cogl_read_pixels() - * - * Since: 1.0 - */ -typedef enum { /*< prefix=COGL_READ_PIXELS >*/ - COGL_READ_PIXELS_COLOR_BUFFER = 1L << 0 -} CoglReadPixelsFlags; - -/** - * cogl_read_pixels: - * @x: The window x position to start reading from - * @y: The window y position to start reading from - * @width: The width of the rectangle you want to read - * @height: The height of the rectangle you want to read - * @source: Identifies which auxillary buffer you want to read - * (only COGL_READ_PIXELS_COLOR_BUFFER supported currently) - * @format: The pixel format you want the result in - * (only COGL_PIXEL_FORMAT_RGBA_8888 supported currently) - * @pixels: The location to write the pixel data. - * - * This reads a rectangle of pixels from the current framebuffer where - * position (0, 0) is the top left. The pixel at (x, y) is the first - * read, and the data is returned with a rowstride of (width * 4). - * - * Currently Cogl assumes that the framebuffer is in a premultiplied - * format so if @format is non-premultiplied it will convert it. To - * read the pixel values without any conversion you should either - * specify a format that doesn't use an alpha channel or use one of - * the formats ending in PRE. - */ -void -cogl_read_pixels (int x, - int y, - int width, - int height, - CoglReadPixelsFlags source, - CoglPixelFormat format, - guint8 *pixels); - -/** - * cogl_flush: - * - * This function should only need to be called in exceptional circumstances. - * - * As an optimization Cogl drawing functions may batch up primitives - * internally, so if you are trying to use raw GL outside of Cogl you stand a - * better chance of being successful if you ask Cogl to flush any batched - * geometry before making your state changes. - * - * It only ensure that the underlying driver is issued all the commands - * necessary to draw the batched primitives. It provides no guarantees about - * when the driver will complete the rendering. - * - * This provides no guarantees about the GL state upon returning and to avoid - * confusing Cogl you should aim to restore any changes you make before - * resuming use of Cogl. - * - * If you are making state changes with the intention of affecting Cogl drawing - * primitives you are 100% on your own since you stand a good chance of - * conflicting with Cogl internals. For example clutter-gst which currently - * uses direct GL calls to bind ARBfp programs will very likely break when Cogl - * starts to use ARBfb programs itself for the material API. - * - * Since: 1.0 - */ -void -cogl_flush (void); - -/** - * cogl_begin_gl: - * - * We do not advise nor reliably support the interleaving of raw GL drawing and - * Cogl drawing functions, but if you insist, cogl_begin_gl() and cogl_end_gl() - * provide a simple mechanism that may at least give you a fighting chance of - * succeeding. - * - * Note: this doesn't help you modify the behaviour of Cogl drawing functions - * through the modification of GL state; that will never be reliably supported, - * but if you are trying to do something like: - * - * |[ - * { - * - setup some OpenGL state. - * - draw using OpenGL (e.g. glDrawArrays() ) - * - reset modified OpenGL state. - * - continue using Cogl to draw - * } - * ]| - * - * You should surround blocks of drawing using raw GL with cogl_begin_gl() - * and cogl_end_gl(): - * - * |[ - * { - * cogl_begin_gl (); - * - setup some OpenGL state. - * - draw using OpenGL (e.g. glDrawArrays() ) - * - reset modified OpenGL state. - * cogl_end_gl (); - * - continue using Cogl to draw - * } - * ]| - * - * Don't ever try and do: - * - * |[ - * { - * - setup some OpenGL state. - * - use Cogl to draw - * - reset modified OpenGL state. - * } - * ]| - * - * When the internals of Cogl evolves, this is very liable to break. - * - * This function will flush all batched primitives, and subsequently flush - * all internal Cogl state to OpenGL as if it were going to draw something - * itself. - * - * The result is that the OpenGL modelview matrix will be setup; the state - * corresponding to the current source material will be set up and other world - * state such as backface culling, depth and fogging enabledness will be sent - * to OpenGL. - * - * No special material state is flushed, so if you want Cogl to setup a - * simplified material state it is your responsibility to set a simple source - * material before calling cogl_begin_gl(). E.g. by calling - * cogl_set_source_color4ub(). - * - * It is your responsibility to restore any OpenGL state that you modify - * to how it was after calling cogl_begin_gl() if you don't do this then the - * result of further Cogl calls is undefined. - * - * You can not nest begin/end blocks. - * - * Again we would like to stress, we do not advise the use of this API and if - * possible we would prefer to improve Cogl than have developers require raw - * OpenGL. - * - * Since: 1.0 - */ -void -cogl_begin_gl (void); - -/** - * cogl_end_gl: - * - * This is the counterpart to cogl_begin_gl() used to delimit blocks of drawing - * code using raw OpenGL. Please refer to cogl_begin_gl() for full details. - * - * Since: 1.0 - */ -void -cogl_end_gl (void); - -G_END_DECLS - -#undef __COGL_H_INSIDE__ - -#endif /* __COGL_H__ */ diff --git a/clutter/cogl/cogl/cogl.pc.in b/clutter/cogl/cogl/cogl.pc.in deleted file mode 100644 index a2b4a4b..0000000 --- a/clutter/cogl/cogl/cogl.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -apiversion=@COGL_API_VERSION@ -requires=@COGL_PKG_REQUIRES@ - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @COGL_VERSION@ -Libs: -L${libdir} -lcogl -Cflags: -I${includedir}/cogl -DCOGL_ENABLE_EXPERIMENTAL_2_0_API -Requires: ${requires} diff --git a/clutter/cogl/cogl/cogl2-clip-state.c b/clutter/cogl/cogl/cogl2-clip-state.c deleted file mode 100644 index 347e0da..0000000 --- a/clutter/cogl/cogl/cogl2-clip-state.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-clip-state-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-journal-private.h" - -void -cogl2_clip_push_from_path (CoglPath *path) -{ - CoglFramebuffer *framebuffer; - CoglClipState *clip_state; - CoglMatrix modelview_matrix; - - framebuffer = cogl_get_draw_framebuffer (); - clip_state = _cogl_framebuffer_get_clip_state (framebuffer); - - cogl_get_modelview_matrix (&modelview_matrix); - - clip_state->stacks->data = - _cogl_clip_stack_push_from_path (clip_state->stacks->data, - path, - &modelview_matrix); -} diff --git a/clutter/cogl/cogl/cogl2-clip-state.h b/clutter/cogl/cogl/cogl2-clip-state.h deleted file mode 100644 index 9239bb1..0000000 --- a/clutter/cogl/cogl/cogl2-clip-state.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL2_CLIP_STATE_H -#define __COGL2_CLIP_STATE_H - -#include - -G_BEGIN_DECLS - -#define cogl_clip_push_from_path cogl2_clip_push_from_path -/** - * cogl_clip_push_from_path: - * @path: The path to clip with. - * - * Sets a new clipping area using @path. The clipping area is intersected - * with the previous clipping area. To restore the previous clipping area, - * call cogl_clip_pop(). - * - * Since: 1.8 - * Stability: Unstable - */ -void -cogl_clip_push_from_path (CoglPath *path); - -G_END_DECLS - -#endif /* __COGL2_CLIP_STATE_H */ diff --git a/clutter/cogl/cogl/cogl2-path.c b/clutter/cogl/cogl/cogl2-path.c deleted file mode 100644 index b9d1ea1..0000000 --- a/clutter/cogl/cogl/cogl2-path.c +++ /dev/null @@ -1,1572 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Ivan Leben - * Øyvind Kolås - * Neil Roberts - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-object.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-path-private.h" -#include "cogl-texture-private.h" -#include "cogl-primitives-private.h" -#include "cogl-private.h" -#include "cogl-attribute-private.h" -#include "tesselator/tesselator.h" - -#include -#include - -#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 - -static void _cogl_path_free (CoglPath *path); - -static void _cogl_path_build_fill_vbo (CoglPath *path); -static void _cogl_path_build_stroke_vbo (CoglPath *path); - -COGL_OBJECT_DEFINE (Path, path); - -static void -_cogl_path_data_clear_vbos (CoglPathData *data) -{ - int i; - - if (data->fill_vbo) - { - cogl_object_unref (data->fill_vbo); - cogl_object_unref (data->fill_vbo_indices); - - for (i = 0; i < COGL_PATH_N_ATTRIBUTES; i++) - cogl_object_unref (data->fill_vbo_attributes[i]); - - data->fill_vbo = NULL; - } - - if (data->stroke_vbo) - { - cogl_object_unref (data->stroke_vbo); - - for (i = 0; i < data->stroke_vbo_n_attributes; i++) - cogl_object_unref (data->stroke_vbo_attributes[i]); - - g_free (data->stroke_vbo_attributes); - - data->stroke_vbo = NULL; - } -} - -static void -_cogl_path_data_unref (CoglPathData *data) -{ - if (--data->ref_count <= 0) - { - _cogl_path_data_clear_vbos (data); - - g_array_free (data->path_nodes, TRUE); - - g_slice_free (CoglPathData, data); - } -} - -static void -_cogl_path_modify (CoglPath *path) -{ - /* This needs to be called whenever the path is about to be modified - to implement copy-on-write semantics */ - - /* If there is more than one path using the data then we need to - copy the data instead */ - if (path->data->ref_count != 1) - { - CoglPathData *old_data = path->data; - - path->data = g_slice_dup (CoglPathData, old_data); - path->data->path_nodes = g_array_new (FALSE, FALSE, - sizeof (CoglPathNode)); - g_array_append_vals (path->data->path_nodes, - old_data->path_nodes->data, - old_data->path_nodes->len); - - path->data->fill_vbo = COGL_INVALID_HANDLE; - path->data->ref_count = 1; - - _cogl_path_data_unref (old_data); - } - /* The path is altered so the vbo will now be invalid */ - else if (path->data->fill_vbo) - _cogl_path_data_clear_vbos (path->data); -} - -void -cogl2_path_set_fill_rule (CoglPath *path, - CoglPathFillRule fill_rule) -{ - g_return_if_fail (cogl_is_path (path)); - - if (path->data->fill_rule != fill_rule) - { - _cogl_path_modify (path); - - path->data->fill_rule = fill_rule; - } -} - -CoglPathFillRule -cogl2_path_get_fill_rule (CoglPath *path) -{ - g_return_val_if_fail (cogl_is_path (path), COGL_PATH_FILL_RULE_NON_ZERO); - - return path->data->fill_rule; -} - -static void -_cogl_path_add_node (CoglPath *path, - gboolean new_sub_path, - float x, - float y) -{ - CoglPathNode new_node; - CoglPathData *data; - - _cogl_path_modify (path); - - data = path->data; - - new_node.x = x; - new_node.y = y; - new_node.path_size = 0; - - if (new_sub_path || data->path_nodes->len == 0) - data->last_path = data->path_nodes->len; - - g_array_append_val (data->path_nodes, new_node); - - g_array_index (data->path_nodes, CoglPathNode, data->last_path).path_size++; - - if (data->path_nodes->len == 1) - { - data->path_nodes_min.x = data->path_nodes_max.x = x; - data->path_nodes_min.y = data->path_nodes_max.y = y; - } - else - { - if (x < data->path_nodes_min.x) - data->path_nodes_min.x = x; - if (x > data->path_nodes_max.x) - data->path_nodes_max.x = x; - if (y < data->path_nodes_min.y) - data->path_nodes_min.y = y; - if (y > data->path_nodes_max.y) - data->path_nodes_max.y = y; - } - - /* Once the path nodes have been modified then we'll assume it's no - longer a rectangle. cogl2_path_rectangle will set this back to - TRUE if this has been called from there */ - data->is_rectangle = FALSE; -} - -static void -_cogl_path_stroke_nodes (CoglPath *path) -{ - CoglPathData *data = path->data; - CoglPipeline *copy = NULL; - CoglPipeline *source; - unsigned int path_start; - int path_num = 0; - CoglPathNode *node; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (G_UNLIKELY (ctx->legacy_state_set)) - { - CoglPipeline *users_source = cogl_get_source (); - copy = cogl_pipeline_copy (users_source); - _cogl_pipeline_apply_legacy_state (copy); - source = copy; - } - else - source = cogl_get_source (); - - if (cogl_pipeline_get_n_layers (source) != 0) - { - /* If we haven't already created a derivative pipeline... */ - if (!copy) - copy = cogl_pipeline_copy (source); - _cogl_pipeline_prune_to_n_layers (copy, 0); - source = copy; - } - - _cogl_path_build_stroke_vbo (path); - - cogl_push_source (source); - - for (path_start = 0; - path_start < data->path_nodes->len; - path_start += node->path_size) - { - node = &g_array_index (data->path_nodes, CoglPathNode, path_start); - - cogl_draw_attributes (COGL_VERTICES_MODE_LINE_STRIP, - 0, node->path_size, - data->stroke_vbo_attributes[path_num], - NULL); - - path_num++; - } - - cogl_pop_source (); - - if (copy) - cogl_object_unref (copy); -} - -void -_cogl_path_get_bounds (CoglPath *path, - float *min_x, - float *min_y, - float *max_x, - float *max_y) -{ - CoglPathData *data = path->data; - - if (data->path_nodes->len == 0) - { - *min_x = 0.0f; - *min_y = 0.0f; - *max_x = 0.0f; - *max_y = 0.0f; - } - else - { - *min_x = data->path_nodes_min.x; - *min_y = data->path_nodes_min.y; - *max_x = data->path_nodes_max.x; - *max_y = data->path_nodes_max.y; - } -} - -static void -_cogl_path_fill_nodes_with_stencil_buffer (CoglPath *path) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_assert (ctx->current_clip_stack_valid); - - _cogl_add_path_to_stencil_buffer (path, - ctx->current_clip_stack_uses_stencil, - FALSE); - - _cogl_rectangle_immediate (path->data->path_nodes_min.x, - path->data->path_nodes_min.y, - path->data->path_nodes_max.x, - path->data->path_nodes_max.y); - - /* The stencil buffer now contains garbage so the clip area needs to - * be rebuilt. - * - * NB: We only ever try and update the clip state during - * _cogl_journal_init (when we flush the framebuffer state) which is - * only called when the journal first gets something logged in it; so - * we call cogl_flush() to emtpy the journal. - */ - _cogl_clip_stack_dirty (); -} - -static void -_cogl_path_fill_nodes (CoglPath *path) -{ - const GList *l; - - /* If any of the layers of the current pipeline contain sliced - textures or textures with waste then it won't work to draw the - path directly. Instead we can use draw the texture as a quad - clipped to the stencil buffer. */ - for (l = _cogl_pipeline_get_layers (cogl_get_source ()); l; l = l->next) - { - CoglHandle layer = l->data; - CoglHandle texture = _cogl_pipeline_layer_get_texture (layer); - - if (texture != COGL_INVALID_HANDLE && - (cogl_texture_is_sliced (texture) || - !_cogl_texture_can_hardware_repeat (texture))) - { - if (cogl_features_available (COGL_FEATURE_STENCIL_BUFFER)) - _cogl_path_fill_nodes_with_stencil_buffer (path); - else - { - static gboolean seen_warning = FALSE; - - if (!seen_warning) - { - g_warning ("Paths can not be filled using materials with " - "sliced textures unless there is a stencil " - "buffer"); - seen_warning = TRUE; - } - } - - return; - } - } - - _cogl_path_build_fill_vbo (path); - - _cogl_draw_indexed_attributes_array - (COGL_VERTICES_MODE_TRIANGLES, - 0, /* first_vertex */ - path->data->fill_vbo_n_indices, - path->data->fill_vbo_indices, - path->data->fill_vbo_attributes, - COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); -} - -void -_cogl_add_path_to_stencil_buffer (CoglPath *path, - gboolean merge, - gboolean need_clear) -{ - CoglPathData *data = path->data; - CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* This can be called from the clip stack code which doesn't flush - the matrix stacks between calls so we need to ensure they're - flushed now */ - _cogl_matrix_stack_flush_to_gl (modelview_stack, - COGL_MATRIX_MODELVIEW); - _cogl_matrix_stack_flush_to_gl (projection_stack, - COGL_MATRIX_PROJECTION); - - /* Just setup a simple pipeline that doesn't use texturing... */ - cogl_push_source (ctx->stencil_pipeline); - - _cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE, 0); - - GE( glEnable (GL_STENCIL_TEST) ); - - GE( glColorMask (FALSE, FALSE, FALSE, FALSE) ); - GE( glDepthMask (FALSE) ); - - if (merge) - { - GE (glStencilMask (2)); - GE (glStencilFunc (GL_LEQUAL, 0x2, 0x6)); - } - else - { - /* If we're not using the stencil buffer for clipping then we - don't need to clear the whole stencil buffer, just the area - that will be drawn */ - if (need_clear) - /* If this is being called from the clip stack code then it - will have set up a scissor for the minimum bounding box of - all of the clips. That box will likely mean that this - _cogl_clear won't need to clear the entire - buffer. _cogl_clear4f is used instead of cogl_clear because - it won't try to flush the journal */ - _cogl_clear4f (COGL_BUFFER_BIT_STENCIL, 0, 0, 0, 0); - else - { - /* Just clear the bounding box */ - GE( glStencilMask (~(GLuint) 0) ); - GE( glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) ); - _cogl_rectangle_immediate (data->path_nodes_min.x, - data->path_nodes_min.y, - data->path_nodes_max.x, - data->path_nodes_max.y); - } - GE (glStencilMask (1)); - GE (glStencilFunc (GL_LEQUAL, 0x1, 0x3)); - } - - GE (glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT)); - - if (path->data->path_nodes->len >= 3) - _cogl_path_fill_nodes (path); - - if (merge) - { - /* Now we have the new stencil buffer in bit 1 and the old - stencil buffer in bit 0 so we need to intersect them */ - GE (glStencilMask (3)); - GE (glStencilFunc (GL_NEVER, 0x2, 0x3)); - GE (glStencilOp (GL_DECR, GL_DECR, GL_DECR)); - /* Decrement all of the bits twice so that only pixels where the - value is 3 will remain */ - - _cogl_matrix_stack_push (projection_stack); - _cogl_matrix_stack_load_identity (projection_stack); - _cogl_matrix_stack_flush_to_gl (projection_stack, - COGL_MATRIX_PROJECTION); - - _cogl_matrix_stack_push (modelview_stack); - _cogl_matrix_stack_load_identity (modelview_stack); - _cogl_matrix_stack_flush_to_gl (modelview_stack, - COGL_MATRIX_MODELVIEW); - - _cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0); - _cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0); - - _cogl_matrix_stack_pop (modelview_stack); - _cogl_matrix_stack_pop (projection_stack); - } - - GE (glStencilMask (~(GLuint) 0)); - GE (glDepthMask (TRUE)); - GE (glColorMask (TRUE, TRUE, TRUE, TRUE)); - - GE (glStencilFunc (GL_EQUAL, 0x1, 0x1)); - GE (glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP)); - - /* restore the original pipeline */ - cogl_pop_source (); -} - -void -cogl2_path_fill (CoglPath *path) -{ - CoglFramebuffer *framebuffer; - - g_return_if_fail (cogl_is_path (path)); - - if (path->data->path_nodes->len == 0) - return; - - /* If the path is a simple rectangle then we can divert to using - cogl_rectangle which should be faster because it can go through - the journal instead of uploading the geometry just for two - triangles */ - if (path->data->is_rectangle) - { - float x_1, y_1, x_2, y_2; - - _cogl_path_get_bounds (path, &x_1, &y_1, &x_2, &y_2); - cogl_rectangle (x_1, y_1, x_2, y_2); - } - else - { - framebuffer = cogl_get_draw_framebuffer (); - - _cogl_framebuffer_flush_journal (framebuffer); - - /* NB: _cogl_framebuffer_flush_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. */ - _cogl_framebuffer_flush_state (framebuffer, - _cogl_get_read_framebuffer (), - 0); - - _cogl_path_fill_nodes (path); - } -} - -void -cogl2_path_stroke (CoglPath *path) -{ - g_return_if_fail (cogl_is_path (path)); - - if (path->data->path_nodes->len == 0) - return; - - _cogl_path_stroke_nodes (path); -} - -void -cogl2_path_move_to (CoglPath *path, - float x, - float y) -{ - CoglPathData *data; - - g_return_if_fail (cogl_is_path (path)); - - _cogl_path_add_node (path, TRUE, x, y); - - data = path->data; - - data->path_start.x = x; - data->path_start.y = y; - - data->path_pen = data->path_start; -} - -void -cogl2_path_rel_move_to (CoglPath *path, - float x, - float y) -{ - CoglPathData *data; - - g_return_if_fail (cogl_is_path (path)); - - data = path->data; - - cogl2_path_move_to (path, - data->path_pen.x + x, - data->path_pen.y + y); -} - -void -cogl2_path_line_to (CoglPath *path, - float x, - float y) -{ - CoglPathData *data; - - g_return_if_fail (cogl_is_path (path)); - - _cogl_path_add_node (path, FALSE, x, y); - - data = path->data; - - data->path_pen.x = x; - data->path_pen.y = y; -} - -void -cogl2_path_rel_line_to (CoglPath *path, - float x, - float y) -{ - CoglPathData *data; - - g_return_if_fail (cogl_is_path (path)); - - data = path->data; - - cogl2_path_line_to (path, - data->path_pen.x + x, - data->path_pen.y + y); -} - -void -cogl2_path_close (CoglPath *path) -{ - g_return_if_fail (cogl_is_path (path)); - - _cogl_path_add_node (path, FALSE, path->data->path_start.x, - path->data->path_start.y); - - path->data->path_pen = path->data->path_start; -} - -void -cogl2_path_line (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2) -{ - cogl2_path_move_to (path, x_1, y_1); - cogl2_path_line_to (path, x_2, y_2); -} - -void -cogl2_path_polyline (CoglPath *path, - const float *coords, - int num_points) -{ - int c = 0; - - g_return_if_fail (cogl_is_path (path)); - - cogl2_path_move_to (path, coords[0], coords[1]); - - for (c = 1; c < num_points; ++c) - cogl2_path_line_to (path, coords[2*c], coords[2*c+1]); -} - -void -cogl2_path_polygon (CoglPath *path, - const float *coords, - int num_points) -{ - cogl2_path_polyline (path, coords, num_points); - cogl2_path_close (path); -} - -void -cogl2_path_rectangle (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2) -{ - gboolean is_rectangle; - - /* If the path was previously empty and the rectangle isn't mirrored - then we'll record that this is a simple rectangle path so that we - can optimise it */ - is_rectangle = (path->data->path_nodes->len == 0 && - x_2 >= x_1 && - y_2 >= y_1); - - cogl2_path_move_to (path, x_1, y_1); - cogl2_path_line_to (path, x_2, y_1); - cogl2_path_line_to (path, x_2, y_2); - cogl2_path_line_to (path, x_1, y_2); - cogl2_path_close (path); - - path->data->is_rectangle = is_rectangle; -} - -gboolean -_cogl_path_is_rectangle (CoglPath *path) -{ - return path->data->is_rectangle; -} - -static void -_cogl_path_arc (CoglPath *path, - float center_x, - float center_y, - float radius_x, - float radius_y, - float angle_1, - float angle_2, - float angle_step, - unsigned int move_first) -{ - float a = 0x0; - float cosa = 0x0; - float sina = 0x0; - float px = 0x0; - float py = 0x0; - - /* Fix invalid angles */ - - if (angle_1 == angle_2 || angle_step == 0x0) - return; - - if (angle_step < 0x0) - angle_step = -angle_step; - - /* Walk the arc by given step */ - - a = angle_1; - while (a != angle_2) - { - cosa = cosf (a * (G_PI/180.0)); - sina = sinf (a * (G_PI/180.0)); - - px = center_x + (cosa * radius_x); - py = center_y + (sina * radius_y); - - if (a == angle_1 && move_first) - cogl2_path_move_to (path, px, py); - else - cogl2_path_line_to (path, px, py); - - if (G_LIKELY (angle_2 > angle_1)) - { - a += angle_step; - if (a > angle_2) - a = angle_2; - } - else - { - a -= angle_step; - if (a < angle_2) - a = angle_2; - } - } - - /* Make sure the final point is drawn */ - - cosa = cosf (angle_2 * (G_PI/180.0)); - sina = sinf (angle_2 * (G_PI/180.0)); - - px = center_x + (cosa * radius_x); - py = center_y + (sina * radius_y); - - cogl2_path_line_to (path, px, py); -} - -void -cogl2_path_arc (CoglPath *path, - float center_x, - float center_y, - float radius_x, - float radius_y, - float angle_1, - float angle_2) -{ - float angle_step = 10; - - g_return_if_fail (cogl_is_path (path)); - - /* it is documented that a move to is needed to create a freestanding - * arc - */ - _cogl_path_arc (path, - center_x, center_y, - radius_x, radius_y, - angle_1, angle_2, - angle_step, 0 /* no move */); -} - - -static void -_cogl_path_rel_arc (CoglPath *path, - float center_x, - float center_y, - float radius_x, - float radius_y, - float angle_1, - float angle_2, - float angle_step) -{ - CoglPathData *data; - - data = path->data; - - _cogl_path_arc (path, - data->path_pen.x + center_x, - data->path_pen.y + center_y, - radius_x, radius_y, - angle_1, angle_2, - angle_step, 0 /* no move */); -} - -void -cogl2_path_ellipse (CoglPath *path, - float center_x, - float center_y, - float radius_x, - float radius_y) -{ - float angle_step = 10; - - g_return_if_fail (cogl_is_path (path)); - - /* FIXME: if shows to be slow might be optimized - * by mirroring just a quarter of it */ - - _cogl_path_arc (path, - center_x, center_y, - radius_x, radius_y, - 0, 360, - angle_step, 1 /* move first */); - - cogl2_path_close (path); -} - -void -cogl2_path_round_rectangle (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2, - float radius, - float arc_step) -{ - float inner_width = x_2 - x_1 - radius * 2; - float inner_height = y_2 - y_1 - radius * 2; - - g_return_if_fail (cogl_is_path (path)); - - cogl2_path_move_to (path, x_1, y_1 + radius); - _cogl_path_rel_arc (path, - radius, 0, - radius, radius, - 180, - 270, - arc_step); - - cogl2_path_line_to (path, - path->data->path_pen.x + inner_width, - path->data->path_pen.y); - _cogl_path_rel_arc (path, - 0, radius, - radius, radius, - -90, - 0, - arc_step); - - cogl2_path_line_to (path, - path->data->path_pen.x, - path->data->path_pen.y + inner_height); - - _cogl_path_rel_arc (path, - -radius, 0, - radius, radius, - 0, - 90, - arc_step); - - cogl2_path_line_to (path, - path->data->path_pen.x - inner_width, - path->data->path_pen.y); - _cogl_path_rel_arc (path, - 0, -radius, - radius, radius, - 90, - 180, - arc_step); - - cogl2_path_close (path); -} - -static void -_cogl_path_bezier3_sub (CoglPath *path, - CoglBezCubic *cubic) -{ - CoglBezCubic cubics[_COGL_MAX_BEZ_RECURSE_DEPTH]; - CoglBezCubic *cleft; - CoglBezCubic *cright; - CoglBezCubic *c; - floatVec2 dif1; - floatVec2 dif2; - floatVec2 mm; - floatVec2 c1; - floatVec2 c2; - floatVec2 c3; - floatVec2 c4; - floatVec2 c5; - int cindex; - - /* Put first curve on stack */ - cubics[0] = *cubic; - cindex = 0; - - while (cindex >= 0) - { - c = &cubics[cindex]; - - - /* Calculate distance of control points from their - * counterparts on the line between end points */ - dif1.x = (c->p2.x * 3) - (c->p1.x * 2) - c->p4.x; - dif1.y = (c->p2.y * 3) - (c->p1.y * 2) - c->p4.y; - dif2.x = (c->p3.x * 3) - (c->p4.x * 2) - c->p1.x; - dif2.y = (c->p3.y * 3) - (c->p4.y * 2) - c->p1.y; - - if (dif1.x < 0) - dif1.x = -dif1.x; - if (dif1.y < 0) - dif1.y = -dif1.y; - if (dif2.x < 0) - dif2.x = -dif2.x; - if (dif2.y < 0) - dif2.y = -dif2.y; - - - /* Pick the greatest of two distances */ - if (dif1.x < dif2.x) dif1.x = dif2.x; - if (dif1.y < dif2.y) dif1.y = dif2.y; - - /* Cancel if the curve is flat enough */ - if (dif1.x + dif1.y <= 1.0 || - cindex == _COGL_MAX_BEZ_RECURSE_DEPTH-1) - { - /* Add subdivision point (skip last) */ - if (cindex == 0) - return; - - _cogl_path_add_node (path, FALSE, c->p4.x, c->p4.y); - - --cindex; - - continue; - } - - /* Left recursion goes on top of stack! */ - cright = c; cleft = &cubics[++cindex]; - - /* Subdivide into 2 sub-curves */ - c1.x = ((c->p1.x + c->p2.x) / 2); - c1.y = ((c->p1.y + c->p2.y) / 2); - mm.x = ((c->p2.x + c->p3.x) / 2); - mm.y = ((c->p2.y + c->p3.y) / 2); - c5.x = ((c->p3.x + c->p4.x) / 2); - c5.y = ((c->p3.y + c->p4.y) / 2); - - c2.x = ((c1.x + mm.x) / 2); - c2.y = ((c1.y + mm.y) / 2); - c4.x = ((mm.x + c5.x) / 2); - c4.y = ((mm.y + c5.y) / 2); - - c3.x = ((c2.x + c4.x) / 2); - c3.y = ((c2.y + c4.y) / 2); - - /* Add left recursion to stack */ - cleft->p1 = c->p1; - cleft->p2 = c1; - cleft->p3 = c2; - cleft->p4 = c3; - - /* Add right recursion to stack */ - cright->p1 = c3; - cright->p2 = c4; - cright->p3 = c5; - cright->p4 = c->p4; - } -} - -void -cogl2_path_curve_to (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3) -{ - CoglBezCubic cubic; - - g_return_if_fail (cogl_is_path (path)); - - /* Prepare cubic curve */ - cubic.p1 = path->data->path_pen; - cubic.p2.x = x_1; - cubic.p2.y = y_1; - cubic.p3.x = x_2; - cubic.p3.y = y_2; - cubic.p4.x = x_3; - cubic.p4.y = y_3; - - /* Run subdivision */ - _cogl_path_bezier3_sub (path, &cubic); - - /* Add last point */ - _cogl_path_add_node (path, FALSE, cubic.p4.x, cubic.p4.y); - path->data->path_pen = cubic.p4; -} - -void -cogl2_path_rel_curve_to (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3) -{ - CoglPathData *data; - - g_return_if_fail (cogl_is_path (path)); - - data = path->data; - - cogl2_path_curve_to (path, - data->path_pen.x + x_1, - data->path_pen.y + y_1, - data->path_pen.x + x_2, - data->path_pen.y + y_2, - data->path_pen.x + x_3, - data->path_pen.y + y_3); -} - -CoglPath * -cogl2_path_new (void) -{ - CoglPath *path; - CoglPathData *data; - - path = g_slice_new (CoglPath); - data = path->data = g_slice_new (CoglPathData); - - data->ref_count = 1; - data->fill_rule = COGL_PATH_FILL_RULE_EVEN_ODD; - data->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode)); - data->last_path = 0; - data->fill_vbo = COGL_INVALID_HANDLE; - data->stroke_vbo = NULL; - data->is_rectangle = FALSE; - - return _cogl_path_object_new (path); -} - -CoglPath * -cogl_path_copy (CoglPath *old_path) -{ - CoglPath *new_path; - - g_return_val_if_fail (cogl_is_path (old_path), NULL); - - new_path = g_slice_new (CoglPath); - new_path->data = old_path->data; - new_path->data->ref_count++; - - return _cogl_path_object_new (new_path); -} - -static void -_cogl_path_free (CoglPath *path) -{ - _cogl_path_data_unref (path->data); - g_slice_free (CoglPath, path); -} - -/* If second order beziers were needed the following code could - * be re-enabled: - */ -#if 0 - -static void -_cogl_path_bezier2_sub (CoglPath *path, - CoglBezQuad *quad) -{ - CoglBezQuad quads[_COGL_MAX_BEZ_RECURSE_DEPTH]; - CoglBezQuad *qleft; - CoglBezQuad *qright; - CoglBezQuad *q; - floatVec2 mid; - floatVec2 dif; - floatVec2 c1; - floatVec2 c2; - floatVec2 c3; - int qindex; - - /* Put first curve on stack */ - quads[0] = *quad; - qindex = 0; - - /* While stack is not empty */ - while (qindex >= 0) - { - - q = &quads[qindex]; - - /* Calculate distance of control point from its - * counterpart on the line between end points */ - mid.x = ((q->p1.x + q->p3.x) / 2); - mid.y = ((q->p1.y + q->p3.y) / 2); - dif.x = (q->p2.x - mid.x); - dif.y = (q->p2.y - mid.y); - if (dif.x < 0) dif.x = -dif.x; - if (dif.y < 0) dif.y = -dif.y; - - /* Cancel if the curve is flat enough */ - if (dif.x + dif.y <= 1.0 || - qindex == _COGL_MAX_BEZ_RECURSE_DEPTH - 1) - { - /* Add subdivision point (skip last) */ - if (qindex == 0) return; - _cogl_path_add_node (path, FALSE, q->p3.x, q->p3.y); - --qindex; continue; - } - - /* Left recursion goes on top of stack! */ - qright = q; qleft = &quads[++qindex]; - - /* Subdivide into 2 sub-curves */ - c1.x = ((q->p1.x + q->p2.x) / 2); - c1.y = ((q->p1.y + q->p2.y) / 2); - c3.x = ((q->p2.x + q->p3.x) / 2); - c3.y = ((q->p2.y + q->p3.y) / 2); - c2.x = ((c1.x + c3.x) / 2); - c2.y = ((c1.y + c3.y) / 2); - - /* Add left recursion onto stack */ - qleft->p1 = q->p1; - qleft->p2 = c1; - qleft->p3 = c2; - - /* Add right recursion onto stack */ - qright->p1 = c2; - qright->p2 = c3; - qright->p3 = q->p3; - } -} - -void -cogl_path_curve2_to (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglBezQuad quad; - - /* Prepare quadratic curve */ - quad.p1 = path->data->path_pen; - quad.p2.x = x_1; - quad.p2.y = y_1; - quad.p3.x = x_2; - quad.p3.y = y_2; - - /* Run subdivision */ - _cogl_path_bezier2_sub (&quad); - - /* Add last point */ - _cogl_path_add_node (FALSE, quad.p3.x, quad.p3.y); - path->data->path_pen = quad.p3; -} - -void -cogl_rel_curve2_to (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglPathData *data; - - g_return_if_fail (cogl_is_path (path)); - - data = path->data; - - cogl_path_curve2_to (data->path_pen.x + x_1, - data->path_pen.y + y_1, - data->path_pen.x + x_2, - data->path_pen.y + y_2); -} - -#endif - -typedef struct _CoglPathTesselator CoglPathTesselator; -typedef struct _CoglPathTesselatorVertex CoglPathTesselatorVertex; - -struct _CoglPathTesselator -{ - GLUtesselator *glu_tess; - GLenum primitive_type; - int vertex_number; - /* Array of CoglPathTesselatorVertex. This needs to grow when the - combine callback is called */ - GArray *vertices; - /* Array of integers for the indices into the vertices array. Each - element will either be guint8, guint16 or guint32 depending on - the number of vertices */ - GArray *indices; - CoglIndicesType indices_type; - /* Indices used to split fans and strips */ - int index_a, index_b; -}; - -struct _CoglPathTesselatorVertex -{ - float x, y, s, t; -}; - -static void -_cogl_path_tesselator_begin (GLenum type, - CoglPathTesselator *tess) -{ - g_assert (type == GL_TRIANGLES || - type == GL_TRIANGLE_FAN || - type == GL_TRIANGLE_STRIP); - - tess->primitive_type = type; - tess->vertex_number = 0; -} - -static CoglIndicesType -_cogl_path_tesselator_get_indices_type_for_size (int n_vertices) -{ - if (n_vertices <= 256) - return COGL_INDICES_TYPE_UNSIGNED_BYTE; - else if (n_vertices <= 65536) - return COGL_INDICES_TYPE_UNSIGNED_SHORT; - else - return COGL_INDICES_TYPE_UNSIGNED_INT; -} - -static void -_cogl_path_tesselator_allocate_indices_array (CoglPathTesselator *tess) -{ - switch (tess->indices_type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - tess->indices = g_array_new (FALSE, FALSE, sizeof (guint8)); - break; - - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - tess->indices = g_array_new (FALSE, FALSE, sizeof (guint16)); - break; - - case COGL_INDICES_TYPE_UNSIGNED_INT: - tess->indices = g_array_new (FALSE, FALSE, sizeof (guint32)); - break; - } -} - -static void -_cogl_path_tesselator_add_index (CoglPathTesselator *tess, int vertex_index) -{ - switch (tess->indices_type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - { - guint8 val = vertex_index; - g_array_append_val (tess->indices, val); - } - break; - - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - { - guint16 val = vertex_index; - g_array_append_val (tess->indices, val); - } - break; - - case COGL_INDICES_TYPE_UNSIGNED_INT: - { - guint32 val = vertex_index; - g_array_append_val (tess->indices, val); - } - break; - } -} - -static void -_cogl_path_tesselator_vertex (void *vertex_data, - CoglPathTesselator *tess) -{ - int vertex_index; - - vertex_index = GPOINTER_TO_INT (vertex_data); - - /* This tries to convert all of the primitives into GL_TRIANGLES - with indices to share vertices */ - switch (tess->primitive_type) - { - case GL_TRIANGLES: - /* Directly use the vertex */ - _cogl_path_tesselator_add_index (tess, vertex_index); - break; - - case GL_TRIANGLE_FAN: - if (tess->vertex_number == 0) - tess->index_a = vertex_index; - else if (tess->vertex_number == 1) - tess->index_b = vertex_index; - else - { - /* Create a triangle with the first vertex, the previous - vertex and this vertex */ - _cogl_path_tesselator_add_index (tess, tess->index_a); - _cogl_path_tesselator_add_index (tess, tess->index_b); - _cogl_path_tesselator_add_index (tess, vertex_index); - /* Next time we will use this vertex as the previous - vertex */ - tess->index_b = vertex_index; - } - break; - - case GL_TRIANGLE_STRIP: - if (tess->vertex_number == 0) - tess->index_a = vertex_index; - else if (tess->vertex_number == 1) - tess->index_b = vertex_index; - else - { - _cogl_path_tesselator_add_index (tess, tess->index_a); - _cogl_path_tesselator_add_index (tess, tess->index_b); - _cogl_path_tesselator_add_index (tess, vertex_index); - if (tess->vertex_number & 1) - tess->index_b = vertex_index; - else - tess->index_a = vertex_index; - } - break; - - default: - g_assert_not_reached (); - } - - tess->vertex_number++; -} - -static void -_cogl_path_tesselator_end (CoglPathTesselator *tess) -{ - tess->primitive_type = GL_FALSE; -} - -static void -_cogl_path_tesselator_combine (double coords[3], - void *vertex_data[4], - float weight[4], - void **out_data, - CoglPathTesselator *tess) -{ - CoglPathTesselatorVertex *vertex; - CoglIndicesType new_indices_type; - int i; - - /* Add a new vertex to the array */ - g_array_set_size (tess->vertices, tess->vertices->len + 1); - vertex = &g_array_index (tess->vertices, - CoglPathTesselatorVertex, - tess->vertices->len - 1); - /* The data is just the index to the vertex */ - *out_data = GINT_TO_POINTER (tess->vertices->len - 1); - /* Set the coordinates of the new vertex */ - vertex->x = coords[0]; - vertex->y = coords[1]; - /* Generate the texture coordinates as the weighted average of the - four incoming coordinates */ - vertex->s = 0.0f; - vertex->t = 0.0f; - for (i = 0; i < 4; i++) - { - CoglPathTesselatorVertex *old_vertex = - &g_array_index (tess->vertices, CoglPathTesselatorVertex, - GPOINTER_TO_INT (vertex_data[i])); - vertex->s += old_vertex->s * weight[i]; - vertex->t += old_vertex->t * weight[i]; - } - - /* Check if we've reached the limit for the data type of our indices */ - new_indices_type = - _cogl_path_tesselator_get_indices_type_for_size (tess->vertices->len); - if (new_indices_type != tess->indices_type) - { - CoglIndicesType old_indices_type = new_indices_type; - GArray *old_vertices = tess->indices; - - /* Copy the indices to an array of the new type */ - tess->indices_type = new_indices_type; - _cogl_path_tesselator_allocate_indices_array (tess); - - switch (old_indices_type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - for (i = 0; i < old_vertices->len; i++) - _cogl_path_tesselator_add_index (tess, - g_array_index (old_vertices, - guint8, i)); - break; - - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - for (i = 0; i < old_vertices->len; i++) - _cogl_path_tesselator_add_index (tess, - g_array_index (old_vertices, - guint16, i)); - break; - - case COGL_INDICES_TYPE_UNSIGNED_INT: - for (i = 0; i < old_vertices->len; i++) - _cogl_path_tesselator_add_index (tess, - g_array_index (old_vertices, - guint32, i)); - break; - } - - g_array_free (old_vertices, TRUE); - } -} - -static void -_cogl_path_build_fill_vbo (CoglPath *path) -{ - CoglPathTesselator tess; - unsigned int path_start = 0; - CoglPathData *data = path->data; - int i; - - /* If we've already got a vbo then we don't need to do anything */ - if (data->fill_vbo) - return; - - tess.primitive_type = FALSE; - - /* Generate a vertex for each point on the path */ - tess.vertices = g_array_new (FALSE, FALSE, sizeof (CoglPathTesselatorVertex)); - g_array_set_size (tess.vertices, data->path_nodes->len); - for (i = 0; i < data->path_nodes->len; i++) - { - CoglPathNode *node = - &g_array_index (data->path_nodes, CoglPathNode, i); - CoglPathTesselatorVertex *vertex = - &g_array_index (tess.vertices, CoglPathTesselatorVertex, i); - - vertex->x = node->x; - vertex->y = node->y; - - /* Add texture coordinates so that a texture would be drawn to - fit the bounding box of the path and then cropped by the - path */ - if (data->path_nodes_min.x == data->path_nodes_max.x) - vertex->s = 0.0f; - else - vertex->s = ((node->x - data->path_nodes_min.x) - / (data->path_nodes_max.x - data->path_nodes_min.x)); - if (data->path_nodes_min.y == data->path_nodes_max.y) - vertex->t = 0.0f; - else - vertex->t = ((node->y - data->path_nodes_min.y) - / (data->path_nodes_max.y - data->path_nodes_min.y)); - } - - tess.indices_type = - _cogl_path_tesselator_get_indices_type_for_size (data->path_nodes->len); - _cogl_path_tesselator_allocate_indices_array (&tess); - - tess.glu_tess = gluNewTess (); - - if (data->fill_rule == COGL_PATH_FILL_RULE_EVEN_ODD) - gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE, - GLU_TESS_WINDING_ODD); - else - gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE, - GLU_TESS_WINDING_NONZERO); - - /* All vertices are on the xy-plane */ - gluTessNormal (tess.glu_tess, 0.0, 0.0, 1.0); - - gluTessCallback (tess.glu_tess, GLU_TESS_BEGIN_DATA, - _cogl_path_tesselator_begin); - gluTessCallback (tess.glu_tess, GLU_TESS_VERTEX_DATA, - _cogl_path_tesselator_vertex); - gluTessCallback (tess.glu_tess, GLU_TESS_END_DATA, - _cogl_path_tesselator_end); - gluTessCallback (tess.glu_tess, GLU_TESS_COMBINE_DATA, - _cogl_path_tesselator_combine); - - gluTessBeginPolygon (tess.glu_tess, &tess); - - while (path_start < data->path_nodes->len) - { - CoglPathNode *node = - &g_array_index (data->path_nodes, CoglPathNode, path_start); - - gluTessBeginContour (tess.glu_tess); - - for (i = 0; i < node->path_size; i++) - { - double vertex[3] = { node[i].x, node[i].y, 0.0 }; - gluTessVertex (tess.glu_tess, vertex, - GINT_TO_POINTER (i + path_start)); - } - - gluTessEndContour (tess.glu_tess); - - path_start += node->path_size; - } - - gluTessEndPolygon (tess.glu_tess); - - gluDeleteTess (tess.glu_tess); - - data->fill_vbo = cogl_vertex_array_new (sizeof (CoglPathTesselatorVertex) * - tess.vertices->len, - tess.vertices->data); - g_array_free (tess.vertices, TRUE); - - data->fill_vbo_attributes[0] = - cogl_attribute_new (data->fill_vbo, - "cogl_position_in", - sizeof (CoglPathTesselatorVertex), - G_STRUCT_OFFSET (CoglPathTesselatorVertex, x), - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - data->fill_vbo_attributes[1] = - cogl_attribute_new (data->fill_vbo, - "cogl_tex_coord0_in", - sizeof (CoglPathTesselatorVertex), - G_STRUCT_OFFSET (CoglPathTesselatorVertex, s), - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - /* NULL terminator */ - data->fill_vbo_attributes[2] = NULL; - - data->fill_vbo_indices = cogl_indices_new (tess.indices_type, - tess.indices->data, - tess.indices->len); - data->fill_vbo_n_indices = tess.indices->len; - g_array_free (tess.indices, TRUE); -} - -static void -_cogl_path_build_stroke_vbo (CoglPath *path) -{ - CoglPathData *data = path->data; - unsigned int n_attributes = 0; - unsigned int path_start; - CoglPathNode *node; - floatVec2 *vbo_p; - unsigned int i; - - /* If we've already got a cached vbo then we don't need to do anything */ - if (data->stroke_vbo) - return; - - data->stroke_vbo = cogl_vertex_array_new (data->path_nodes->len * - sizeof (floatVec2), - NULL); - - vbo_p = - _cogl_buffer_map_for_fill_or_fallback (COGL_BUFFER (data->stroke_vbo)); - - /* Copy the vertices in and count the number of sub paths. Each sub - path will form a separate attribute so we can paint the disjoint - line strips */ - for (path_start = 0; - path_start < data->path_nodes->len; - path_start += node->path_size) - { - node = &g_array_index (data->path_nodes, CoglPathNode, path_start); - - for (i = 0; i < node->path_size; i++) - { - vbo_p[path_start + i].x = node[i].x; - vbo_p[path_start + i].y = node[i].y; - } - - n_attributes++; - } - - _cogl_buffer_unmap_for_fill_or_fallback (COGL_BUFFER (data->stroke_vbo)); - - data->stroke_vbo_attributes = g_new (CoglAttribute *, n_attributes); - - /* Now we can loop the sub paths again to create the attributes */ - for (i = 0, path_start = 0; - path_start < data->path_nodes->len; - i++, path_start += node->path_size) - { - node = &g_array_index (data->path_nodes, CoglPathNode, path_start); - - data->stroke_vbo_attributes[i] = - cogl_attribute_new (data->stroke_vbo, - "cogl_position_in", - sizeof (floatVec2), - path_start * sizeof (floatVec2), - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - } - - data->stroke_vbo_n_attributes = n_attributes; -} diff --git a/clutter/cogl/cogl/cogl2-path.h b/clutter/cogl/cogl/cogl2-path.h deleted file mode 100644 index f702c4a..0000000 --- a/clutter/cogl/cogl/cogl2-path.h +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL2_PATH_H__ -#define __COGL2_PATH_H__ - -#include - -G_BEGIN_DECLS - -/** - * SECTION:cogl-paths - * @short_description: Functions for constructing and drawing 2D paths. - * - * There are two levels on which drawing with cogl-paths can be used. - * The highest level functions construct various simple primitive - * shapes to be either filled or stroked. Using a lower-level set of - * functions more complex and arbitrary paths can be constructed by - * concatenating straight line, bezier curve and arc segments. - * - * When constructing arbitrary paths, the current pen location is - * initialized using the move_to command. The subsequent path segments - * implicitly use the last pen location as their first vertex and move - * the pen location to the last vertex they produce at the end. Also - * there are special versions of functions that allow specifying the - * vertices of the path segments relative to the last pen location - * rather then in the absolute coordinates. - */ - -typedef struct _CoglPath CoglPath; - -#define COGL_PATH(obj) ((CoglPath *)(obj)) - -#define cogl_path_new cogl2_path_new -/** - * cogl_path_new: - * - * Creates a new, empty path object. The default fill rule is - * %COGL_PATH_FILL_RULE_EVEN_ODD. - * - * Return value: A pointer to a newly allocated #CoglPath, which can - * be freed using cogl_object_unref(). - * - * Since: 2.0 - */ -CoglPath * -cogl_path_new (void); - -/** - * cogl_path_copy: - * @path: A #CoglPath object - * - * Returns a new copy of the path in @path. The new path has a - * reference count of 1 so you should unref it with - * cogl_object_unref() if you no longer need it. - * - * Internally the path will share the data until one of the paths is - * modified so copying paths should be relatively cheap. - * - * Return value: a copy of the path in @path. - * - * Since: 2.0 - */ -CoglPath * -cogl_path_copy (CoglPath *path); - -/** - * cogl_is_path: - * @object: A #CoglObject - * - * Gets whether the given object references an existing path object. - * - * Return value: %TRUE if the object references a #CoglPath, - * %FALSE otherwise. - * - * Since: 2.0 - */ -gboolean -cogl_is_path (void *object); - -#define cogl_path_move_to cogl2_path_move_to -/** - * cogl_path_move_to: - * @x: X coordinate of the pen location to move to. - * @y: Y coordinate of the pen location to move to. - * - * Moves the pen to the given location. If there is an existing path - * this will start a new disjoint subpath. - * - * Since: 2.0 - */ -void -cogl_path_move_to (CoglPath *path, - float x, - float y); - -#define cogl_path_rel_move_to cogl2_path_rel_move_to -/** - * cogl_path_rel_move_to: - * @x: X offset from the current pen location to move the pen to. - * @y: Y offset from the current pen location to move the pen to. - * - * Moves the pen to the given offset relative to the current pen - * location. If there is an existing path this will start a new - * disjoint subpath. - * - * Since: 2.0 - */ -void -cogl_path_rel_move_to (CoglPath *path, - float x, - float y); - -#define cogl_path_line_to cogl2_path_line_to -/** - * cogl_path_line_to: - * @x: X coordinate of the end line vertex - * @y: Y coordinate of the end line vertex - * - * Adds a straight line segment to the current path that ends at the - * given coordinates. - * - * Since: 2.0 - */ -void -cogl_path_line_to (CoglPath *path, - float x, - float y); - -#define cogl_path_rel_line_to cogl2_path_rel_line_to -/** - * cogl_path_rel_line_to: - * @x: X offset from the current pen location of the end line vertex - * @y: Y offset from the current pen location of the end line vertex - * - * Adds a straight line segment to the current path that ends at the - * given coordinates relative to the current pen location. - * - * Since: 2.0 - */ -void -cogl_path_rel_line_to (CoglPath *path, - float x, - float y); - -#define cogl_path_arc cogl2_path_arc -/** - * cogl_path_arc: - * @center_x: X coordinate of the elliptical arc center - * @center_y: Y coordinate of the elliptical arc center - * @radius_x: X radius of the elliptical arc - * @radius_y: Y radius of the elliptical arc - * @angle_1: Angle in degrees at which the arc begin - * @angle_2: Angle in degrees at which the arc ends - * - * Adds an elliptical arc segment to the current path. A straight line - * segment will link the current pen location with the first vertex - * of the arc. If you perform a move_to to the arcs start just before - * drawing it you create a free standing arc. - * - * The angles are measured in degrees where 0° is in the direction of - * the positive X axis and 90° is in the direction of the positive Y - * axis. The angle of the arc begins at @angle_1 and heads towards - * @angle_2 (so if @angle_2 is less than @angle_1 it will decrease, - * otherwise it will increase). - * - * Since: 2.0 - */ -void -cogl_path_arc (CoglPath *path, - float center_x, - float center_y, - float radius_x, - float radius_y, - float angle_1, - float angle_2); - -#define cogl_path_curve_to cogl2_path_curve_to -/** - * cogl_path_curve_to: - * @x_1: X coordinate of the second bezier control point - * @y_1: Y coordinate of the second bezier control point - * @x_2: X coordinate of the third bezier control point - * @y_2: Y coordinate of the third bezier control point - * @x_3: X coordinate of the fourth bezier control point - * @y_3: Y coordinate of the fourth bezier control point - * - * Adds a cubic bezier curve segment to the current path with the given - * second, third and fourth control points and using current pen location - * as the first control point. - * - * Since: 2.0 - */ -void -cogl_path_curve_to (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3); - -#define cogl_path_rel_curve_to cogl2_path_rel_curve_to -/** - * cogl_path_rel_curve_to: - * @x_1: X coordinate of the second bezier control point - * @y_1: Y coordinate of the second bezier control point - * @x_2: X coordinate of the third bezier control point - * @y_2: Y coordinate of the third bezier control point - * @x_3: X coordinate of the fourth bezier control point - * @y_3: Y coordinate of the fourth bezier control point - * - * Adds a cubic bezier curve segment to the current path with the given - * second, third and fourth control points and using current pen location - * as the first control point. The given coordinates are relative to the - * current pen location. - * - * Since: 2.0 - */ -void -cogl_path_rel_curve_to (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2, - float x_3, - float y_3); - -#define cogl_path_close cogl2_path_close -/** - * cogl_path_close: - * - * Closes the path being constructed by adding a straight line segment - * to it that ends at the first vertex of the path. - * - * Since: 2.0 - */ -void -cogl_path_close (CoglPath *path); - -#define cogl_path_line cogl2_path_line -/** - * cogl_path_line: - * @x_1: X coordinate of the start line vertex - * @y_1: Y coordinate of the start line vertex - * @x_2: X coordinate of the end line vertex - * @y_2: Y coordinate of the end line vertex - * - * Constructs a straight line shape starting and ending at the given - * coordinates. If there is an existing path this will start a new - * disjoint sub-path. - * - * Since: 2.0 - */ -void -cogl_path_line (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2); - -#define cogl_path_polyline cogl2_path_polyline -/** - * cogl_path_polyline: - * @coords: (in) (array) (transfer none): A pointer to the first element of an - * array of fixed-point values that specify the vertex coordinates. - * @num_points: The total number of vertices. - * - * Constructs a series of straight line segments, starting from the - * first given vertex coordinate. If there is an existing path this - * will start a new disjoint sub-path. Each subsequent segment starts - * where the previous one ended and ends at the next given vertex - * coordinate. - * - * The coords array must contain 2 * num_points values. The first value - * represents the X coordinate of the first vertex, the second value - * represents the Y coordinate of the first vertex, continuing in the same - * fashion for the rest of the vertices. (num_points - 1) segments will - * be constructed. - * - * Since: 2.0 - */ -void -cogl_path_polyline (CoglPath *path, - const float *coords, - int num_points); - -#define cogl_path_polygon cogl2_path_polygon -/** - * cogl_path_polygon: - * @coords: (in) (array) (transfer none): A pointer to the first element of - * an array of fixed-point values that specify the vertex coordinates. - * @num_points: The total number of vertices. - * - * Constructs a polygonal shape of the given number of vertices. If - * there is an existing path this will start a new disjoint sub-path. - * - * The coords array must contain 2 * num_points values. The first value - * represents the X coordinate of the first vertex, the second value - * represents the Y coordinate of the first vertex, continuing in the same - * fashion for the rest of the vertices. - * - * Since: 2.0 - */ -void -cogl_path_polygon (CoglPath *path, - const float *coords, - int num_points); - -#define cogl_path_rectangle cogl2_path_rectangle -/** - * cogl_path_rectangle: - * @x_1: X coordinate of the top-left corner. - * @y_1: Y coordinate of the top-left corner. - * @x_2: X coordinate of the bottom-right corner. - * @y_2: Y coordinate of the bottom-right corner. - * - * Constructs a rectangular shape at the given coordinates. If there - * is an existing path this will start a new disjoint sub-path. - * - * Since: 2.0 - */ -void -cogl_path_rectangle (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2); - -#define cogl_path_ellipse cogl2_path_ellipse -/** - * cogl_path_ellipse: - * @center_x: X coordinate of the ellipse center - * @center_y: Y coordinate of the ellipse center - * @radius_x: X radius of the ellipse - * @radius_y: Y radius of the ellipse - * - * Constructs an ellipse shape. If there is an existing path this will - * start a new disjoint sub-path. - * - * Since: 2.0 - */ -void -cogl_path_ellipse (CoglPath *path, - float center_x, - float center_y, - float radius_x, - float radius_y); - -#define cogl_path_round_rectangle cogl2_path_round_rectangle -/** - * cogl_path_round_rectangle: - * @x_1: X coordinate of the top-left corner. - * @y_1: Y coordinate of the top-left corner. - * @x_2: X coordinate of the bottom-right corner. - * @y_2: Y coordinate of the bottom-right corner. - * @radius: Radius of the corner arcs. - * @arc_step: Angle increment resolution for subdivision of - * the corner arcs. - * - * Constructs a rectangular shape with rounded corners. If there is an - * existing path this will start a new disjoint sub-path. - * - * Since: 2.0 - */ -void -cogl_path_round_rectangle (CoglPath *path, - float x_1, - float y_1, - float x_2, - float y_2, - float radius, - float arc_step); - -/** - * CoglPathFillRule: - * @COGL_PATH_FILL_RULE_NON_ZERO: Each time the line crosses an edge of - * the path from left to right one is added to a counter and each time - * it crosses from right to left the counter is decremented. If the - * counter is non-zero then the point will be filled. See . - * @COGL_PATH_FILL_RULE_EVEN_ODD: If the line crosses an edge of the - * path an odd number of times then the point will filled, otherwise - * it won't. See . - * - * #CoglPathFillRule is used to determine how a path is filled. There - * are two options - 'non-zero' and 'even-odd'. To work out whether any - * point will be filled imagine drawing an infinetely long line in any - * direction from that point. The number of times and the direction - * that the edges of the path crosses this line determines whether the - * line is filled as described below. Any open sub paths are treated - * as if there was an extra line joining the first point and the last - * point. - * - * The default fill rule is %COGL_PATH_FILL_RULE_EVEN_ODD. The fill - * rule is attached to the current path so preserving a path with - * cogl_get_path() also preserves the fill rule. Calling - * cogl_path_new() resets the current fill rule to the default. - * - *
- * Example of filling various paths using the non-zero rule - * - *
- * - *
- * Example of filling various paths using the even-odd rule - * - *
- * - * Since: 1.4 - */ -typedef enum { - COGL_PATH_FILL_RULE_NON_ZERO, - COGL_PATH_FILL_RULE_EVEN_ODD -} CoglPathFillRule; - -#define cogl_path_set_fill_rule cogl2_path_set_fill_rule -/** - * cogl_path_set_fill_rule: - * @fill_rule: The new fill rule. - * - * Sets the fill rule of the current path to @fill_rule. This will - * affect how the path is filled when cogl_path_fill() is later - * called. Note that the fill rule state is attached to the path so - * calling cogl_get_path() will preserve the fill rule and calling - * cogl_path_new() will reset the fill rule back to the default. - * - * Since: 2.0 - */ -void -cogl_path_set_fill_rule (CoglPath *path, CoglPathFillRule fill_rule); - -#define cogl_path_get_fill_rule cogl2_path_get_fill_rule -/** - * cogl_path_get_fill_rule: - * - * Retrieves the fill rule set using cogl_path_set_fill_rule(). - * - * Return value: the fill rule that is used for the current path. - * - * Since: 2.0 - */ -CoglPathFillRule -cogl_path_get_fill_rule (CoglPath *path); - -#define cogl_path_fill cogl2_path_fill -/** - * cogl_path_fill: - * - * Fills the interior of the constructed shape using the current - * drawing color. - * - * The interior of the shape is determined using the fill rule of the - * path. See %CoglPathFillRule for details. - * - * The result of referencing sliced textures in your current - * pipeline when filling a path are undefined. You should pass - * the %COGL_TEXTURE_NO_SLICING flag when loading any texture you will - * use while filling a path. - * - * Since: 2.0 - */ -void -cogl_path_fill (CoglPath *path); - -#define cogl_path_stroke cogl2_path_stroke -/** - * cogl_path_stroke: - * - * Strokes the constructed shape using the current drawing color and a - * width of 1 pixel (regardless of the current transformation - * matrix). - * - * Since: 2.0 - */ -void -cogl_path_stroke (CoglPath *path); - -G_END_DECLS - -#endif /* __COGL2_PATH_H__ */ - diff --git a/clutter/cogl/cogl/driver/Makefile.am b/clutter/cogl/cogl/driver/Makefile.am deleted file mode 100644 index e39b278..0000000 --- a/clutter/cogl/cogl/driver/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -include $(top_srcdir)/build/autotools/Makefile.am.silent - -NULL = - -SUBDIRS = $(COGL_DRIVER) - -DIST_SUBDIRS = gl gles diff --git a/clutter/cogl/cogl/driver/gl/cogl-context-driver-gl.h b/clutter/cogl/cogl/driver/gl/cogl-context-driver-gl.h deleted file mode 100644 index 2d8e521..0000000 --- a/clutter/cogl/cogl/driver/gl/cogl-context-driver-gl.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_CONTEXT_DRIVER_H -#define __COGL_CONTEXT_DRIVER_H - -#include "cogl.h" - -#ifndef APIENTRY -#define APIENTRY -#endif - -#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g) - -#define COGL_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * pf_ ## name) args; - -#define COGL_FEATURE_END() - -typedef struct _CoglContextDriver -{ - /* This defines a list of function pointers */ -#include "cogl-feature-functions-gl.h" - - GLint gl_max_program_temoraries_arb; -} CoglContextDriver; - -#undef COGL_FEATURE_BEGIN -#undef COGL_FEATURE_FUNCTION -#undef COGL_FEATURE_END - -#endif /* __COGL_CONTEXT_DRIVER_H */ - diff --git a/clutter/cogl/cogl/driver/gl/cogl-feature-functions-gl.h b/clutter/cogl/cogl/driver/gl/cogl-feature-functions-gl.h deleted file mode 100644 index e26e4e9..0000000 --- a/clutter/cogl/cogl/driver/gl/cogl-feature-functions-gl.h +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/* This is included multiple times with different definitions for - these macros */ - -COGL_FEATURE_BEGIN (offscreen, 255, 255, - /* for some reason the ARB version of this - extension doesn't have an ARB suffix for the - functions */ - "ARB:\0EXT\0", - "framebuffer_object\0", - COGL_FEATURE_OFFSCREEN, - 0) -COGL_FEATURE_FUNCTION (void, glGenRenderbuffers, - (GLsizei n, - GLuint *renderbuffers)) -COGL_FEATURE_FUNCTION (void, glDeleteRenderbuffers, - (GLsizei n, - const GLuint *renderbuffers)) -COGL_FEATURE_FUNCTION (void, glBindRenderbuffer, - (GLenum target, - GLuint renderbuffer)) -COGL_FEATURE_FUNCTION (void, glRenderbufferStorage, - (GLenum target, - GLenum internalformat, - GLsizei width, - GLsizei height)) -COGL_FEATURE_FUNCTION (void, glGenFramebuffers, - (GLsizei n, - GLuint *framebuffers)) -COGL_FEATURE_FUNCTION (void, glBindFramebuffer, - (GLenum target, - GLuint framebuffer)) -COGL_FEATURE_FUNCTION (void, glFramebufferTexture2D, - (GLenum target, - GLenum attachment, - GLenum textarget, - GLuint texture, - GLint level)) -COGL_FEATURE_FUNCTION (void, glFramebufferRenderbuffer, - (GLenum target, - GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer)) -COGL_FEATURE_FUNCTION (GLenum, glCheckFramebufferStatus, - (GLenum target)) -COGL_FEATURE_FUNCTION (void, glDeleteFramebuffers, - (GLsizei n, - const GLuint *framebuffers)) -COGL_FEATURE_FUNCTION (void, glGenerateMipmap, - (GLenum target)) -COGL_FEATURE_FUNCTION (void, glGetFramebufferAttachmentParameteriv, - (GLenum target, - GLenum attachment, - GLenum pname, - GLint *params)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (offscreen_blit, 255, 255, - "EXT\0", - "framebuffer_blit\0", - COGL_FEATURE_OFFSCREEN_BLIT, - 0) -COGL_FEATURE_FUNCTION (void, glBlitFramebuffer, - (GLint srcX0, - GLint srcY0, - GLint srcX1, - GLint srcY1, - GLint dstX0, - GLint dstY0, - GLint dstX1, - GLint dstY1, - GLbitfield mask, - GLenum filter)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (offscreen_multisample, 255, 255, - "EXT\0", - "framebuffer_multisample\0", - COGL_FEATURE_OFFSCREEN_MULTISAMPLE, - 0) -COGL_FEATURE_FUNCTION (void, glRenderbufferStorageMultisample, - (GLenum target, - GLsizei samples, - GLenum internalformat, - GLsizei width, - GLsizei height)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (read_pixels_async, 2, 1, - "EXT\0", - "pixel_buffer_object\0", - COGL_FEATURE_PBOS, - 0) -COGL_FEATURE_END () - -/* ARB_fragment_program */ -COGL_FEATURE_BEGIN (arbfp, 255, 255, - "ARB\0", - "fragment_program\0", - COGL_FEATURE_SHADERS_ARBFP, - 0) -COGL_FEATURE_FUNCTION (void, glGenPrograms, - (GLsizei n, - GLuint *programs)) -COGL_FEATURE_FUNCTION (void, glDeletePrograms, - (GLsizei n, - GLuint *programs)) -COGL_FEATURE_FUNCTION (void, glBindProgram, - (GLenum target, - GLuint program)) -COGL_FEATURE_FUNCTION (void, glProgramString, - (GLenum target, - GLenum format, - GLsizei len, - const void *program)) -COGL_FEATURE_FUNCTION (void, glProgramLocalParameter4fv, - (GLenum target, - GLuint index, - GLfloat *params)) -COGL_FEATURE_END () - -/* The function names in OpenGL 2.0 are different so we can't easily - just check for GL 2.0 */ -COGL_FEATURE_BEGIN (shaders_glsl, 2, 0, - "\0", - "\0", - COGL_FEATURE_SHADERS_GLSL, - 0) -COGL_FEATURE_FUNCTION (GLuint, glCreateProgram, - (void)) -COGL_FEATURE_FUNCTION (GLuint, glCreateShader, - (GLenum shaderType)) -COGL_FEATURE_FUNCTION (void, glShaderSource, - (GLuint shader, - GLsizei count, - const GLchar **string, - const GLint *length)) -COGL_FEATURE_FUNCTION (void, glCompileShader, - (GLuint shader)) -COGL_FEATURE_FUNCTION (void, glDeleteShader, - (GLuint shader)) -COGL_FEATURE_FUNCTION (void, glAttachShader, - (GLuint program, - GLuint shader)) -COGL_FEATURE_FUNCTION (void, glLinkProgram, - (GLuint program)) -COGL_FEATURE_FUNCTION (void, glUseProgram, - (GLuint program)) -COGL_FEATURE_FUNCTION (GLint, glGetUniformLocation, - (GLuint program, - const GLchar *name)) -COGL_FEATURE_FUNCTION (void, glDeleteProgram, - (GLuint program)) -COGL_FEATURE_FUNCTION (void, glGetShaderInfoLog, - (GLuint shader, - GLsizei maxLength, - GLsizei *length, - GLchar *infoLog)) -COGL_FEATURE_FUNCTION (void, glGetShaderiv, - (GLuint shader, - GLenum pname, - GLint *params)) - -COGL_FEATURE_FUNCTION (void, glVertexAttribPointer, - (GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer)) -COGL_FEATURE_FUNCTION (void, glEnableVertexAttribArray, - (GLuint index)) -COGL_FEATURE_FUNCTION (void, glDisableVertexAttribArray, - (GLuint index)) - -COGL_FEATURE_FUNCTION (void, glUniform1f, - (GLint location, - GLfloat v0)) -COGL_FEATURE_FUNCTION (void, glUniform2f, - (GLint location, - GLfloat v0, - GLfloat v1)) -COGL_FEATURE_FUNCTION (void, glUniform3f, - (GLint location, - GLfloat v0, - GLfloat v1, - GLfloat v2)) -COGL_FEATURE_FUNCTION (void, glUniform4f, - (GLint location, - GLfloat v0, - GLfloat v1, - GLfloat v2, - GLfloat v3)) -COGL_FEATURE_FUNCTION (void, glUniform1fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_FEATURE_FUNCTION (void, glUniform2fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_FEATURE_FUNCTION (void, glUniform3fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_FEATURE_FUNCTION (void, glUniform4fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_FEATURE_FUNCTION (void, glUniform1i, - (GLint location, - GLint v0)) -COGL_FEATURE_FUNCTION (void, glUniform2i, - (GLint location, - GLint v0, - GLint v1)) -COGL_FEATURE_FUNCTION (void, glUniform3i, - (GLint location, - GLint v0, - GLint v1, - GLint v2)) -COGL_FEATURE_FUNCTION (void, glUniform4i, - (GLint location, - GLint v0, - GLint v1, - GLint v2, - GLint v3)) -COGL_FEATURE_FUNCTION (void, glUniform1iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_FEATURE_FUNCTION (void, glUniform2iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_FEATURE_FUNCTION (void, glUniform3iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_FEATURE_FUNCTION (void, glUniform4iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_FEATURE_FUNCTION (void, glUniformMatrix2fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_FEATURE_FUNCTION (void, glUniformMatrix3fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_FEATURE_FUNCTION (void, glUniformMatrix4fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) - -COGL_FEATURE_FUNCTION (void, glGetProgramiv, - (GLuint program, - GLenum pname, - GLint *params)) - -COGL_FEATURE_FUNCTION (void, glGetProgramInfoLog, - (GLuint program, - GLsizei bufSize, - GLsizei *length, - GLchar *infoLog)) - -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (vbos, 1, 5, - "ARB\0", - "vertex_buffer_object\0", - COGL_FEATURE_VBOS | - COGL_FEATURE_MAP_BUFFER_FOR_READ | - COGL_FEATURE_MAP_BUFFER_FOR_WRITE, - 0) -COGL_FEATURE_FUNCTION (void, glGenBuffers, - (GLuint n, - GLuint *buffers)) -COGL_FEATURE_FUNCTION (void, glBindBuffer, - (GLenum target, - GLuint buffer)) -COGL_FEATURE_FUNCTION (void, glBufferData, - (GLenum target, - GLsizeiptr size, - const GLvoid *data, - GLenum usage)) -COGL_FEATURE_FUNCTION (void, glBufferSubData, - (GLenum target, - GLintptr offset, - GLsizeiptr size, - const GLvoid *data)) -COGL_FEATURE_FUNCTION (void *, glMapBuffer, - (GLenum target, - GLenum access)) -COGL_FEATURE_FUNCTION (GLboolean, glUnmapBuffer, - (GLenum target)) -COGL_FEATURE_FUNCTION (void, glDeleteBuffers, - (GLsizei n, - const GLuint *buffers)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (texture_rectangle, 255, 255, - "ARB\0", - "texture_rectangle\0", - COGL_FEATURE_TEXTURE_RECTANGLE, - 0) -COGL_FEATURE_END () - -/* Cogl requires OpenGL 1.2 so we assume these functions are always - available and don't bother setting any feature flags. We still have - to fetch the function pointers though because under Windows you can - not call any function defined after GL 1.1 directly */ -COGL_FEATURE_BEGIN (in_1_2, 1, 2, - "\0", - "\0", - 0, - 0) -COGL_FEATURE_FUNCTION (void, glDrawRangeElements, - (GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices)) -COGL_FEATURE_FUNCTION (void, glBlendEquation, - (GLenum mode)) -COGL_FEATURE_FUNCTION (void, glBlendColor, - (GLclampf red, - GLclampf green, - GLclampf blue, - GLclampf alpha)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (texture_3d, 1, 2, - "\0", - "\0", - COGL_FEATURE_TEXTURE_3D, - 0) -COGL_FEATURE_FUNCTION (void, glTexImage3D, - (GLenum target, GLint level, - GLint internalFormat, - GLsizei width, GLsizei height, - GLsizei depth, GLint border, - GLenum format, GLenum type, - const GLvoid *pixels)) -COGL_FEATURE_FUNCTION (void, glTexSubImage3D, - (GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, - GLenum format, - GLenum type, const GLvoid *pixels)) -COGL_FEATURE_END () - -/* Available in GL 1.3 or the multitexture extension. These are - required */ -COGL_FEATURE_BEGIN (multitexture, 1, 3, - "ARB\0", - "multitexture\0", - 0, - 0) -COGL_FEATURE_FUNCTION (void, glActiveTexture, - (GLenum texture)) -COGL_FEATURE_FUNCTION (void, glClientActiveTexture, - (GLenum texture)) -COGL_FEATURE_END () - -/* Optional, declared in 1.4 */ -COGL_FEATURE_BEGIN (blend_func_separate, 1, 4, - "EXT\0", - "blend_func_separate\0", - 0, - 0) -COGL_FEATURE_FUNCTION (void, glBlendFuncSeparate, - (GLenum srcRGB, - GLenum dstRGB, - GLenum srcAlpha, - GLenum dstAlpha)) -COGL_FEATURE_END () - -/* Optional, declared in 2.0 */ -COGL_FEATURE_BEGIN (blend_equation_separate, 2, 0, - "EXT\0", - "blend_equation_separate\0", - 0, - 0) -COGL_FEATURE_FUNCTION (void, glBlendEquationSeparate, - (GLenum modeRGB, - GLenum modeAlpha)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (point_sprites, 2, 0, - "ARB\0", - "point_sprite\0", - COGL_FEATURE_POINT_SPRITE, - 0) -COGL_FEATURE_END () diff --git a/clutter/cogl/cogl/driver/gl/cogl-gl.c b/clutter/cogl/cogl/driver/gl/cogl-gl.c deleted file mode 100644 index 22392de..0000000 --- a/clutter/cogl/cogl/driver/gl/cogl-gl.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl.h" - -#include "cogl-private.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-feature-private.h" - -static gboolean -_cogl_get_gl_version (int *major_out, int *minor_out) -{ - const char *version_string, *major_end, *minor_end; - int major = 0, minor = 0; - - /* Get the OpenGL version number */ - if ((version_string = (const char *) glGetString (GL_VERSION)) == NULL) - return FALSE; - - /* Extract the major number */ - for (major_end = version_string; *major_end >= '0' - && *major_end <= '9'; major_end++) - major = (major * 10) + *major_end - '0'; - /* If there were no digits or the major number isn't followed by a - dot then it is invalid */ - if (major_end == version_string || *major_end != '.') - return FALSE; - - /* Extract the minor number */ - for (minor_end = major_end + 1; *minor_end >= '0' - && *minor_end <= '9'; minor_end++) - minor = (minor * 10) + *minor_end - '0'; - /* If there were no digits or there is an unexpected character then - it is invalid */ - if (minor_end == major_end + 1 - || (*minor_end && *minor_end != ' ' && *minor_end != '.')) - return FALSE; - - *major_out = major; - *minor_out = minor; - - return TRUE; -} - -gboolean -_cogl_gl_check_version (GError **error) -{ - int major, minor; - const char *gl_extensions; - - if (!_cogl_get_gl_version (&major, &minor)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_UNKNOWN_VERSION, - "The OpenGL version could not be determined"); - return FALSE; - } - - /* GL 1.3 supports all of the required functionality in core */ - if (COGL_CHECK_GL_VERSION (major, minor, 1, 3)) - return TRUE; - - gl_extensions = (const char*) glGetString (GL_EXTENSIONS); - - /* OpenGL 1.2 is only supported if we have the multitexturing - extension */ - if (!_cogl_check_extension ("GL_ARB_multitexture", gl_extensions)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "The OpenGL driver is missing " - "the GL_ARB_multitexture extension"); - return FALSE; - } - - /* OpenGL 1.2 is required */ - if (!COGL_CHECK_GL_VERSION (major, minor, 1, 2)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "The OpenGL version of your driver (%i.%i) " - "is not compatible with Cogl", - major, minor); - return FALSE; - } - - return TRUE; -} - -/* Define a set of arrays containing the functions required from GL - for each feature */ -#define COGL_FEATURE_BEGIN(name, min_gl_major, min_gl_minor, \ - namespaces, extension_names, \ - feature_flags, feature_flags_private) \ - static const CoglFeatureFunction cogl_feature_ ## name ## _funcs[] = { -#define COGL_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglContext, drv.pf_ ## name) }, -#define COGL_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl-feature-functions-gl.h" - -/* Define an array of features */ -#undef COGL_FEATURE_BEGIN -#define COGL_FEATURE_BEGIN(name, min_gl_major, min_gl_minor, \ - namespaces, extension_names, \ - feature_flags, feature_flags_private) \ - { min_gl_major, min_gl_minor, namespaces, \ - extension_names, feature_flags, feature_flags_private, 0, \ - cogl_feature_ ## name ## _funcs }, -#undef COGL_FEATURE_FUNCTION -#define COGL_FEATURE_FUNCTION(ret, name, args) -#undef COGL_FEATURE_END -#define COGL_FEATURE_END() - -static const CoglFeatureData cogl_feature_data[] = - { -#include "cogl-feature-functions-gl.h" - }; - -#undef COGL_FEATURE_BEGIN -#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g) -#undef COGL_FEATURE_FUNCTION -#define COGL_FEATURE_FUNCTION(ret, name, args) \ - context->drv.pf_ ## name = NULL; -#undef COGL_FEATURE_END -#define COGL_FEATURE_END() - -static void -initialize_function_table (CoglContext *context) -{ - #include "cogl-feature-functions-gl.h" -} - -/* Query the GL extensions and lookup the corresponding function - * pointers. Theoretically the list of extensions can change for - * different GL contexts so it is the winsys backend's responsiblity - * to know when to re-query the GL extensions. */ -void -_cogl_gl_update_features (CoglContext *context) -{ - CoglFeatureFlags flags = 0; - const char *gl_extensions; - int max_clip_planes = 0; - int num_stencil_bits = 0; - int gl_major = 0, gl_minor = 0; - int i; - - COGL_NOTE (WINSYS, - "Checking features\n" - " GL_VENDOR: %s\n" - " GL_RENDERER: %s\n" - " GL_VERSION: %s\n" - " GL_EXTENSIONS: %s", - glGetString (GL_VENDOR), - glGetString (GL_RENDERER), - glGetString (GL_VERSION), - glGetString (GL_EXTENSIONS)); - - _cogl_get_gl_version (&gl_major, &gl_minor); - - flags = (COGL_FEATURE_TEXTURE_READ_PIXELS - | COGL_FEATURE_UNSIGNED_INT_INDICES); - - gl_extensions = (const char *)glGetString (GL_EXTENSIONS); - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) || - _cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions)) - { - flags |= COGL_FEATURE_TEXTURE_NPOT - | COGL_FEATURE_TEXTURE_NPOT_BASIC - | COGL_FEATURE_TEXTURE_NPOT_MIPMAP - | COGL_FEATURE_TEXTURE_NPOT_REPEAT; - } - -#ifdef GL_YCBCR_MESA - if (_cogl_check_extension ("GL_MESA_ycbcr_texture", gl_extensions)) - { - flags |= COGL_FEATURE_TEXTURE_YUV; - } -#endif - - GE( glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) ); - /* We need at least three stencil bits to combine clips */ - if (num_stencil_bits > 2) - flags |= COGL_FEATURE_STENCIL_BUFFER; - - GE( glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) ); - if (max_clip_planes >= 4) - flags |= COGL_FEATURE_FOUR_CLIP_PLANES; - - initialize_function_table (context); - - for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++) - if (_cogl_feature_check ("GL", cogl_feature_data + i, - gl_major, gl_minor, - gl_extensions, - context)) - flags |= cogl_feature_data[i].feature_flags; - - /* Cache features */ - context->feature_flags |= flags; -} diff --git a/clutter/cogl/cogl/driver/gl/cogl-texture-driver-gl.c b/clutter/cogl/cogl/driver/gl/cogl-texture-driver-gl.c deleted file mode 100644 index 72fd574..0000000 --- a/clutter/cogl/cogl/driver/gl/cogl-texture-driver-gl.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-primitives.h" -#include "cogl-pipeline-opengl-private.h" - -#include -#include -#include - -#define glGenerateMipmap ctx->drv.pf_glGenerateMipmap -#define glTexImage3D ctx->drv.pf_glTexImage3D - -void -_cogl_texture_driver_gen (GLenum gl_target, - GLsizei n, - GLuint *textures) -{ - unsigned int i; - - GE (glGenTextures (n, textures)); - - for (i = 0; i < n; i++) - { - _cogl_bind_gl_texture_transient (gl_target, - textures[i], - FALSE); - - switch (gl_target) - { - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */ - GE( glTexParameteri (gl_target, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR) ); - break; - - case GL_TEXTURE_RECTANGLE_ARB: - /* Texture rectangles already default to GL_LINEAR so nothing - needs to be done */ - break; - - default: - g_assert_not_reached(); - } - } -} - -/* OpenGL - unlike GLES - can upload a sub region of pixel data from a larger - * source buffer */ -static void -prep_gl_for_pixels_upload_full (int pixels_rowstride, - int image_height, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - GE( glPixelStorei (GL_UNPACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) ); - - GE( glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) ); - GE( glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) ); - - if (cogl_features_available (COGL_FEATURE_TEXTURE_3D)) - GE( glPixelStorei (GL_UNPACK_IMAGE_HEIGHT, image_height) ); - - _cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride); -} - -void -_cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride, - int pixels_bpp) -{ - prep_gl_for_pixels_upload_full (pixels_rowstride, 0, 0, 0, pixels_bpp); -} - -/* OpenGL - unlike GLES - can download pixel data into a sub region of - * a larger destination buffer */ -static void -prep_gl_for_pixels_download_full (int pixels_rowstride, - int image_height, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - GE( glPixelStorei (GL_PACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) ); - - GE( glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) ); - GE( glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) ); - - if (cogl_features_available (COGL_FEATURE_TEXTURE_3D)) - GE( glPixelStorei (GL_PACK_IMAGE_HEIGHT, image_height) ); - - _cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride); -} - -void -_cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride, - int pixels_bpp) -{ - prep_gl_for_pixels_download_full (pixels_rowstride, 0, 0, 0, pixels_bpp); -} - -void -_cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type) -{ - guint8 *data; - int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp)); - - data = _cogl_bitmap_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0); - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (_cogl_bitmap_get_rowstride (source_bmp), - 0, - src_x, - src_y, - bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - GE( glTexSubImage2D (gl_target, 0, - dst_x, dst_y, - width, height, - source_gl_format, - source_gl_type, - data) ); - - _cogl_bitmap_unbind (source_bmp); -} - -void -_cogl_texture_driver_upload_to_gl (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type) -{ - guint8 *data; - int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp)); - - data = _cogl_bitmap_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0); - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (_cogl_bitmap_get_rowstride (source_bmp), - 0, 0, 0, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - GE( glTexImage2D (gl_target, 0, - internal_gl_format, - _cogl_bitmap_get_width (source_bmp), - _cogl_bitmap_get_height (source_bmp), - 0, - source_gl_format, - source_gl_type, - data) ); - - _cogl_bitmap_unbind (source_bmp); -} - -void -_cogl_texture_driver_upload_to_gl_3d (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - GLint height, - GLint depth, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type) -{ - guint8 *data; - int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp)); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - data = _cogl_bitmap_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0); - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (_cogl_bitmap_get_rowstride (source_bmp), - (_cogl_bitmap_get_height (source_bmp) / - depth), - 0, 0, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - GE( glTexImage3D (gl_target, - 0, /* level */ - internal_gl_format, - _cogl_bitmap_get_width (source_bmp), - height, - depth, - 0, - source_gl_format, - source_gl_type, - data) ); - - _cogl_bitmap_unbind (source_bmp); -} - -gboolean -_cogl_texture_driver_gl_get_tex_image (GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - guint8 *dest) -{ - GE (glGetTexImage (gl_target, - 0, /* level */ - dest_gl_format, - dest_gl_type, - (GLvoid *)dest)); - return TRUE; -} - -gboolean -_cogl_texture_driver_size_supported_3d (GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height, - int depth) -{ - GLenum proxy_target; - GLint new_width = 0; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (gl_target == GL_TEXTURE_3D) - proxy_target = GL_PROXY_TEXTURE_3D; - else - /* Unknown target, assume it's not supported */ - return FALSE; - - /* Proxy texture allows for a quick check for supported size */ - GE( glTexImage3D (proxy_target, 0, GL_RGBA, - width, height, depth, 0 /* border */, - gl_format, gl_type, NULL) ); - - GE( glGetTexLevelParameteriv (proxy_target, 0, - GL_TEXTURE_WIDTH, &new_width) ); - - return new_width != 0; -} - -gboolean -_cogl_texture_driver_size_supported (GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height) -{ - GLenum proxy_target; - GLint new_width = 0; - - if (gl_target == GL_TEXTURE_2D) - proxy_target = GL_PROXY_TEXTURE_2D; -#if HAVE_COGL_GL - else if (gl_target == GL_TEXTURE_RECTANGLE_ARB) - proxy_target = GL_PROXY_TEXTURE_RECTANGLE_ARB; -#endif - else - /* Unknown target, assume it's not supported */ - return FALSE; - - /* Proxy texture allows for a quick check for supported size */ - GE( glTexImage2D (proxy_target, 0, GL_RGBA, - width, height, 0 /* border */, - gl_format, gl_type, NULL) ); - - GE( glGetTexLevelParameteriv (proxy_target, 0, - GL_TEXTURE_WIDTH, &new_width) ); - - return new_width != 0; -} - -void -_cogl_texture_driver_try_setting_gl_border_color ( - GLuint gl_target, - const GLfloat *transparent_color) -{ - /* Use a transparent border color so that we can leave the - color buffer alone when using texture co-ordinates - outside of the texture */ - GE( glTexParameterfv (gl_target, GL_TEXTURE_BORDER_COLOR, - transparent_color) ); -} - -gboolean -_cogl_pixel_format_from_gl_internal (GLenum gl_int_format, - CoglPixelFormat *out_format) -{ - /* It doesn't really matter we convert to exact same - format (some have no cogl match anyway) since format - is re-matched against cogl when getting or setting - texture image data. - */ - - switch (gl_int_format) - { - case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8: - case GL_ALPHA12: case GL_ALPHA16: - - *out_format = COGL_PIXEL_FORMAT_A_8; - return TRUE; - - case GL_LUMINANCE: case GL_LUMINANCE4: case GL_LUMINANCE8: - case GL_LUMINANCE12: case GL_LUMINANCE16: - - *out_format = COGL_PIXEL_FORMAT_G_8; - return TRUE; - - case GL_RGB: case GL_RGB4: case GL_RGB5: case GL_RGB8: - case GL_RGB10: case GL_RGB12: case GL_RGB16: case GL_R3_G3_B2: - - *out_format = COGL_PIXEL_FORMAT_RGB_888; - return TRUE; - - case GL_RGBA: case GL_RGBA2: case GL_RGBA4: case GL_RGB5_A1: - case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: - - *out_format = COGL_PIXEL_FORMAT_RGBA_8888; - return TRUE; - } - - return FALSE; -} - -CoglPixelFormat -_cogl_pixel_format_to_gl (CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - CoglPixelFormat required_format; - GLenum glintformat = 0; - GLenum glformat = 0; - GLenum gltype = 0; - - /* FIXME: check YUV support */ - - required_format = format; - - /* Find GL equivalents */ - switch (format & COGL_UNPREMULT_MASK) - { - case COGL_PIXEL_FORMAT_A_8: - glintformat = GL_ALPHA; - glformat = GL_ALPHA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_G_8: - glintformat = GL_LUMINANCE; - glformat = GL_LUMINANCE; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_RGB_888: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_BGR_888: - glintformat = GL_RGB; - glformat = GL_BGR; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_RGBA_8888: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_BGRA_8888: - glintformat = GL_RGBA; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_BYTE; - break; - - /* The following two types of channel ordering - * have no GL equivalent unless defined using - * system word byte ordering */ - case COGL_PIXEL_FORMAT_ARGB_8888: - glintformat = GL_RGBA; - glformat = GL_BGRA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - - case COGL_PIXEL_FORMAT_ABGR_8888: - glintformat = GL_RGBA; - glformat = GL_RGBA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - - /* The following three types of channel ordering - * are always defined using system word byte - * ordering (even according to GLES spec) */ - case COGL_PIXEL_FORMAT_RGB_565: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_SHORT_5_6_5; - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_5_5_5_1; - break; - - /* FIXME: check extensions for YUV support */ - default: - break; - } - - if (out_glintformat != NULL) - *out_glintformat = glintformat; - if (out_glformat != NULL) - *out_glformat = glformat; - if (out_gltype != NULL) - *out_gltype = gltype; - - return required_format; -} - -gboolean -_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target) -{ - /* GL_ARB_texture_rectangle textures are supported if they are - created from foreign because some chipsets have trouble with - GL_ARB_texture_non_power_of_two. There is no Cogl call to create - them directly to emphasize the fact that they don't work fully - (for example, no mipmapping and complicated shader support) */ - - /* Allow 2-dimensional or rectangle textures only */ - if (gl_target != GL_TEXTURE_2D && gl_target != GL_TEXTURE_RECTANGLE_ARB) - return FALSE; - - return TRUE; -} - -void -_cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - GE( glGenerateMipmap (gl_target) ); -} - -CoglPixelFormat -_cogl_texture_driver_find_best_gl_get_data_format ( - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type) -{ - /* Find closest format that's supported by GL */ - return _cogl_pixel_format_to_gl (format, - NULL, /* don't need */ - closest_gl_format, - closest_gl_type); -} - diff --git a/clutter/cogl/cogl/driver/gles/cogl-context-driver-gles.h b/clutter/cogl/cogl/driver/gles/cogl-context-driver-gles.h deleted file mode 100644 index ca3b1d4..0000000 --- a/clutter/cogl/cogl/driver/gles/cogl-context-driver-gles.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_CONTEXT_DRIVER_H -#define __COGL_CONTEXT_DRIVER_H - -#include "cogl.h" - -#ifndef APIENTRY -#define APIENTRY -#endif - -#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g) - -#define COGL_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * pf_ ## name) args; - -#define COGL_FEATURE_END() - -typedef struct _CoglContextDriver -{ - /* This defines a list of function pointers */ -#include "cogl-feature-functions-gles.h" - -} CoglContextDriver; - -#undef COGL_FEATURE_BEGIN -#undef COGL_FEATURE_FUNCTION -#undef COGL_FEATURE_END - -#endif /* __COGL_CONTEXT_DRIVER_H */ - diff --git a/clutter/cogl/cogl/driver/gles/cogl-feature-functions-gles.h b/clutter/cogl/cogl/driver/gles/cogl-feature-functions-gles.h deleted file mode 100644 index b70b13b..0000000 --- a/clutter/cogl/cogl/driver/gles/cogl-feature-functions-gles.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/* This is included multiple times with different definitions for - these macros */ - -COGL_FEATURE_BEGIN (offscreen, 255, 255, - "OES\0", - "framebuffer_object\0", - COGL_FEATURE_OFFSCREEN, - 0) -COGL_FEATURE_FUNCTION (void, glGenRenderbuffers, - (GLsizei n, - GLuint *renderbuffers)) -COGL_FEATURE_FUNCTION (void, glDeleteRenderbuffers, - (GLsizei n, - const GLuint *renderbuffers)) -COGL_FEATURE_FUNCTION (void, glBindRenderbuffer, - (GLenum target, - GLuint renderbuffer)) -COGL_FEATURE_FUNCTION (void, glRenderbufferStorage, - (GLenum target, - GLenum internalformat, - GLsizei width, - GLsizei height)) -COGL_FEATURE_FUNCTION (void, glGenFramebuffers, - (GLsizei n, - GLuint *framebuffers)) -COGL_FEATURE_FUNCTION (void, glBindFramebuffer, - (GLenum target, - GLuint framebuffer)) -COGL_FEATURE_FUNCTION (void, glFramebufferTexture2D, - (GLenum target, - GLenum attachment, - GLenum textarget, - GLuint texture, - GLint level)) -COGL_FEATURE_FUNCTION (void, glFramebufferRenderbuffer, - (GLenum target, - GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer)) -COGL_FEATURE_FUNCTION (GLenum, glCheckFramebufferStatus, - (GLenum target)) -COGL_FEATURE_FUNCTION (void, glDeleteFramebuffers, - (GLsizei n, - const GLuint *framebuffers)) -COGL_FEATURE_FUNCTION (void, glGenerateMipmap, - (GLenum target)) -COGL_FEATURE_FUNCTION (void, glGetFramebufferAttachmentParameteriv, - (GLenum target, - GLenum attachment, - GLenum pname, - GLint *params)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (offscreen_blit, 255, 255, - "ANGLE\0", - "framebuffer_blit\0", - COGL_FEATURE_OFFSCREEN_BLIT, - 0) -COGL_FEATURE_FUNCTION (void, glBlitFramebuffer, - (GLint srcX0, - GLint srcY0, - GLint srcX1, - GLint srcY1, - GLint dstX0, - GLint dstY0, - GLint dstX1, - GLint dstY1, - GLbitfield mask, - GLenum filter)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (element_index_uint, 255, 255, - "OES\0", - "element_index_uint\0", - COGL_FEATURE_UNSIGNED_INT_INDICES, - 0) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (texture_npot, 255, 255, - "OES\0IMG\0", - "texture_npot\0", - COGL_FEATURE_TEXTURE_NPOT | - COGL_FEATURE_TEXTURE_NPOT_BASIC | - COGL_FEATURE_TEXTURE_NPOT_MIPMAP | - COGL_FEATURE_TEXTURE_NPOT_REPEAT, - 0) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (texture_3d, 1, 2, - "OES\0", - "texture_3D\0", - COGL_FEATURE_TEXTURE_3D, - 0) -COGL_FEATURE_FUNCTION (void, glTexImage3D, - (GLenum target, GLint level, - GLint internalFormat, - GLsizei width, GLsizei height, - GLsizei depth, GLint border, - GLenum format, GLenum type, - const GLvoid *pixels)) -COGL_FEATURE_FUNCTION (void, glTexSubImage3D, - (GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid* pixels)) -COGL_FEATURE_END () - -COGL_FEATURE_BEGIN (map_buffer, 255, 255, - "OES\0", - "mapbuffer\0", - COGL_FEATURE_MAP_BUFFER_FOR_WRITE, - 0) -COGL_FEATURE_FUNCTION (void *, glMapBuffer, - (GLenum target, - GLenum access)) -COGL_FEATURE_FUNCTION (GLboolean, glUnmapBuffer, - (GLenum target)) -COGL_FEATURE_END () diff --git a/clutter/cogl/cogl/driver/gles/cogl-gles.c b/clutter/cogl/cogl/driver/gles/cogl-gles.c deleted file mode 100644 index f137925..0000000 --- a/clutter/cogl/cogl/driver/gles/cogl-gles.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-context-private.h" -#include "cogl-feature-private.h" - -gboolean -_cogl_gl_check_version (GError **error) -{ - /* The GLES backend doesn't have any particular version requirements */ - return TRUE; -} - -/* Define a set of arrays containing the functions required from GL - for each feature */ -#define COGL_FEATURE_BEGIN(name, min_gl_major, min_gl_minor, \ - namespaces, extension_names, \ - feature_flags, feature_flags_private) \ - static const CoglFeatureFunction cogl_feature_ ## name ## _funcs[] = { -#define COGL_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglContext, drv.pf_ ## name) }, -#define COGL_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl-feature-functions-gles.h" - -/* Define an array of features */ -#undef COGL_FEATURE_BEGIN -#define COGL_FEATURE_BEGIN(name, min_gl_major, min_gl_minor, \ - namespaces, extension_names, \ - feature_flags, feature_flags_private) \ - { min_gl_major, min_gl_minor, namespaces, \ - extension_names, feature_flags, feature_flags_private, 0, \ - cogl_feature_ ## name ## _funcs }, -#undef COGL_FEATURE_FUNCTION -#define COGL_FEATURE_FUNCTION(ret, name, args) -#undef COGL_FEATURE_END -#define COGL_FEATURE_END() - -static const CoglFeatureData cogl_feature_data[] = - { -#include "cogl-feature-functions-gles.h" - }; - -#undef COGL_FEATURE_BEGIN -#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g) -#undef COGL_FEATURE_FUNCTION -#define COGL_FEATURE_FUNCTION(ret, name, args) \ - context->drv.pf_ ## name = NULL; -#undef COGL_FEATURE_END -#define COGL_FEATURE_END() - -static void -initialize_function_table (CoglContext *context) -{ - #include "cogl-feature-functions-gles.h" -} - -/* Query the GL extensions and lookup the corresponding function - * pointers. Theoretically the list of extensions can change for - * different GL contexts so it is the winsys backend's responsiblity - * to know when to re-query the GL extensions. */ -void -_cogl_gl_update_features (CoglContext *context) -{ - CoglFeatureFlags flags = 0; - const char *gl_extensions; -#ifndef HAVE_COGL_GLES2 - int max_clip_planes = 0; -#endif - int num_stencil_bits = 0; - int i; - - COGL_NOTE (WINSYS, - "Checking features\n" - " GL_VENDOR: %s\n" - " GL_RENDERER: %s\n" - " GL_VERSION: %s\n" - " GL_EXTENSIONS: %s", - glGetString (GL_VENDOR), - glGetString (GL_RENDERER), - glGetString (GL_VERSION), - glGetString (GL_EXTENSIONS)); - - gl_extensions = (const char*) glGetString (GL_EXTENSIONS); - - - GE( glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) ); - /* We need at least three stencil bits to combine clips */ - if (num_stencil_bits > 2) - flags |= COGL_FEATURE_STENCIL_BUFFER; - -#ifndef HAVE_COGL_GLES2 - GE( glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) ); - if (max_clip_planes >= 4) - flags |= COGL_FEATURE_FOUR_CLIP_PLANES; -#endif - -#ifdef HAVE_COGL_GLES2 - flags |= COGL_FEATURE_SHADERS_GLSL | COGL_FEATURE_OFFSCREEN; - /* Note GLES 2 core doesn't support mipmaps for npot textures or - * repeat modes other than CLAMP_TO_EDGE. */ - flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC; -#endif - - flags |= COGL_FEATURE_VBOS; - - /* Both GLES 1.1 and GLES 2.0 support point sprites in core */ - flags |= COGL_FEATURE_POINT_SPRITE; - - initialize_function_table (context); - - for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++) - if (_cogl_feature_check ("GL", cogl_feature_data + i, - 0, 0, - gl_extensions, - context)) - flags |= cogl_feature_data[i].feature_flags; - - /* Cache features */ - context->feature_flags |= flags; -} diff --git a/clutter/cogl/cogl/driver/gles/cogl-texture-driver-gles.c b/clutter/cogl/cogl/driver/gles/cogl-texture-driver-gles.c deleted file mode 100644 index bf67d83..0000000 --- a/clutter/cogl/cogl/driver/gles/cogl-texture-driver-gles.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Matthew Allum - * Neil Roberts - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-context-private.h" -#include "cogl-handle.h" -#include "cogl-primitives.h" - -#include -#include -#include - -#define glTexImage3D ctx->drv.pf_glTexImage3D -#define glTexSubImage3D ctx->drv.pf_glTexSubImage3D - -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif -#ifndef GL_MAX_3D_TEXTURE_SIZE_OES -#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 -#endif - -void -_cogl_texture_driver_gen (GLenum gl_target, - GLsizei n, - GLuint *textures) -{ - unsigned int i; - - GE (glGenTextures (n, textures)); - - for (i = 0; i < n; i++) - { - _cogl_bind_gl_texture_transient (gl_target, textures[i], FALSE); - - switch (gl_target) - { - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */ - GE( glTexParameteri (gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ); - break; - - default: - g_assert_not_reached(); - } - } -} - -void -_cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride, - int pixels_bpp) -{ - _cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride); -} - -void -_cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride, - int pixels_bpp) -{ - _cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride); -} - -static CoglBitmap * -prepare_bitmap_alignment_for_upload (CoglBitmap *src_bmp) -{ - CoglPixelFormat format = _cogl_bitmap_get_format (src_bmp); - int bpp = _cogl_get_format_bpp (format); - int src_rowstride = _cogl_bitmap_get_rowstride (src_bmp); - int width = _cogl_bitmap_get_width (src_bmp); - int alignment = 1; - - if (src_rowstride == 0) - return cogl_object_ref (src_bmp); - - /* Work out the alignment of the source rowstride */ - alignment = 1 << (_cogl_util_ffs (src_rowstride) - 1); - alignment = MIN (alignment, 8); - - /* If the aligned data equals the rowstride then we can upload from - the bitmap directly using GL_UNPACK_ALIGNMENT */ - if (((width * bpp + alignment - 1) & ~(alignment - 1)) == src_rowstride) - return cogl_object_ref (src_bmp); - /* Otherwise we need to copy the bitmap to pack the alignment - because GLES has no GL_ROW_LENGTH */ - else - return _cogl_bitmap_copy (src_bmp); -} - -void -_cogl_texture_driver_upload_subregion_to_gl (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type) -{ - guint8 *data; - CoglPixelFormat source_format = _cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_get_format_bpp (source_format); - CoglBitmap *slice_bmp; - int rowstride; - - /* If we are copying a sub region of the source bitmap then we need - to copy it because GLES does not support GL_UNPACK_ROW_LENGTH */ - if (src_x != 0 || src_y != 0 || - width != _cogl_bitmap_get_width (source_bmp) || - height != _cogl_bitmap_get_height (source_bmp)) - { - rowstride = bpp * width; - rowstride = (rowstride + 3) & ~3; - slice_bmp = - _cogl_bitmap_new_from_data (g_malloc (height * rowstride), - source_format, - width, height, - rowstride, - (CoglBitmapDestroyNotify) g_free, - NULL); - _cogl_bitmap_copy_subregion (source_bmp, - slice_bmp, - src_x, src_y, - 0, 0, /* dst_x/y */ - width, height); - } - else - { - slice_bmp = prepare_bitmap_alignment_for_upload (source_bmp); - rowstride = _cogl_bitmap_get_rowstride (slice_bmp); - } - - /* Setup gl alignment to match rowstride and top-left corner */ - _cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp); - - data = _cogl_bitmap_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - GE( glTexSubImage2D (gl_target, 0, - dst_x, dst_y, - width, height, - source_gl_format, - source_gl_type, - data) ); - - _cogl_bitmap_unbind (slice_bmp); - - cogl_object_unref (slice_bmp); -} - -void -_cogl_texture_driver_upload_to_gl (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type) -{ - int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp)); - int rowstride; - int bmp_width = _cogl_bitmap_get_width (source_bmp); - int bmp_height = _cogl_bitmap_get_height (source_bmp); - CoglBitmap *bmp; - guint8 *data; - - bmp = prepare_bitmap_alignment_for_upload (source_bmp); - rowstride = _cogl_bitmap_get_rowstride (bmp); - - /* Setup gl alignment to match rowstride and top-left corner */ - _cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - data = _cogl_bitmap_bind (bmp, COGL_BUFFER_ACCESS_READ, 0); - - GE( glTexImage2D (gl_target, 0, - internal_gl_format, - bmp_width, bmp_height, - 0, - source_gl_format, - source_gl_type, - data) ); - - _cogl_bitmap_unbind (bmp); - - cogl_object_unref (bmp); -} - -void -_cogl_texture_driver_upload_to_gl_3d (GLenum gl_target, - GLuint gl_handle, - gboolean is_foreign, - GLint height, - GLint depth, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type) -{ - int bpp = _cogl_get_format_bpp (_cogl_bitmap_get_format (source_bmp)); - int rowstride = _cogl_bitmap_get_rowstride (source_bmp); - int bmp_width = _cogl_bitmap_get_width (source_bmp); - int bmp_height = _cogl_bitmap_get_height (source_bmp); - guint8 *data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - /* If the rowstride or image height can't be specified with just - GL_ALIGNMENT alone then we need to copy the bitmap because there - is no GL_ROW_LENGTH */ - if (rowstride / bpp != bmp_width || - height != bmp_height / depth) - { - CoglBitmap *bmp; - int image_height = bmp_height / depth; - int i; - - _cogl_texture_driver_prep_gl_for_pixels_upload (bmp_width * bpp, bpp); - - /* Initialize the texture with empty data and then upload each - image with a sub-region update */ - - GE( glTexImage3D (gl_target, - 0, /* level */ - internal_gl_format, - bmp_width, - height, - depth, - 0, - source_gl_format, - source_gl_type, - NULL) ); - - bmp = _cogl_bitmap_new_from_data (g_malloc (bpp * bmp_width * height), - _cogl_bitmap_get_format (source_bmp), - bmp_width, - height, - bpp * bmp_width, - (CoglBitmapDestroyNotify) g_free, - NULL); - - for (i = 0; i < depth; i++) - { - _cogl_bitmap_copy_subregion (source_bmp, - bmp, - 0, image_height * i, - 0, 0, - bmp_width, - height); - - data = _cogl_bitmap_bind (bmp, - COGL_BUFFER_ACCESS_READ, 0); - - GE( glTexSubImage3D (gl_target, - 0, /* level */ - 0, /* xoffset */ - 0, /* yoffset */ - i, /* zoffset */ - bmp_width, /* width */ - height, /* height */ - 1, /* depth */ - source_gl_format, - source_gl_type, - data) ); - - _cogl_bitmap_unbind (bmp); - } - - cogl_object_unref (bmp); - } - else - { - data = _cogl_bitmap_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0); - - _cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp); - - GE( glTexImage3D (gl_target, - 0, /* level */ - internal_gl_format, - bmp_width, - height, - depth, - 0, - source_gl_format, - source_gl_type, - data) ); - - _cogl_bitmap_unbind (source_bmp); - } -} - -/* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead - * fallback to a generic render + readpixels approach to downloading - * texture data. (See _cogl_texture_draw_and_read() ) */ -gboolean -_cogl_texture_driver_gl_get_tex_image (GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - guint8 *dest) -{ - return FALSE; -} - -gboolean -_cogl_texture_driver_size_supported_3d (GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height, - int depth) -{ - GLint max_size; - - /* GLES doesn't support a proxy texture target so let's at least - check whether the size is greater than - GL_MAX_3D_TEXTURE_SIZE_OES */ - GE( glGetIntegerv (GL_MAX_3D_TEXTURE_SIZE_OES, &max_size) ); - - return width <= max_size && height <= max_size && depth <= max_size; -} - -gboolean -_cogl_texture_driver_size_supported (GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height) -{ - GLint max_size; - - /* GLES doesn't support a proxy texture target so let's at least - check whether the size is greater than GL_MAX_TEXTURE_SIZE */ - GE( glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_size) ); - - return width <= max_size && height <= max_size; -} - -void -_cogl_texture_driver_try_setting_gl_border_color ( - GLuint gl_target, - const GLfloat *transparent_color) -{ - /* FAIL! */ -} - -gboolean -_cogl_pixel_format_from_gl_internal (GLenum gl_int_format, - CoglPixelFormat *out_format) -{ - return TRUE; -} - -CoglPixelFormat -_cogl_pixel_format_to_gl (CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - CoglPixelFormat required_format; - GLenum glintformat = 0; - GLenum glformat = 0; - GLenum gltype = 0; - - /* FIXME: check YUV support */ - - required_format = format; - - /* Find GL equivalents */ - switch (format & COGL_UNPREMULT_MASK) - { - case COGL_PIXEL_FORMAT_A_8: - glintformat = GL_ALPHA; - glformat = GL_ALPHA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_G_8: - glintformat = GL_LUMINANCE; - glformat = GL_LUMINANCE; - gltype = GL_UNSIGNED_BYTE; - break; - - /* Just one 24-bit ordering supported */ - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_BYTE; - required_format = COGL_PIXEL_FORMAT_RGB_888; - break; - - /* Just one 32-bit ordering supported */ - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ABGR_8888: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_BYTE; - required_format = COGL_PIXEL_FORMAT_RGBA_8888; - required_format |= (format & COGL_PREMULT_BIT); - break; - - /* The following three types of channel ordering - * are always defined using system word byte - * ordering (even according to GLES spec) */ - case COGL_PIXEL_FORMAT_RGB_565: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_SHORT_5_6_5; - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_5_5_5_1; - break; - - /* FIXME: check extensions for YUV support */ - default: - break; - } - - if (out_glintformat != NULL) - *out_glintformat = glintformat; - if (out_glformat != NULL) - *out_glformat = glformat; - if (out_gltype != NULL) - *out_gltype = gltype; - - return required_format; -} - -gboolean -_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target) -{ - /* Allow 2-dimensional textures only */ - if (gl_target != GL_TEXTURE_2D) - return FALSE; - return TRUE; -} - -void -_cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target) -{ -#ifdef HAVE_COGL_GLES2 - GE( glGenerateMipmap (gl_target) ); -#endif -} - -CoglPixelFormat -_cogl_texture_driver_find_best_gl_get_data_format ( - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type) -{ - /* Find closest format that's supported by GL - (Can't use _cogl_pixel_format_to_gl since available formats - when reading pixels on GLES are severely limited) */ - *closest_gl_format = GL_RGBA; - *closest_gl_type = GL_UNSIGNED_BYTE; - return COGL_PIXEL_FORMAT_RGBA_8888; -} - diff --git a/clutter/cogl/cogl/stb_image.c b/clutter/cogl/cogl/stb_image.c deleted file mode 100644 index 75562f6..0000000 --- a/clutter/cogl/cogl/stb_image.c +++ /dev/null @@ -1,3891 +0,0 @@ -/* stbi-1.18 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c - when you control the images you're loading - - QUICK NOTES: - Primarily of interest to game developers and other people who can - avoid problematic images and only need the trivial interface - - JPEG baseline (no JPEG progressive, no oddball channel decimations) - PNG 8-bit only - BMP non-1bpp, non-RLE - TGA (not sure what subset, if a subset) - PSD (composited view only, no extra channels) - HDR (radiance rgbE format) - writes BMP,TGA (define STBI_NO_WRITE to remove code) - decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code) - supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD) - - TODO: - stbi_info_* - - history: - 1.18 fix a threading bug (local mutable static) - 1.17 support interlaced PNG - 1.16 major bugfix - convert_format converted one too many pixels - 1.15 initialize some fields for thread safety - 1.14 fix threadsafe conversion bug; header-file-only version (#define STBI_HEADER_FILE_ONLY before including) - 1.13 threadsafe - 1.12 const qualifiers in the API - 1.11 Support installable IDCT, colorspace conversion routines - 1.10 Fixes for 64-bit (don't use "unsigned long") - optimized upsampling by Fabian "ryg" Giesen - 1.09 Fix format-conversion for PSD code (bad global variables!) - 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz - 1.07 attempt to fix C++ warning/errors again - 1.06 attempt to fix C++ warning/errors again - 1.05 fix TGA loading to return correct *comp and use good luminance calc - 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free - 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR - 1.02 support for (subset of) HDR files, float interface for preferred access to them - 1.01 fix bug: possible bug in handling right-side up bmps... not sure - fix bug: the stbi_bmp_load() and stbi_tga_load() functions didn't work at all - 1.00 interface to zlib that skips zlib header - 0.99 correct handling of alpha in palette - 0.98 TGA loader by lonesock; dynamically add loaders (untested) - 0.97 jpeg errors on too large a file; also catch another malloc failure - 0.96 fix detection of invalid v value - particleman@mollyrocket forum - 0.95 during header scan, seek to markers in case of padding - 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same - 0.93 handle jpegtran output; verbose errors - 0.92 read 4,8,16,24,32-bit BMP files of several formats - 0.91 output 24-bit Windows 3.0 BMP files - 0.90 fix a few more warnings; bump version number to approach 1.0 - 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd - 0.60 fix compiling as c++ - 0.59 fix warnings: merge Dave Moore's -Wall fixes - 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian - 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less - than 16 available - 0.56 fix bug: zlib uncompressed mode len vs. nlen - 0.55 fix bug: restart_interval not initialized to 0 - 0.54 allow NULL for 'int *comp' - 0.53 fix bug in png 3->4; speedup png decoding - 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments - 0.51 obey req_comp requests, 1-component jpegs return as 1-component, - on 'test' only check type, not whether we support this variant -*/ - - -#ifndef STBI_INCLUDE_STB_IMAGE_H -#define STBI_INCLUDE_STB_IMAGE_H - -//// begin header file //////////////////////////////////////////////////// -// -// Limitations: -// - no progressive/interlaced support (jpeg, png) -// - 8-bit samples only (jpeg, png) -// - not threadsafe -// - channel subsampling of at most 2 in each dimension (jpeg) -// - no delayed line count (jpeg) -- IJG doesn't support either -// -// Basic usage (see HDR discussion below): -// int x,y,n; -// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); -// // ... process data if not NULL ... -// // ... x = width, y = height, n = # 8-bit components per pixel ... -// // ... replace '0' with '1'..'4' to force that many components per pixel -// stbi_image_free(data) -// -// Standard parameters: -// int *x -- outputs image width in pixels -// int *y -- outputs image height in pixels -// int *comp -- outputs # of image components in image file -// int req_comp -- if non-zero, # of image components requested in result -// -// The return value from an image loader is an 'unsigned char *' which points -// to the pixel data. The pixel data consists of *y scanlines of *x pixels, -// with each pixel consisting of N interleaved 8-bit components; the first -// pixel pointed to is top-left-most in the image. There is no padding between -// image scanlines or between pixels, regardless of format. The number of -// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise. -// If req_comp is non-zero, *comp has the number of components that _would_ -// have been output otherwise. E.g. if you set req_comp to 4, you will always -// get RGBA output, but you can check *comp to easily see if it's opaque. -// -// An output image with N components has the following components interleaved -// in this order in each pixel: -// -// N=#comp components -// 1 grey -// 2 grey, alpha -// 3 red, green, blue -// 4 red, green, blue, alpha -// -// If image loading fails for any reason, the return value will be NULL, -// and *x, *y, *comp will be unchanged. The function stbi_failure_reason() -// can be queried for an extremely brief, end-user unfriendly explanation -// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid -// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly -// more user-friendly ones. -// -// Paletted PNG and BMP images are automatically depalettized. -// -// -// =========================================================================== -// -// HDR image support (disable by defining STBI_NO_HDR) -// -// stb_image now supports loading HDR images in general, and currently -// the Radiance .HDR file format, although the support is provided -// generically. You can still load any file through the existing interface; -// if you attempt to load an HDR file, it will be automatically remapped to -// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; -// both of these constants can be reconfigured through this interface: -// -// stbi_hdr_to_ldr_gamma(2.2f); -// stbi_hdr_to_ldr_scale(1.0f); -// -// (note, do not use _inverse_ constants; stbi_image will invert them -// appropriately). -// -// Additionally, there is a new, parallel interface for loading files as -// (linear) floats to preserve the full dynamic range: -// -// float *data = stbi_loadf(filename, &x, &y, &n, 0); -// -// If you load LDR images through this interface, those images will -// be promoted to floating point values, run through the inverse of -// constants corresponding to the above: -// -// stbi_ldr_to_hdr_scale(1.0f); -// stbi_ldr_to_hdr_gamma(2.2f); -// -// Finally, given a filename (or an open file or memory block--see header -// file for details) containing image data, you can query for the "most -// appropriate" interface to use (that is, whether the image is HDR or -// not), using: -// -// stbi_is_hdr(char *filename); - -#ifndef STBI_NO_STDIO -#include -#endif - -#define STBI_VERSION 1 - -enum -{ - STBI_default = 0, // only used for req_comp - - STBI_grey = 1, - STBI_grey_alpha = 2, - STBI_rgb = 3, - STBI_rgb_alpha = 4, -}; - -typedef unsigned char stbi_uc; - -#ifdef __cplusplus -extern "C" { -#endif - -// WRITING API - -#if !defined(STBI_NO_WRITE) && !defined(STBI_NO_STDIO) -// write a BMP/TGA file given tightly packed 'comp' channels (no padding, nor bmp-stride-padding) -// (you must include the appropriate extension in the filename). -// returns TRUE on success, FALSE if couldn't open file, error writing file -extern int stbi_write_bmp (char const *filename, int x, int y, int comp, void *data); -extern int stbi_write_tga (char const *filename, int x, int y, int comp, void *data); -#endif - -// PRIMARY API - works on images of any type - -// load image by filename, open file, or memory buffer -#ifndef STBI_NO_STDIO -extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); -#endif -extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); -// for stbi_load_from_file, file pointer is left pointing immediately after image - -#ifndef STBI_NO_HDR -#ifndef STBI_NO_STDIO -extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); -extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -#endif -extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); - -extern void stbi_hdr_to_ldr_gamma(float gamma); -extern void stbi_hdr_to_ldr_scale(float scale); - -extern void stbi_ldr_to_hdr_gamma(float gamma); -extern void stbi_ldr_to_hdr_scale(float scale); - -#endif // STBI_NO_HDR - -// get a VERY brief reason for failure -// NOT THREADSAFE -extern char *stbi_failure_reason (void); - -// free the loaded image -- this is just free() -extern void stbi_image_free (void *retval_from_stbi_load); - -// get image dimensions & components without fully decoding -extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); -extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); -#ifndef STBI_NO_STDIO -extern int stbi_info (char const *filename, int *x, int *y, int *comp); -extern int stbi_is_hdr (char const *filename); -extern int stbi_is_hdr_from_file(FILE *f); -#endif - -// ZLIB client - used by PNG, available for other purposes - -extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); -extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); -extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - -extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); -extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - -// TYPE-SPECIFIC ACCESS - -// is it a jpeg? -extern int stbi_jpeg_test_memory (stbi_uc const *buffer, int len); -extern stbi_uc *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); -extern int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); - -#ifndef STBI_NO_STDIO -extern stbi_uc *stbi_jpeg_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern int stbi_jpeg_test_file (FILE *f); -extern stbi_uc *stbi_jpeg_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); - -extern int stbi_jpeg_info (char const *filename, int *x, int *y, int *comp); -extern int stbi_jpeg_info_from_file (FILE *f, int *x, int *y, int *comp); -#endif - -// is it a png? -extern int stbi_png_test_memory (stbi_uc const *buffer, int len); -extern stbi_uc *stbi_png_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); -extern int stbi_png_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp); - -#ifndef STBI_NO_STDIO -extern stbi_uc *stbi_png_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern int stbi_png_info (char const *filename, int *x, int *y, int *comp); -extern int stbi_png_test_file (FILE *f); -extern stbi_uc *stbi_png_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -extern int stbi_png_info_from_file (FILE *f, int *x, int *y, int *comp); -#endif - -// is it a bmp? -extern int stbi_bmp_test_memory (stbi_uc const *buffer, int len); - -extern stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); -#ifndef STBI_NO_STDIO -extern int stbi_bmp_test_file (FILE *f); -extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -#endif - -// is it a tga? -extern int stbi_tga_test_memory (stbi_uc const *buffer, int len); - -extern stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); -#ifndef STBI_NO_STDIO -extern int stbi_tga_test_file (FILE *f); -extern stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -#endif - -// is it a psd? -extern int stbi_psd_test_memory (stbi_uc const *buffer, int len); - -extern stbi_uc *stbi_psd_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); -#ifndef STBI_NO_STDIO -extern int stbi_psd_test_file (FILE *f); -extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -#endif - -// is it an hdr? -extern int stbi_hdr_test_memory (stbi_uc const *buffer, int len); - -extern float * stbi_hdr_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); -#ifndef STBI_NO_STDIO -extern int stbi_hdr_test_file (FILE *f); -extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); -#endif - -// define new loaders -typedef struct -{ - int (*test_memory)(stbi_uc const *buffer, int len); - stbi_uc * (*load_from_memory)(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); - #ifndef STBI_NO_STDIO - int (*test_file)(FILE *f); - stbi_uc * (*load_from_file)(FILE *f, int *x, int *y, int *comp, int req_comp); - #endif -} stbi_loader; - -// register a loader by filling out the above structure (you must defined ALL functions) -// returns 1 if added or already added, 0 if not added (too many loaders) -// NOT THREADSAFE -extern int stbi_register_loader(stbi_loader *loader); - -// define faster low-level operations (typically SIMD support) -#if STBI_SIMD -typedef void (*stbi_idct_8x8)(uint8 *out, int out_stride, short data[64], unsigned short *dequantize); -// compute an integer IDCT on "input" -// input[x] = data[x] * dequantize[x] -// write results to 'out': 64 samples, each run of 8 spaced by 'out_stride' -// CLAMP results to 0..255 -typedef void (*stbi_YCbCr_to_RGB_run)(uint8 *output, uint8 const *y, uint8 const *cb, uint8 const *cr, int count, int step); -// compute a conversion from YCbCr to RGB -// 'count' pixels -// write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B -// y: Y input channel -// cb: Cb input channel; scale/biased to be 0..255 -// cr: Cr input channel; scale/biased to be 0..255 - -extern void stbi_install_idct(stbi_idct_8x8 func); -extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); -#endif // STBI_SIMD - -#ifdef __cplusplus -} -#endif - -// -// -//// end header file ///////////////////////////////////////////////////// -#endif // STBI_INCLUDE_STB_IMAGE_H - -#ifndef STBI_HEADER_FILE_ONLY - -#ifndef STBI_NO_HDR -#include // ldexp -#include // strcmp -#endif - -#ifndef STBI_NO_STDIO -#include -#endif -#include -#include -#include -#include - -#ifndef _MSC_VER - #ifdef __cplusplus - #define __forceinline inline - #else - #define __forceinline - #endif -#endif - - -// implementation: -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef signed short int16; -typedef unsigned int uint32; -typedef signed int int32; -typedef unsigned int uint; - -// should produce compiler error if size is wrong -typedef unsigned char validate_uint32[sizeof(uint32)==4]; - -#if defined(STBI_NO_STDIO) && !defined(STBI_NO_WRITE) -#define STBI_NO_WRITE -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// Generic API that works on all image types -// - -// this is not threadsafe -static char *failure_reason; - -char *stbi_failure_reason(void) -{ - return failure_reason; -} - -static int e(char *str) -{ - failure_reason = str; - return 0; -} - -#ifdef STBI_NO_FAILURE_STRINGS - #define e(x,y) 0 -#elif defined(STBI_FAILURE_USERMSG) - #define e(x,y) e(y) -#else - #define e(x,y) e(x) -#endif - -#define epf(x,y) ((float *) (e(x,y)?NULL:NULL)) -#define epuc(x,y) ((unsigned char *) (e(x,y)?NULL:NULL)) - -void stbi_image_free(void *retval_from_stbi_load) -{ - free(retval_from_stbi_load); -} - -#define MAX_LOADERS 32 -stbi_loader *loaders[MAX_LOADERS]; -static int max_loaders = 0; - -int stbi_register_loader(stbi_loader *loader) -{ - int i; - for (i=0; i < MAX_LOADERS; ++i) { - // already present? - if (loaders[i] == loader) - return 1; - // end of the list? - if (loaders[i] == NULL) { - loaders[i] = loader; - max_loaders = i+1; - return 1; - } - } - // no room for it - return 0; -} - -#ifndef STBI_NO_HDR -static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp); -static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp); -#endif - -#ifndef STBI_NO_STDIO -unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - FILE *f = fopen(filename, "rb"); - unsigned char *result; - if (!f) return epuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - int i; - if (stbi_jpeg_test_file(f)) - return stbi_jpeg_load_from_file(f,x,y,comp,req_comp); - if (stbi_png_test_file(f)) - return stbi_png_load_from_file(f,x,y,comp,req_comp); - if (stbi_bmp_test_file(f)) - return stbi_bmp_load_from_file(f,x,y,comp,req_comp); - if (stbi_psd_test_file(f)) - return stbi_psd_load_from_file(f,x,y,comp,req_comp); - #ifndef STBI_NO_HDR - if (stbi_hdr_test_file(f)) { - float *hdr = stbi_hdr_load_from_file(f, x,y,comp,req_comp); - return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); - } - #endif - for (i=0; i < max_loaders; ++i) - if (loaders[i]->test_file(f)) - return loaders[i]->load_from_file(f,x,y,comp,req_comp); - // test tga last because it's a crappy test! - if (stbi_tga_test_file(f)) - return stbi_tga_load_from_file(f,x,y,comp,req_comp); - return epuc("unknown image type", "Image not of any known type, or corrupt"); -} -#endif - -unsigned char *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - int i; - if (stbi_jpeg_test_memory(buffer,len)) - return stbi_jpeg_load_from_memory(buffer,len,x,y,comp,req_comp); - if (stbi_png_test_memory(buffer,len)) - return stbi_png_load_from_memory(buffer,len,x,y,comp,req_comp); - if (stbi_bmp_test_memory(buffer,len)) - return stbi_bmp_load_from_memory(buffer,len,x,y,comp,req_comp); - if (stbi_psd_test_memory(buffer,len)) - return stbi_psd_load_from_memory(buffer,len,x,y,comp,req_comp); - #ifndef STBI_NO_HDR - if (stbi_hdr_test_memory(buffer, len)) { - float *hdr = stbi_hdr_load_from_memory(buffer, len,x,y,comp,req_comp); - return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); - } - #endif - for (i=0; i < max_loaders; ++i) - if (loaders[i]->test_memory(buffer,len)) - return loaders[i]->load_from_memory(buffer,len,x,y,comp,req_comp); - // test tga last because it's a crappy test! - if (stbi_tga_test_memory(buffer,len)) - return stbi_tga_load_from_memory(buffer,len,x,y,comp,req_comp); - return epuc("unknown image type", "Image not of any known type, or corrupt"); -} - -#ifndef STBI_NO_HDR - -#ifndef STBI_NO_STDIO -float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - FILE *f = fopen(filename, "rb"); - float *result; - if (!f) return epf("can't fopen", "Unable to open file"); - result = stbi_loadf_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *data; - #ifndef STBI_NO_HDR - if (stbi_hdr_test_file(f)) - return stbi_hdr_load_from_file(f,x,y,comp,req_comp); - #endif - data = stbi_load_from_file(f, x, y, comp, req_comp); - if (data) - return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); - return epf("unknown image type", "Image not of any known type, or corrupt"); -} -#endif - -float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi_uc *data; - #ifndef STBI_NO_HDR - if (stbi_hdr_test_memory(buffer, len)) - return stbi_hdr_load_from_memory(buffer, len,x,y,comp,req_comp); - #endif - data = stbi_load_from_memory(buffer, len, x, y, comp, req_comp); - if (data) - return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); - return epf("unknown image type", "Image not of any known type, or corrupt"); -} -#endif - -// these is-hdr-or-not is defined independent of whether STBI_NO_HDR is -// defined, for API simplicity; if STBI_NO_HDR is defined, it always -// reports false! - -int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) -{ - #ifndef STBI_NO_HDR - return stbi_hdr_test_memory(buffer, len); - #else - return 0; - #endif -} - -#ifndef STBI_NO_STDIO -extern int stbi_is_hdr (char const *filename) -{ - FILE *f = fopen(filename, "rb"); - int result=0; - if (f) { - result = stbi_is_hdr_from_file(f); - fclose(f); - } - return result; -} - -extern int stbi_is_hdr_from_file(FILE *f) -{ - #ifndef STBI_NO_HDR - return stbi_hdr_test_file(f); - #else - return 0; - #endif -} - -#endif - -// @TODO: get image dimensions & components without fully decoding -#ifndef STBI_NO_STDIO -extern int stbi_info (char const *filename, int *x, int *y, int *comp); -extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); -#endif -extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); - -#ifndef STBI_NO_HDR -static float h2l_gamma_i=1.0f/2.2f, h2l_scale_i=1.0f; -static float l2h_gamma=2.2f, l2h_scale=1.0f; - -void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1/gamma; } -void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1/scale; } - -void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; } -void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } -#endif - - -////////////////////////////////////////////////////////////////////////////// -// -// Common code used by all image loaders -// - -enum -{ - SCAN_load=0, - SCAN_type, - SCAN_header, -}; - -typedef struct -{ - uint32 img_x, img_y; - int img_n, img_out_n; - - #ifndef STBI_NO_STDIO - FILE *img_file; - #endif - uint8 *img_buffer, *img_buffer_end; -} stbi; - -#ifndef STBI_NO_STDIO -static void start_file(stbi *s, FILE *f) -{ - s->img_file = f; -} -#endif - -static void start_mem(stbi *s, uint8 const *buffer, int len) -{ -#ifndef STBI_NO_STDIO - s->img_file = NULL; -#endif - s->img_buffer = (uint8 *) buffer; - s->img_buffer_end = (uint8 *) buffer+len; -} - -__forceinline static int get8(stbi *s) -{ -#ifndef STBI_NO_STDIO - if (s->img_file) { - int c = fgetc(s->img_file); - return c == EOF ? 0 : c; - } -#endif - if (s->img_buffer < s->img_buffer_end) - return *s->img_buffer++; - return 0; -} - -__forceinline static int at_eof(stbi *s) -{ -#ifndef STBI_NO_STDIO - if (s->img_file) - return feof(s->img_file); -#endif - return s->img_buffer >= s->img_buffer_end; -} - -__forceinline static uint8 get8u(stbi *s) -{ - return (uint8) get8(s); -} - -static void skip(stbi *s, int n) -{ -#ifndef STBI_NO_STDIO - if (s->img_file) - fseek(s->img_file, n, SEEK_CUR); - else -#endif - s->img_buffer += n; -} - -static int get16(stbi *s) -{ - int z = get8(s); - return (z << 8) + get8(s); -} - -static uint32 get32(stbi *s) -{ - uint32 z = get16(s); - return (z << 16) + get16(s); -} - -static int get16le(stbi *s) -{ - int z = get8(s); - return z + (get8(s) << 8); -} - -static uint32 get32le(stbi *s) -{ - uint32 z = get16le(s); - return z + (get16le(s) << 16); -} - -static void getn(stbi *s, stbi_uc *buffer, int n) -{ -#ifndef STBI_NO_STDIO - if (s->img_file) { - fread(buffer, 1, n, s->img_file); - return; - } -#endif - memcpy(buffer, s->img_buffer, n); - s->img_buffer += n; -} - -////////////////////////////////////////////////////////////////////////////// -// -// generic converter from built-in img_n to req_comp -// individual types do this automatically as much as possible (e.g. jpeg -// does all cases internally since it needs to colorspace convert anyway, -// and it never has alpha, so very few cases ). png can automatically -// interleave an alpha=255 channel, but falls back to this for other cases -// -// assume data buffer is malloced, so malloc a new one and free that one -// only failure mode is malloc failing - -static uint8 compute_y(int r, int g, int b) -{ - return (uint8) (((r*77) + (g*150) + (29*b)) >> 8); -} - -static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp, uint x, uint y) -{ - int i,j; - unsigned char *good; - - if (req_comp == img_n) return data; - assert(req_comp >= 1 && req_comp <= 4); - - good = (unsigned char *) malloc(req_comp * x * y); - if (good == NULL) { - free(data); - return epuc("outofmem", "Out of memory"); - } - - for (j=0; j < (int) y; ++j) { - unsigned char *src = data + j * x * img_n ; - unsigned char *dest = good + j * x * req_comp; - - #define COMBO(a,b) ((a)*8+(b)) - #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch(COMBO(img_n, req_comp)) { - CASE(1,2) dest[0]=src[0], dest[1]=255; break; - CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; - CASE(2,1) dest[0]=src[0]; break; - CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; - CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; - CASE(3,1) dest[0]=compute_y(src[0],src[1],src[2]); break; - CASE(3,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = 255; break; - CASE(4,1) dest[0]=compute_y(src[0],src[1],src[2]); break; - CASE(4,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; - CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; - default: assert(0); - } - #undef CASE - } - - free(data); - return good; -} - -#ifndef STBI_NO_HDR -static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp) -{ - int i,k,n; - float *output = (float *) malloc(x * y * comp * sizeof(float)); - if (output == NULL) { free(data); return epf("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - output[i*comp + k] = (float) pow(data[i*comp+k]/255.0f, l2h_gamma) * l2h_scale; - } - if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; - } - free(data); - return output; -} - -#define float2int(x) ((int) (x)) -static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) -{ - int i,k,n; - stbi_uc *output = (stbi_uc *) malloc(x * y * comp); - if (output == NULL) { free(data); return epuc("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = float2int(z); - } - if (k < comp) { - float z = data[i*comp+k] * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = float2int(z); - } - } - free(data); - return output; -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// "baseline" JPEG/JFIF decoder (not actually fully baseline implementation) -// -// simple implementation -// - channel subsampling of at most 2 in each dimension -// - doesn't support delayed output of y-dimension -// - simple interface (only one output format: 8-bit interleaved RGB) -// - doesn't try to recover corrupt jpegs -// - doesn't allow partial loading, loading multiple at once -// - still fast on x86 (copying globals into locals doesn't help x86) -// - allocates lots of intermediate memory (full size of all components) -// - non-interleaved case requires this anyway -// - allows good upsampling (see next) -// high-quality -// - upsampled channels are bilinearly interpolated, even across blocks -// - quality integer IDCT derived from IJG's 'slow' -// performance -// - fast huffman; reasonable integer IDCT -// - uses a lot of intermediate memory, could cache poorly -// - load http://nothings.org/remote/anemones.jpg 3 times on 2.8Ghz P4 -// stb_jpeg: 1.34 seconds (MSVC6, default release build) -// stb_jpeg: 1.06 seconds (MSVC6, processor = Pentium Pro) -// IJL11.dll: 1.08 seconds (compiled by intel) -// IJG 1998: 0.98 seconds (MSVC6, makefile provided by IJG) -// IJG 1998: 0.95 seconds (MSVC6, makefile + proc=PPro) - -// huffman decoding acceleration -#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache - -typedef struct -{ - uint8 fast[1 << FAST_BITS]; - // weirdly, repacking this into AoS is a 10% speed loss, instead of a win - uint16 code[256]; - uint8 values[256]; - uint8 size[257]; - unsigned int maxcode[18]; - int delta[17]; // old 'firstsymbol' - old 'firstcode' -} huffman; - -typedef struct -{ - #if STBI_SIMD - unsigned short dequant2[4][64]; - #endif - stbi s; - huffman huff_dc[4]; - huffman huff_ac[4]; - uint8 dequant[4][64]; - -// sizes for components, interleaved MCUs - int img_h_max, img_v_max; - int img_mcu_x, img_mcu_y; - int img_mcu_w, img_mcu_h; - -// definition of jpeg image component - struct - { - int id; - int h,v; - int tq; - int hd,ha; - int dc_pred; - - int x,y,w2,h2; - uint8 *data; - void *raw_data; - uint8 *linebuf; - } img_comp[4]; - - uint32 code_buffer; // jpeg entropy-coded buffer - int code_bits; // number of valid bits - unsigned char marker; // marker seen while filling entropy buffer - int nomore; // flag if we saw a marker so must stop - - int scan_n, order[4]; - int restart_interval, todo; -} jpeg; - -static int build_huffman(huffman *h, int *count) -{ - int i,j,k=0,code; - // build size list for each symbol (from JPEG spec) - for (i=0; i < 16; ++i) - for (j=0; j < count[i]; ++j) - h->size[k++] = (uint8) (i+1); - h->size[k] = 0; - - // compute actual symbols (from jpeg spec) - code = 0; - k = 0; - for(j=1; j <= 16; ++j) { - // compute delta to add to code to compute symbol id - h->delta[j] = k - code; - if (h->size[k] == j) { - while (h->size[k] == j) - h->code[k++] = (uint16) (code++); - if (code-1 >= (1 << j)) return e("bad code lengths","Corrupt JPEG"); - } - // compute largest code + 1 for this size, preshifted as needed later - h->maxcode[j] = code << (16-j); - code <<= 1; - } - h->maxcode[j] = 0xffffffff; - - // build non-spec acceleration table; 255 is flag for not-accelerated - memset(h->fast, 255, 1 << FAST_BITS); - for (i=0; i < k; ++i) { - int s = h->size[i]; - if (s <= FAST_BITS) { - int c = h->code[i] << (FAST_BITS-s); - int m = 1 << (FAST_BITS-s); - for (j=0; j < m; ++j) { - h->fast[c+j] = (uint8) i; - } - } - } - return 1; -} - -static void grow_buffer_unsafe(jpeg *j) -{ - do { - int b = j->nomore ? 0 : get8(&j->s); - if (b == 0xff) { - int c = get8(&j->s); - if (c != 0) { - j->marker = (unsigned char) c; - j->nomore = 1; - return; - } - } - j->code_buffer = (j->code_buffer << 8) | b; - j->code_bits += 8; - } while (j->code_bits <= 24); -} - -// (1 << n) - 1 -static uint32 bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; - -// decode a jpeg huffman value from the bitstream -__forceinline static int decode(jpeg *j, huffman *h) -{ - unsigned int temp; - int c,k; - - if (j->code_bits < 16) grow_buffer_unsafe(j); - - // look at the top FAST_BITS and determine what symbol ID it is, - // if the code is <= FAST_BITS - c = (j->code_buffer >> (j->code_bits - FAST_BITS)) & ((1 << FAST_BITS)-1); - k = h->fast[c]; - if (k < 255) { - if (h->size[k] > j->code_bits) - return -1; - j->code_bits -= h->size[k]; - return h->values[k]; - } - - // naive test is to shift the code_buffer down so k bits are - // valid, then test against maxcode. To speed this up, we've - // preshifted maxcode left so that it has (16-k) 0s at the - // end; in other words, regardless of the number of bits, it - // wants to be compared against something shifted to have 16; - // that way we don't need to shift inside the loop. - if (j->code_bits < 16) - temp = (j->code_buffer << (16 - j->code_bits)) & 0xffff; - else - temp = (j->code_buffer >> (j->code_bits - 16)) & 0xffff; - for (k=FAST_BITS+1 ; ; ++k) - if (temp < h->maxcode[k]) - break; - if (k == 17) { - // error! code not found - j->code_bits -= 16; - return -1; - } - - if (k > j->code_bits) - return -1; - - // convert the huffman code to the symbol id - c = ((j->code_buffer >> (j->code_bits - k)) & bmask[k]) + h->delta[k]; - assert((((j->code_buffer) >> (j->code_bits - h->size[c])) & bmask[h->size[c]]) == h->code[c]); - - // convert the id to a symbol - j->code_bits -= k; - return h->values[c]; -} - -// combined JPEG 'receive' and JPEG 'extend', since baseline -// always extends everything it receives. -__forceinline static int extend_receive(jpeg *j, int n) -{ - unsigned int m = 1 << (n-1); - unsigned int k; - if (j->code_bits < n) grow_buffer_unsafe(j); - k = (j->code_buffer >> (j->code_bits - n)) & bmask[n]; - j->code_bits -= n; - // the following test is probably a random branch that won't - // predict well. I tried to table accelerate it but failed. - // maybe it's compiling as a conditional move? - if (k < m) - return (-1 << n) + k + 1; - else - return k; -} - -// given a value that's at position X in the zigzag stream, -// where does it appear in the 8x8 matrix coded as row-major? -static uint8 dezigzag[64+15] = -{ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - // let corrupt input sample past end - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63 -}; - -// decode one 64-entry block-- -static int decode_block(jpeg *j, short data[64], huffman *hdc, huffman *hac, int b) -{ - int diff,dc,k; - int t = decode(j, hdc); - if (t < 0) return e("bad huffman code","Corrupt JPEG"); - - // 0 all the ac values now so we can do it 32-bits at a time - memset(data,0,64*sizeof(data[0])); - - diff = t ? extend_receive(j, t) : 0; - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short) dc; - - // decode AC components, see JPEG spec - k = 1; - do { - int r,s; - int rs = decode(j, hac); - if (rs < 0) return e("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (rs != 0xf0) break; // end block - k += 16; - } else { - k += r; - // decode into unzigzag'd location - data[dezigzag[k++]] = (short) extend_receive(j,s); - } - } while (k < 64); - return 1; -} - -// take a -128..127 value and clamp it and convert to 0..255 -__forceinline static uint8 clamp(int x) -{ - x += 128; - // trick to use a single test to catch both cases - if ((unsigned int) x > 255) { - if (x < 0) return 0; - if (x > 255) return 255; - } - return (uint8) x; -} - -#define f2f(x) (int) (((x) * 4096 + 0.5)) -#define fsh(x) ((x) << 12) - -// derived from jidctint -- DCT_ISLOW -#define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ - int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ - p2 = s2; \ - p3 = s6; \ - p1 = (p2+p3) * f2f(0.5411961f); \ - t2 = p1 + p3*f2f(-1.847759065f); \ - t3 = p1 + p2*f2f( 0.765366865f); \ - p2 = s0; \ - p3 = s4; \ - t0 = fsh(p2+p3); \ - t1 = fsh(p2-p3); \ - x0 = t0+t3; \ - x3 = t0-t3; \ - x1 = t1+t2; \ - x2 = t1-t2; \ - t0 = s7; \ - t1 = s5; \ - t2 = s3; \ - t3 = s1; \ - p3 = t0+t2; \ - p4 = t1+t3; \ - p1 = t0+t3; \ - p2 = t1+t2; \ - p5 = (p3+p4)*f2f( 1.175875602f); \ - t0 = t0*f2f( 0.298631336f); \ - t1 = t1*f2f( 2.053119869f); \ - t2 = t2*f2f( 3.072711026f); \ - t3 = t3*f2f( 1.501321110f); \ - p1 = p5 + p1*f2f(-0.899976223f); \ - p2 = p5 + p2*f2f(-2.562915447f); \ - p3 = p3*f2f(-1.961570560f); \ - p4 = p4*f2f(-0.390180644f); \ - t3 += p1+p4; \ - t2 += p2+p3; \ - t1 += p2+p4; \ - t0 += p1+p3; - -#if !STBI_SIMD -// .344 seconds on 3*anemones.jpg -static void idct_block(uint8 *out, int out_stride, short data[64], uint8 *dequantize) -{ - int i,val[64],*v=val; - uint8 *o,*dq = dequantize; - short *d = data; - - // columns - for (i=0; i < 8; ++i,++d,++dq, ++v) { - // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 - && d[40]==0 && d[48]==0 && d[56]==0) { - // no shortcut 0 seconds - // (1|2|3|4|5|6|7)==0 0 seconds - // all separate -0.047 seconds - // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0] * dq[0] << 2; - v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } else { - IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24], - d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56]) - // constants scaled things up by 1<<12; let's bring them back - // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[ 0] = (x0+t3) >> 10; - v[56] = (x0-t3) >> 10; - v[ 8] = (x1+t2) >> 10; - v[48] = (x1-t2) >> 10; - v[16] = (x2+t1) >> 10; - v[40] = (x2-t1) >> 10; - v[24] = (x3+t0) >> 10; - v[32] = (x3-t0) >> 10; - } - } - - for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { - // no fast case since the first 1D IDCT spread components out - IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) - // constants scaled things up by 1<<12, plus we had 1<<2 from first - // loop, plus horizontal and vertical each scale by sqrt(8) so together - // we've got an extra 1<<3, so 1<<17 total we need to remove. - x0 += 65536; x1 += 65536; x2 += 65536; x3 += 65536; - o[0] = clamp((x0+t3) >> 17); - o[7] = clamp((x0-t3) >> 17); - o[1] = clamp((x1+t2) >> 17); - o[6] = clamp((x1-t2) >> 17); - o[2] = clamp((x2+t1) >> 17); - o[5] = clamp((x2-t1) >> 17); - o[3] = clamp((x3+t0) >> 17); - o[4] = clamp((x3-t0) >> 17); - } -} -#else -static void idct_block(uint8 *out, int out_stride, short data[64], unsigned short *dequantize) -{ - int i,val[64],*v=val; - uint8 *o; - unsigned short *dq = dequantize; - short *d = data; - - // columns - for (i=0; i < 8; ++i,++d,++dq, ++v) { - // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 - && d[40]==0 && d[48]==0 && d[56]==0) { - // no shortcut 0 seconds - // (1|2|3|4|5|6|7)==0 0 seconds - // all separate -0.047 seconds - // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0] * dq[0] << 2; - v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } else { - IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24], - d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56]) - // constants scaled things up by 1<<12; let's bring them back - // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[ 0] = (x0+t3) >> 10; - v[56] = (x0-t3) >> 10; - v[ 8] = (x1+t2) >> 10; - v[48] = (x1-t2) >> 10; - v[16] = (x2+t1) >> 10; - v[40] = (x2-t1) >> 10; - v[24] = (x3+t0) >> 10; - v[32] = (x3-t0) >> 10; - } - } - - for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { - // no fast case since the first 1D IDCT spread components out - IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) - // constants scaled things up by 1<<12, plus we had 1<<2 from first - // loop, plus horizontal and vertical each scale by sqrt(8) so together - // we've got an extra 1<<3, so 1<<17 total we need to remove. - x0 += 65536; x1 += 65536; x2 += 65536; x3 += 65536; - o[0] = clamp((x0+t3) >> 17); - o[7] = clamp((x0-t3) >> 17); - o[1] = clamp((x1+t2) >> 17); - o[6] = clamp((x1-t2) >> 17); - o[2] = clamp((x2+t1) >> 17); - o[5] = clamp((x2-t1) >> 17); - o[3] = clamp((x3+t0) >> 17); - o[4] = clamp((x3-t0) >> 17); - } -} -static stbi_idct_8x8 stbi_idct_installed = idct_block; - -extern void stbi_install_idct(stbi_idct_8x8 func) -{ - stbi_idct_installed = func; -} -#endif - -#define MARKER_none 0xff -// if there's a pending marker from the entropy stream, return that -// otherwise, fetch from the stream and get a marker. if there's no -// marker, return 0xff, which is never a valid marker value -static uint8 get_marker(jpeg *j) -{ - uint8 x; - if (j->marker != MARKER_none) { x = j->marker; j->marker = MARKER_none; return x; } - x = get8u(&j->s); - if (x != 0xff) return MARKER_none; - while (x == 0xff) - x = get8u(&j->s); - return x; -} - -// in each scan, we'll have scan_n components, and the order -// of the components is specified by order[] -#define RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) - -// after a restart interval, reset the entropy decoder and -// the dc prediction -static void reset(jpeg *j) -{ - j->code_bits = 0; - j->code_buffer = 0; - j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; - j->marker = MARKER_none; - j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; - // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, - // since we don't even allow 1<<30 pixels -} - -static int parse_entropy_coded_data(jpeg *z) -{ - reset(z); - if (z->scan_n == 1) { - int i,j; - #if STBI_SIMD - __declspec(align(16)) - #endif - short data[64]; - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; - #if STBI_SIMD - stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); - #else - idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); - #endif - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!RESTART(z->marker)) return 1; - reset(z); - } - } - } - } else { // interleaved! - int i,j,k,x,y; - short data[64]; - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x)*8; - int y2 = (j*z->img_comp[n].v + y)*8; - if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; - #if STBI_SIMD - stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); - #else - idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); - #endif - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!RESTART(z->marker)) return 1; - reset(z); - } - } - } - } - return 1; -} - -static int process_marker(jpeg *z, int m) -{ - int L; - switch (m) { - case MARKER_none: // no marker found - return e("expected marker","Corrupt JPEG"); - - case 0xC2: // SOF - progressive - return e("progressive jpeg","JPEG format not supported (progressive)"); - - case 0xDD: // DRI - specify restart interval - if (get16(&z->s) != 4) return e("bad DRI len","Corrupt JPEG"); - z->restart_interval = get16(&z->s); - return 1; - - case 0xDB: // DQT - define quantization table - L = get16(&z->s)-2; - while (L > 0) { - int q = get8(&z->s); - int p = q >> 4; - int t = q & 15,i; - if (p != 0) return e("bad DQT type","Corrupt JPEG"); - if (t > 3) return e("bad DQT table","Corrupt JPEG"); - for (i=0; i < 64; ++i) - z->dequant[t][dezigzag[i]] = get8u(&z->s); - #if STBI_SIMD - for (i=0; i < 64; ++i) - z->dequant2[t][i] = z->dequant[t][i]; - #endif - L -= 65; - } - return L==0; - - case 0xC4: // DHT - define huffman table - L = get16(&z->s)-2; - while (L > 0) { - uint8 *v; - int sizes[16],i,m=0; - int q = get8(&z->s); - int tc = q >> 4; - int th = q & 15; - if (tc > 1 || th > 3) return e("bad DHT header","Corrupt JPEG"); - for (i=0; i < 16; ++i) { - sizes[i] = get8(&z->s); - m += sizes[i]; - } - L -= 17; - if (tc == 0) { - if (!build_huffman(z->huff_dc+th, sizes)) return 0; - v = z->huff_dc[th].values; - } else { - if (!build_huffman(z->huff_ac+th, sizes)) return 0; - v = z->huff_ac[th].values; - } - for (i=0; i < m; ++i) - v[i] = get8u(&z->s); - L -= m; - } - return L==0; - } - // check for comment block or APP blocks - if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - skip(&z->s, get16(&z->s)-2); - return 1; - } - return 0; -} - -// after we see SOS -static int process_scan_header(jpeg *z) -{ - int i; - int Ls = get16(&z->s); - z->scan_n = get8(&z->s); - if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s.img_n) return e("bad SOS component count","Corrupt JPEG"); - if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG"); - for (i=0; i < z->scan_n; ++i) { - int id = get8(&z->s), which; - int q = get8(&z->s); - for (which = 0; which < z->s.img_n; ++which) - if (z->img_comp[which].id == id) - break; - if (which == z->s.img_n) return 0; - z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return e("bad DC huff","Corrupt JPEG"); - z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG"); - z->order[i] = which; - } - if (get8(&z->s) != 0) return e("bad SOS","Corrupt JPEG"); - get8(&z->s); // should be 63, but might be 0 - if (get8(&z->s) != 0) return e("bad SOS","Corrupt JPEG"); - - return 1; -} - -static int process_frame_header(jpeg *z, int scan) -{ - stbi *s = &z->s; - int Lf,p,i,q, h_max=1,v_max=1,c; - Lf = get16(s); if (Lf < 11) return e("bad SOF len","Corrupt JPEG"); // JPEG - p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = get16(s); if (s->img_x == 0) return e("0 width","Corrupt JPEG"); // JPEG requires - c = get8(s); - if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG"); // JFIF requires - s->img_n = c; - for (i=0; i < c; ++i) { - z->img_comp[i].data = NULL; - z->img_comp[i].linebuf = NULL; - } - - if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG"); - - for (i=0; i < s->img_n; ++i) { - z->img_comp[i].id = get8(s); - if (z->img_comp[i].id != i+1) // JFIF requires - if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! - return e("bad component ID","Corrupt JPEG"); - q = get8(s); - z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H","Corrupt JPEG"); - z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V","Corrupt JPEG"); - z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG"); - } - - if (scan != SCAN_load) return 1; - - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); - - for (i=0; i < s->img_n; ++i) { - if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; - } - - // compute interleaved mcu info - z->img_h_max = h_max; - z->img_v_max = v_max; - z->img_mcu_w = h_max * 8; - z->img_mcu_h = v_max * 8; - z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; - z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; - - for (i=0; i < s->img_n; ++i) { - // number of effective pixels (e.g. for non-interleaved MCU) - z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; - z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; - // to simplify generation, we'll allocate enough memory to decode - // the bogus oversized data from using interleaved MCUs and their - // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't - // discard the extra data until colorspace conversion - z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; - z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); - if (z->img_comp[i].raw_data == NULL) { - for(--i; i >= 0; --i) { - free(z->img_comp[i].raw_data); - z->img_comp[i].data = NULL; - } - return e("outofmem", "Out of memory"); - } - // align blocks for installable-idct using mmx/sse - z->img_comp[i].data = (uint8*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - z->img_comp[i].linebuf = NULL; - } - - return 1; -} - -// use comparisons since in some cases we handle more than one case (e.g. SOF) -#define DNL(x) ((x) == 0xdc) -#define SOI(x) ((x) == 0xd8) -#define EOI(x) ((x) == 0xd9) -#define SOF(x) ((x) == 0xc0 || (x) == 0xc1) -#define SOS(x) ((x) == 0xda) - -static int decode_jpeg_header(jpeg *z, int scan) -{ - int m; - z->marker = MARKER_none; // initialize cached marker to empty - m = get_marker(z); - if (!SOI(m)) return e("no SOI","Corrupt JPEG"); - if (scan == SCAN_type) return 1; - m = get_marker(z); - while (!SOF(m)) { - if (!process_marker(z,m)) return 0; - m = get_marker(z); - while (m == MARKER_none) { - // some files have extra padding after their blocks, so ok, we'll scan - if (at_eof(&z->s)) return e("no SOF", "Corrupt JPEG"); - m = get_marker(z); - } - } - if (!process_frame_header(z, scan)) return 0; - return 1; -} - -static int decode_jpeg_image(jpeg *j) -{ - int m; - j->restart_interval = 0; - if (!decode_jpeg_header(j, SCAN_load)) return 0; - m = get_marker(j); - while (!EOI(m)) { - if (SOS(m)) { - if (!process_scan_header(j)) return 0; - if (!parse_entropy_coded_data(j)) return 0; - } else { - if (!process_marker(j, m)) return 0; - } - m = get_marker(j); - } - return 1; -} - -// static jfif-centered resampling (across block boundaries) - -typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1, - int w, int hs); - -#define div4(x) ((uint8) ((x) >> 2)) - -static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) -{ - return in_near; -} - -static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) -{ - // need to generate two samples vertically for every one in input - int i; - for (i=0; i < w; ++i) - out[i] = div4(3*in_near[i] + in_far[i] + 2); - return out; -} - -static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) -{ - // need to generate two samples horizontally for every one in input - int i; - uint8 *input = in_near; - if (w == 1) { - // if only one sample, can't do any interpolation - out[0] = out[1] = input[0]; - return out; - } - - out[0] = input[0]; - out[1] = div4(input[0]*3 + input[1] + 2); - for (i=1; i < w-1; ++i) { - int n = 3*input[i]+2; - out[i*2+0] = div4(n+input[i-1]); - out[i*2+1] = div4(n+input[i+1]); - } - out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2); - out[i*2+1] = input[w-1]; - return out; -} - -#define div16(x) ((uint8) ((x) >> 4)) - -static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i,t0,t1; - if (w == 1) { - out[0] = out[1] = div4(3*in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3*in_near[0] + in_far[0]; - out[0] = div4(t1+2); - for (i=1; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = div16(3*t0 + t1 + 8); - out[i*2 ] = div16(3*t1 + t0 + 8); - } - out[w*2-1] = div4(t1+2); - return out; -} - -static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) -{ - // resample with nearest-neighbor - int i,j; - for (i=0; i < w; ++i) - for (j=0; j < hs; ++j) - out[i*hs+j] = in_near[i]; - return out; -} - -#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) - -// 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) -// VC6 without processor=Pro is generating multiple LEAs per multiply! -static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) -{ - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 16) + 32768; // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr*float2fixed(1.40200f); - g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); - b = y_fixed + cb*float2fixed(1.77200f); - r >>= 16; - g >>= 16; - b >>= 16; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (uint8)r; - out[1] = (uint8)g; - out[2] = (uint8)b; - out[3] = 255; - out += step; - } -} - -#if STBI_SIMD -static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row; - -void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func) -{ - stbi_YCbCr_installed = func; -} -#endif - - -// clean up the temporary component buffers -static void cleanup_jpeg(jpeg *j) -{ - int i; - for (i=0; i < j->s.img_n; ++i) { - if (j->img_comp[i].data) { - free(j->img_comp[i].raw_data); - j->img_comp[i].data = NULL; - } - if (j->img_comp[i].linebuf) { - free(j->img_comp[i].linebuf); - j->img_comp[i].linebuf = NULL; - } - } -} - -typedef struct -{ - resample_row_func resample; - uint8 *line0,*line1; - int hs,vs; // expansion factor in each axis - int w_lores; // horizontal pixels pre-expansion - int ystep; // how far through vertical expansion we are - int ypos; // which pre-expansion row we're on -} stbi_resample; - -static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) -{ - int n, decode_n; - // validate req_comp - if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); - z->s.img_n = 0; - - // load a jpeg image from whichever source - if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL; } - - // determine actual number of components to generate - n = req_comp ? req_comp : z->s.img_n; - - if (z->s.img_n == 3 && n < 3) - decode_n = 1; - else - decode_n = z->s.img_n; - - // resample and color-convert - { - int k; - uint i,j; - uint8 *output; - uint8 *coutput[4]; - - stbi_resample res_comp[4]; - - for (k=0; k < decode_n; ++k) { - stbi_resample *r = &res_comp[k]; - - // allocate line buffer big enough for upsampling off the edges - // with upsample factor of 4 - z->img_comp[k].linebuf = (uint8 *) malloc(z->s.img_x + 3); - if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } - - r->hs = z->img_h_max / z->img_comp[k].h; - r->vs = z->img_v_max / z->img_comp[k].v; - r->ystep = r->vs >> 1; - r->w_lores = (z->s.img_x + r->hs-1) / r->hs; - r->ypos = 0; - r->line0 = r->line1 = z->img_comp[k].data; - - if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; - else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2; - else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2; - else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2; - else r->resample = resample_row_generic; - } - - // can't error after this so, this is safe - output = (uint8 *) malloc(n * z->s.img_x * z->s.img_y + 1); - if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } - - // now go ahead and resample - for (j=0; j < z->s.img_y; ++j) { - uint8 *out = output + n * z->s.img_x * j; - for (k=0; k < decode_n; ++k) { - stbi_resample *r = &res_comp[k]; - int y_bot = r->ystep >= (r->vs >> 1); - coutput[k] = r->resample(z->img_comp[k].linebuf, - y_bot ? r->line1 : r->line0, - y_bot ? r->line0 : r->line1, - r->w_lores, r->hs); - if (++r->ystep >= r->vs) { - r->ystep = 0; - r->line0 = r->line1; - if (++r->ypos < z->img_comp[k].y) - r->line1 += z->img_comp[k].w2; - } - } - if (n >= 3) { - uint8 *y = coutput[0]; - if (z->s.img_n == 3) { - #if STBI_SIMD - stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); - #else - YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s.img_x, n); - #endif - } else - for (i=0; i < z->s.img_x; ++i) { - out[0] = out[1] = out[2] = y[i]; - out[3] = 255; // not used if n==3 - out += n; - } - } else { - uint8 *y = coutput[0]; - if (n == 1) - for (i=0; i < z->s.img_x; ++i) out[i] = y[i]; - else - for (i=0; i < z->s.img_x; ++i) *out++ = y[i], *out++ = 255; - } - } - cleanup_jpeg(z); - *out_x = z->s.img_x; - *out_y = z->s.img_y; - if (comp) *comp = z->s.img_n; // report original components, not output - return output; - } -} - -#ifndef STBI_NO_STDIO -unsigned char *stbi_jpeg_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - jpeg j; - start_file(&j.s, f); - return load_jpeg_image(&j, x,y,comp,req_comp); -} - -unsigned char *stbi_jpeg_load(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *data; - FILE *f = fopen(filename, "rb"); - if (!f) return NULL; - data = stbi_jpeg_load_from_file(f,x,y,comp,req_comp); - fclose(f); - return data; -} -#endif - -unsigned char *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - jpeg j; - start_mem(&j.s, buffer,len); - return load_jpeg_image(&j, x,y,comp,req_comp); -} - -#ifndef STBI_NO_STDIO -int stbi_jpeg_test_file(FILE *f) -{ - int n,r; - jpeg j; - n = ftell(f); - start_file(&j.s, f); - r = decode_jpeg_header(&j, SCAN_type); - fseek(f,n,SEEK_SET); - return r; -} -#endif - -int stbi_jpeg_test_memory(stbi_uc const *buffer, int len) -{ - jpeg j; - start_mem(&j.s, buffer,len); - return decode_jpeg_header(&j, SCAN_type); -} - -// @TODO: -#ifndef STBI_NO_STDIO -extern int stbi_jpeg_info (char const *filename, int *x, int *y, int *comp); -extern int stbi_jpeg_info_from_file (FILE *f, int *x, int *y, int *comp); -#endif -extern int stbi_jpeg_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); - -// public domain zlib decode v0.2 Sean Barrett 2006-11-18 -// simple implementation -// - all input must be provided in an upfront buffer -// - all output is written to a single output buffer (can malloc/realloc) -// performance -// - fast huffman - -// fast-way is faster to check than jpeg huffman, but slow way is slower -#define ZFAST_BITS 9 // accelerate all cases in default tables -#define ZFAST_MASK ((1 << ZFAST_BITS) - 1) - -// zlib-style huffman encoding -// (jpegs packs from left, zlib from right, so can't share code) -typedef struct -{ - uint16 fast[1 << ZFAST_BITS]; - uint16 firstcode[16]; - int maxcode[17]; - uint16 firstsymbol[16]; - uint8 size[288]; - uint16 value[288]; -} zhuffman; - -__forceinline static int bitreverse16(int n) -{ - n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); - n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); - n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); - n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); - return n; -} - -__forceinline static int bit_reverse(int v, int bits) -{ - assert(bits <= 16); - // to bit reverse n bits, reverse 16 and shift - // e.g. 11 bits, bit reverse and shift away 5 - return bitreverse16(v) >> (16-bits); -} - -static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) -{ - int i,k=0; - int code, next_code[16], sizes[17]; - - // DEFLATE spec for generating codes - memset(sizes, 0, sizeof(sizes)); - memset(z->fast, 255, sizeof(z->fast)); - for (i=0; i < num; ++i) - ++sizes[sizelist[i]]; - sizes[0] = 0; - for (i=1; i < 16; ++i) - assert(sizes[i] <= (1 << i)); - code = 0; - for (i=1; i < 16; ++i) { - next_code[i] = code; - z->firstcode[i] = (uint16) code; - z->firstsymbol[i] = (uint16) k; - code = (code + sizes[i]); - if (sizes[i]) - if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG"); - z->maxcode[i] = code << (16-i); // preshift for inner loop - code <<= 1; - k += sizes[i]; - } - z->maxcode[16] = 0x10000; // sentinel - for (i=0; i < num; ++i) { - int s = sizelist[i]; - if (s) { - int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; - z->size[c] = (uint8)s; - z->value[c] = (uint16)i; - if (s <= ZFAST_BITS) { - int k = bit_reverse(next_code[s],s); - while (k < (1 << ZFAST_BITS)) { - z->fast[k] = (uint16) c; - k += (1 << s); - } - } - ++next_code[s]; - } - } - return 1; -} - -// zlib-from-memory implementation for PNG reading -// because PNG allows splitting the zlib stream arbitrarily, -// and it's annoying structurally to have PNG call ZLIB call PNG, -// we require PNG read all the IDATs and combine them into a single -// memory buffer - -typedef struct -{ - uint8 *zbuffer, *zbuffer_end; - int num_bits; - uint32 code_buffer; - - char *zout; - char *zout_start; - char *zout_end; - int z_expandable; - - zhuffman z_length, z_distance; -} zbuf; - -__forceinline static int zget8(zbuf *z) -{ - if (z->zbuffer >= z->zbuffer_end) return 0; - return *z->zbuffer++; -} - -static void fill_bits(zbuf *z) -{ - do { - assert(z->code_buffer < (1U << z->num_bits)); - z->code_buffer |= zget8(z) << z->num_bits; - z->num_bits += 8; - } while (z->num_bits <= 24); -} - -__forceinline static unsigned int zreceive(zbuf *z, int n) -{ - unsigned int k; - if (z->num_bits < n) fill_bits(z); - k = z->code_buffer & ((1 << n) - 1); - z->code_buffer >>= n; - z->num_bits -= n; - return k; -} - -__forceinline static int zhuffman_decode(zbuf *a, zhuffman *z) -{ - int b,s,k; - if (a->num_bits < 16) fill_bits(a); - b = z->fast[a->code_buffer & ZFAST_MASK]; - if (b < 0xffff) { - s = z->size[b]; - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; - } - - // not resolved by fast table, so compute it the slow way - // use jpeg approach, which requires MSbits at top - k = bit_reverse(a->code_buffer, 16); - for (s=ZFAST_BITS+1; ; ++s) - if (k < z->maxcode[s]) - break; - if (s == 16) return -1; // invalid code! - // code size is s, so: - b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; - assert(z->size[b] == s); - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; -} - -static int expand(zbuf *z, int n) // need to make room for n bytes -{ - char *q; - int cur, limit; - if (!z->z_expandable) return e("output buffer limit","Corrupt PNG"); - cur = (int) (z->zout - z->zout_start); - limit = (int) (z->zout_end - z->zout_start); - while (cur + n > limit) - limit *= 2; - q = (char *) realloc(z->zout_start, limit); - if (q == NULL) return e("outofmem", "Out of memory"); - z->zout_start = q; - z->zout = q + cur; - z->zout_end = q + limit; - return 1; -} - -static int length_base[31] = { - 3,4,5,6,7,8,9,10,11,13, - 15,17,19,23,27,31,35,43,51,59, - 67,83,99,115,131,163,195,227,258,0,0 }; - -static int length_extra[31]= -{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; - -static int dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, -257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; - -static int dist_extra[32] = -{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -static int parse_huffman_block(zbuf *a) -{ - for(;;) { - int z = zhuffman_decode(a, &a->z_length); - if (z < 256) { - if (z < 0) return e("bad huffman code","Corrupt PNG"); // error in huffman codes - if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0; - *a->zout++ = (char) z; - } else { - uint8 *p; - int len,dist; - if (z == 256) return 1; - z -= 257; - len = length_base[z]; - if (length_extra[z]) len += zreceive(a, length_extra[z]); - z = zhuffman_decode(a, &a->z_distance); - if (z < 0) return e("bad huffman code","Corrupt PNG"); - dist = dist_base[z]; - if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); - if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG"); - if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0; - p = (uint8 *) (a->zout - dist); - while (len--) - *a->zout++ = *p++; - } - } -} - -static int compute_huffman_codes(zbuf *a) -{ - static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; - zhuffman z_codelength; - uint8 lencodes[286+32+137];//padding for maximum single op - uint8 codelength_sizes[19]; - int i,n; - - int hlit = zreceive(a,5) + 257; - int hdist = zreceive(a,5) + 1; - int hclen = zreceive(a,4) + 4; - - memset(codelength_sizes, 0, sizeof(codelength_sizes)); - for (i=0; i < hclen; ++i) { - int s = zreceive(a,3); - codelength_sizes[length_dezigzag[i]] = (uint8) s; - } - if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; - - n = 0; - while (n < hlit + hdist) { - int c = zhuffman_decode(a, &z_codelength); - assert(c >= 0 && c < 19); - if (c < 16) - lencodes[n++] = (uint8) c; - else if (c == 16) { - c = zreceive(a,2)+3; - memset(lencodes+n, lencodes[n-1], c); - n += c; - } else if (c == 17) { - c = zreceive(a,3)+3; - memset(lencodes+n, 0, c); - n += c; - } else { - assert(c == 18); - c = zreceive(a,7)+11; - memset(lencodes+n, 0, c); - n += c; - } - } - if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG"); - if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; - if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; - return 1; -} - -static int parse_uncompressed_block(zbuf *a) -{ - uint8 header[4]; - int len,nlen,k; - if (a->num_bits & 7) - zreceive(a, a->num_bits & 7); // discard - // drain the bit-packed data into header - k = 0; - while (a->num_bits > 0) { - header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns? - a->code_buffer >>= 8; - a->num_bits -= 8; - } - assert(a->num_bits == 0); - // now fill header the normal way - while (k < 4) - header[k++] = (uint8) zget8(a); - len = header[1] * 256 + header[0]; - nlen = header[3] * 256 + header[2]; - if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG"); - if (a->zout + len > a->zout_end) - if (!expand(a, len)) return 0; - memcpy(a->zout, a->zbuffer, len); - a->zbuffer += len; - a->zout += len; - return 1; -} - -static int parse_zlib_header(zbuf *a) -{ - int cmf = zget8(a); - int cm = cmf & 15; - /* int cinfo = cmf >> 4; */ - int flg = zget8(a); - if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG"); // zlib spec - if (flg & 32) return e("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return e("bad compression","Corrupt PNG"); // DEFLATE required for png - // window = 1 << (8 + cinfo)... but who cares, we fully buffer output - return 1; -} - -// @TODO: should statically initialize these for optimal thread safety -static uint8 default_length[288], default_distance[32]; -static void init_defaults(void) -{ - int i; // use <= to match clearly with spec - for (i=0; i <= 143; ++i) default_length[i] = 8; - for ( ; i <= 255; ++i) default_length[i] = 9; - for ( ; i <= 279; ++i) default_length[i] = 7; - for ( ; i <= 287; ++i) default_length[i] = 8; - - for (i=0; i <= 31; ++i) default_distance[i] = 5; -} - -int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead -static int parse_zlib(zbuf *a, int parse_header) -{ - int final, type; - if (parse_header) - if (!parse_zlib_header(a)) return 0; - a->num_bits = 0; - a->code_buffer = 0; - do { - final = zreceive(a,1); - type = zreceive(a,2); - if (type == 0) { - if (!parse_uncompressed_block(a)) return 0; - } else if (type == 3) { - return 0; - } else { - if (type == 1) { - // use fixed code lengths - if (!default_distance[31]) init_defaults(); - if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0; - if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; - } else { - if (!compute_huffman_codes(a)) return 0; - } - if (!parse_huffman_block(a)) return 0; - } - if (stbi_png_partial && a->zout - a->zout_start > 65536) - break; - } while (!final); - return 1; -} - -static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header) -{ - a->zout_start = obuf; - a->zout = obuf; - a->zout_end = obuf + olen; - a->z_expandable = exp; - - return parse_zlib(a, parse_header); -} - -char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) -{ - zbuf a; - char *p = (char *) malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (uint8 *) buffer; - a.zbuffer_end = (uint8 *) buffer + len; - if (do_zlib(&a, p, initial_size, 1, 1)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - free(a.zout_start); - return NULL; - } -} - -char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) -{ - return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); -} - -int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) -{ - zbuf a; - a.zbuffer = (uint8 *) ibuffer; - a.zbuffer_end = (uint8 *) ibuffer + ilen; - if (do_zlib(&a, obuffer, olen, 0, 1)) - return (int) (a.zout - a.zout_start); - else - return -1; -} - -char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) -{ - zbuf a; - char *p = (char *) malloc(16384); - if (p == NULL) return NULL; - a.zbuffer = (uint8 *) buffer; - a.zbuffer_end = (uint8 *) buffer+len; - if (do_zlib(&a, p, 16384, 1, 0)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - free(a.zout_start); - return NULL; - } -} - -int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) -{ - zbuf a; - a.zbuffer = (uint8 *) ibuffer; - a.zbuffer_end = (uint8 *) ibuffer + ilen; - if (do_zlib(&a, obuffer, olen, 0, 0)) - return (int) (a.zout - a.zout_start); - else - return -1; -} - -// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 -// simple implementation -// - only 8-bit samples -// - no CRC checking -// - allocates lots of intermediate memory -// - avoids problem of streaming data between subsystems -// - avoids explicit window management -// performance -// - uses stb_zlib, a PD zlib implementation with fast huffman decoding - - -typedef struct -{ - uint32 length; - uint32 type; -} chunk; - -#define PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) - -static chunk get_chunk_header(stbi *s) -{ - chunk c; - c.length = get32(s); - c.type = get32(s); - return c; -} - -static int check_png_header(stbi *s) -{ - static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 }; - int i; - for (i=0; i < 8; ++i) - if (get8(s) != png_sig[i]) return e("bad png sig","Not a PNG"); - return 1; -} - -typedef struct -{ - stbi s; - uint8 *idata, *expanded, *out; -} png; - - -enum { - F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4, - F_avg_first, F_paeth_first, -}; - -static uint8 first_row_filter[5] = -{ - F_none, F_sub, F_none, F_avg_first, F_paeth_first -}; - -static int paeth(int a, int b, int c) -{ - int p = a + b - c; - int pa = abs(p-a); - int pb = abs(p-b); - int pc = abs(p-c); - if (pa <= pb && pa <= pc) return a; - if (pb <= pc) return b; - return c; -} - -// create the png data from post-deflated data -static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) -{ - stbi *s = &a->s; - uint32 i,j,stride = x*out_n; - int k; - int img_n = s->img_n; // copy it into a local for later - assert(out_n == s->img_n || out_n == s->img_n+1); - if (stbi_png_partial) y = 1; - a->out = (uint8 *) malloc(x * y * out_n); - if (!a->out) return e("outofmem", "Out of memory"); - if (!stbi_png_partial) { - if (s->img_x == x && s->img_y == y) - if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); - else // interlaced: - if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); - } - for (j=0; j < y; ++j) { - uint8 *cur = a->out + stride*j; - uint8 *prior = cur - stride; - int filter = *raw++; - if (filter > 4) return e("invalid filter","Corrupt PNG"); - // if first row, use special filter that doesn't sample previous row - if (j == 0) filter = first_row_filter[filter]; - // handle first pixel explicitly - for (k=0; k < img_n; ++k) { - switch(filter) { - case F_none : cur[k] = raw[k]; break; - case F_sub : cur[k] = raw[k]; break; - case F_up : cur[k] = raw[k] + prior[k]; break; - case F_avg : cur[k] = raw[k] + (prior[k]>>1); break; - case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break; - case F_avg_first : cur[k] = raw[k]; break; - case F_paeth_first: cur[k] = raw[k]; break; - } - } - if (img_n != out_n) cur[img_n] = 255; - raw += img_n; - cur += out_n; - prior += out_n; - // this is a little gross, so that we don't switch per-pixel or per-component - if (img_n == out_n) { - #define CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ - for (k=0; k < img_n; ++k) - switch(filter) { - CASE(F_none) cur[k] = raw[k]; break; - CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break; - CASE(F_up) cur[k] = raw[k] + prior[k]; break; - CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break; - CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break; - CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break; - CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break; - } - #undef CASE - } else { - assert(img_n+1 == out_n); - #define CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ - for (k=0; k < img_n; ++k) - switch(filter) { - CASE(F_none) cur[k] = raw[k]; break; - CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break; - CASE(F_up) cur[k] = raw[k] + prior[k]; break; - CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break; - CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; - CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break; - CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break; - } - #undef CASE - } - } - return 1; -} - -static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) -{ - uint8 *final; - int p; - int save; - if (!interlaced) - return create_png_image_raw(a, raw, raw_len, out_n, a->s.img_x, a->s.img_y); - save = stbi_png_partial; - stbi_png_partial = 0; - - // de-interlacing - final = (uint8 *) malloc(a->s.img_x * a->s.img_y * out_n); - for (p=0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; - int xspc[] = { 8,8,4,4,2,2,1 }; - int yspc[] = { 8,8,8,4,4,2,2 }; - int i,j,x,y; - // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 - x = (a->s.img_x - xorig[p] + xspc[p]-1) / xspc[p]; - y = (a->s.img_y - yorig[p] + yspc[p]-1) / yspc[p]; - if (x && y) { - if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { - free(final); - return 0; - } - for (j=0; j < y; ++j) - for (i=0; i < x; ++i) - memcpy(final + (j*yspc[p]+yorig[p])*a->s.img_x*out_n + (i*xspc[p]+xorig[p])*out_n, - a->out + (j*x+i)*out_n, out_n); - free(a->out); - raw += (x*out_n+1)*y; - raw_len -= (x*out_n+1)*y; - } - } - a->out = final; - - stbi_png_partial = save; - return 1; -} - -static int compute_transparency(png *z, uint8 tc[3], int out_n) -{ - stbi *s = &z->s; - uint32 i, pixel_count = s->img_x * s->img_y; - uint8 *p = z->out; - - // compute color-based transparency, assuming we've - // already got 255 as the alpha value in the output - assert(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i=0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 255); - p += 2; - } - } else { - for (i=0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) -{ - uint32 i, pixel_count = a->s.img_x * a->s.img_y; - uint8 *p, *temp_out, *orig = a->out; - - p = (uint8 *) malloc(pixel_count * pal_img_n); - if (p == NULL) return e("outofmem", "Out of memory"); - - // between here and free(out) below, exitting would leak - temp_out = p; - - if (pal_img_n == 3) { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p += 3; - } - } else { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p[3] = palette[n+3]; - p += 4; - } - } - free(a->out); - a->out = temp_out; - return 1; -} - -static int parse_png_file(png *z, int scan, int req_comp) -{ - uint8 palette[1024], pal_img_n=0; - uint8 has_trans=0, tc[3]; - uint32 ioff=0, idata_limit=0, i, pal_len=0; - int first=1,k,interlace=0; - stbi *s = &z->s; - - if (!check_png_header(s)) return 0; - - if (scan == SCAN_type) return 1; - - for(;;first=0) { - chunk c = get_chunk_header(s); - if (first && c.type != PNG_TYPE('I','H','D','R')) - return e("first not IHDR","Corrupt PNG"); - switch (c.type) { - case PNG_TYPE('I','H','D','R'): { - int depth,color,comp,filter; - if (!first) return e("multiple IHDR","Corrupt PNG"); - if (c.length != 13) return e("bad IHDR len","Corrupt PNG"); - s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)"); - s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)"); - depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only"); - color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG"); - if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG"); - comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG"); - filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG"); - interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG"); - if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG"); - if (!pal_img_n) { - s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); - if (scan == SCAN_header) return 1; - } else { - // if paletted, then pal_n is our final components, and - // img_n is # components to decompress/filter. - s->img_n = 1; - if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG"); - // if SCAN_header, have to scan to see if we have a tRNS - } - break; - } - - case PNG_TYPE('P','L','T','E'): { - if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG"); - pal_len = c.length / 3; - if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG"); - for (i=0; i < pal_len; ++i) { - palette[i*4+0] = get8u(s); - palette[i*4+1] = get8u(s); - palette[i*4+2] = get8u(s); - palette[i*4+3] = 255; - } - break; - } - - case PNG_TYPE('t','R','N','S'): { - if (z->idata) return e("tRNS after IDAT","Corrupt PNG"); - if (pal_img_n) { - if (scan == SCAN_header) { s->img_n = 4; return 1; } - if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG"); - if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG"); - pal_img_n = 4; - for (i=0; i < c.length; ++i) - palette[i*4+3] = get8u(s); - } else { - if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG"); - if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG"); - has_trans = 1; - for (k=0; k < s->img_n; ++k) - tc[k] = (uint8) get16(s); // non 8-bit images will be larger - } - break; - } - - case PNG_TYPE('I','D','A','T'): { - if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG"); - if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; } - if (ioff + c.length > idata_limit) { - uint8 *p; - if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; - while (ioff + c.length > idata_limit) - idata_limit *= 2; - p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL) return e("outofmem", "Out of memory"); - z->idata = p; - } - #ifndef STBI_NO_STDIO - if (s->img_file) - { - if (fread(z->idata+ioff,1,c.length,s->img_file) != c.length) return e("outofdata","Corrupt PNG"); - } - else - #endif - { - memcpy(z->idata+ioff, s->img_buffer, c.length); - s->img_buffer += c.length; - } - ioff += c.length; - break; - } - - case PNG_TYPE('I','E','N','D'): { - uint32 raw_len; - if (scan != SCAN_load) return 1; - if (z->idata == NULL) return e("no IDAT","Corrupt PNG"); - z->expanded = (uint8 *) stbi_zlib_decode_malloc((char *) z->idata, ioff, (int *) &raw_len); - if (z->expanded == NULL) return 0; // zlib should set error - free(z->idata); z->idata = NULL; - if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) - s->img_out_n = s->img_n+1; - else - s->img_out_n = s->img_n; - if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; - if (has_trans) - if (!compute_transparency(z, tc, s->img_out_n)) return 0; - if (pal_img_n) { - // pal_img_n == 3 or 4 - s->img_n = pal_img_n; // record the actual colors we had - s->img_out_n = pal_img_n; - if (req_comp >= 3) s->img_out_n = req_comp; - if (!expand_palette(z, palette, pal_len, s->img_out_n)) - return 0; - } - free(z->expanded); z->expanded = NULL; - return 1; - } - - default: - // if critical, fail - if ((c.type & (1 << 29)) == 0) { - #ifndef STBI_NO_FAILURE_STRINGS - // not threadsafe - static char invalid_chunk[] = "XXXX chunk not known"; - invalid_chunk[0] = (uint8) (c.type >> 24); - invalid_chunk[1] = (uint8) (c.type >> 16); - invalid_chunk[2] = (uint8) (c.type >> 8); - invalid_chunk[3] = (uint8) (c.type >> 0); - #endif - return e(invalid_chunk, "PNG not supported: unknown chunk type"); - } - skip(s, c.length); - break; - } - // end of chunk, read and skip CRC - get32(s); - } -} - -static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp) -{ - unsigned char *result=NULL; - p->expanded = NULL; - p->idata = NULL; - p->out = NULL; - if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); - if (parse_png_file(p, SCAN_load, req_comp)) { - result = p->out; - p->out = NULL; - if (req_comp && req_comp != p->s.img_out_n) { - result = convert_format(result, p->s.img_out_n, req_comp, p->s.img_x, p->s.img_y); - p->s.img_out_n = req_comp; - if (result == NULL) return result; - } - *x = p->s.img_x; - *y = p->s.img_y; - if (n) *n = p->s.img_n; - } - free(p->out); p->out = NULL; - free(p->expanded); p->expanded = NULL; - free(p->idata); p->idata = NULL; - - return result; -} - -#ifndef STBI_NO_STDIO -unsigned char *stbi_png_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - png p; - start_file(&p.s, f); - return do_png(&p, x,y,comp,req_comp); -} - -unsigned char *stbi_png_load(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *data; - FILE *f = fopen(filename, "rb"); - if (!f) return NULL; - data = stbi_png_load_from_file(f,x,y,comp,req_comp); - fclose(f); - return data; -} -#endif - -unsigned char *stbi_png_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - png p; - start_mem(&p.s, buffer,len); - return do_png(&p, x,y,comp,req_comp); -} - -#ifndef STBI_NO_STDIO -int stbi_png_test_file(FILE *f) -{ - png p; - int n,r; - n = ftell(f); - start_file(&p.s, f); - r = parse_png_file(&p, SCAN_type,STBI_default); - fseek(f,n,SEEK_SET); - return r; -} -#endif - -int stbi_png_test_memory(stbi_uc const *buffer, int len) -{ - png p; - start_mem(&p.s, buffer, len); - return parse_png_file(&p, SCAN_type,STBI_default); -} - -// TODO: load header from png -#ifndef STBI_NO_STDIO -int stbi_png_info (char const *filename, int *x, int *y, int *comp) -{ - png p; - FILE *f = fopen(filename, "rb"); - if (!f) return 0; - start_file(&p.s, f); - if (parse_png_file(&p, SCAN_header, 0)) { - if(x) *x = p.s.img_x; - if(y) *y = p.s.img_y; - if (comp) *comp = p.s.img_n; - fclose(f); - return 1; - } - fclose(f); - return 0; -} - -extern int stbi_png_info_from_file (FILE *f, int *x, int *y, int *comp); -#endif -extern int stbi_png_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp); - -// Microsoft/Windows BMP image - -static int bmp_test(stbi *s) -{ - int sz; - if (get8(s) != 'B') return 0; - if (get8(s) != 'M') return 0; - get32le(s); // discard filesize - get16le(s); // discard reserved - get16le(s); // discard reserved - get32le(s); // discard data offset - sz = get32le(s); - if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; - return 0; -} - -#ifndef STBI_NO_STDIO -int stbi_bmp_test_file (FILE *f) -{ - stbi s; - int r,n = ftell(f); - start_file(&s,f); - r = bmp_test(&s); - fseek(f,n,SEEK_SET); - return r; -} -#endif - -int stbi_bmp_test_memory (stbi_uc const *buffer, int len) -{ - stbi s; - start_mem(&s, buffer, len); - return bmp_test(&s); -} - -// returns 0..31 for the highest set bit -static int high_bit(unsigned int z) -{ - int n=0; - if (z == 0) return -1; - if (z >= 0x10000) n += 16, z >>= 16; - if (z >= 0x00100) n += 8, z >>= 8; - if (z >= 0x00010) n += 4, z >>= 4; - if (z >= 0x00004) n += 2, z >>= 2; - if (z >= 0x00002) n += 1, z >>= 1; - return n; -} - -static int bitcount(unsigned int a) -{ - a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 - a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits - a = (a + (a >> 8)); // max 16 per 8 bits - a = (a + (a >> 16)); // max 32 per 8 bits - return a & 0xff; -} - -static int shiftsigned(int v, int shift, int bits) -{ - int result; - int z=0; - - if (shift < 0) v <<= -shift; - else v >>= shift; - result = v; - - z = bits; - while (z < 8) { - result += v >> z; - z += bits; - } - return result; -} - -static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) -{ - uint8 *out; - unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0; - stbi_uc pal[256][4]; - int psize=0,i,j,compress=0,width; - int bpp, flip_vertically, pad, target, offset, hsz; - if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP"); - get32le(s); // discard filesize - get16le(s); // discard reserved - get16le(s); // discard reserved - offset = get32le(s); - hsz = get32le(s); - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown"); - failure_reason = "bad BMP"; - if (hsz == 12) { - s->img_x = get16le(s); - s->img_y = get16le(s); - } else { - s->img_x = get32le(s); - s->img_y = get32le(s); - } - if (get16le(s) != 1) return 0; - bpp = get16le(s); - if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit"); - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); - if (hsz == 12) { - if (bpp < 24) - psize = (offset - 14 - 24) / 3; - } else { - compress = get32le(s); - if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE"); - get32le(s); // discard sizeof - get32le(s); // discard hres - get32le(s); // discard vres - get32le(s); // discard colorsused - get32le(s); // discard max important - if (hsz == 40 || hsz == 56) { - if (hsz == 56) { - get32le(s); - get32le(s); - get32le(s); - get32le(s); - } - if (bpp == 16 || bpp == 32) { - mr = mg = mb = 0; - if (compress == 0) { - if (bpp == 32) { - mr = 0xff << 16; - mg = 0xff << 8; - mb = 0xff << 0; - ma = 0xff << 24; - fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 - } else { - mr = 31 << 10; - mg = 31 << 5; - mb = 31 << 0; - } - } else if (compress == 3) { - mr = get32le(s); - mg = get32le(s); - mb = get32le(s); - // not documented, but generated by photoshop and handled by mspaint - if (mr == mg && mg == mb) { - // ?!?!? - return NULL; - } - } else - return NULL; - } - } else { - assert(hsz == 108); - mr = get32le(s); - mg = get32le(s); - mb = get32le(s); - ma = get32le(s); - get32le(s); // discard color space - for (i=0; i < 12; ++i) - get32le(s); // discard color space parameters - } - if (bpp < 16) - psize = (offset - 14 - hsz) >> 2; - } - s->img_n = ma ? 4 : 3; - if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 - target = req_comp; - else - target = s->img_n; // if they want monochrome, we'll post-convert - out = (stbi_uc *) malloc(target * s->img_x * s->img_y); - if (!out) return epuc("outofmem", "Out of memory"); - if (bpp < 16) { - int z=0; - if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); } - for (i=0; i < psize; ++i) { - pal[i][2] = get8(s); - pal[i][1] = get8(s); - pal[i][0] = get8(s); - if (hsz != 12) get8(s); - pal[i][3] = 255; - } - skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); - if (bpp == 4) width = (s->img_x + 1) >> 1; - else if (bpp == 8) width = s->img_x; - else { free(out); return epuc("bad bpp", "Corrupt BMP"); } - pad = (-width)&3; - for (j=0; j < (int) s->img_y; ++j) { - for (i=0; i < (int) s->img_x; i += 2) { - int v=get8(s),v2=0; - if (bpp == 4) { - v2 = v & 15; - v >>= 4; - } - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - v = (bpp == 8) ? get8(s) : v2; - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - } - skip(s, pad); - } - } else { - int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; - int z = 0; - int easy=0; - skip(s, offset - 14 - hsz); - if (bpp == 24) width = 3 * s->img_x; - else if (bpp == 16) width = 2*s->img_x; - else /* bpp = 32 and pad = 0 */ width=0; - pad = (-width) & 3; - if (bpp == 24) { - easy = 1; - } else if (bpp == 32) { - if (mb == 0xff && mg == 0xff00 && mr == 0xff000000 && ma == 0xff000000) - easy = 2; - } - if (!easy) { - if (!mr || !mg || !mb) return epuc("bad masks", "Corrupt BMP"); - // right shift amt to put high bit in position #7 - rshift = high_bit(mr)-7; rcount = bitcount(mr); - gshift = high_bit(mg)-7; gcount = bitcount(mr); - bshift = high_bit(mb)-7; bcount = bitcount(mr); - ashift = high_bit(ma)-7; acount = bitcount(mr); - } - for (j=0; j < (int) s->img_y; ++j) { - if (easy) { - for (i=0; i < (int) s->img_x; ++i) { - int a; - out[z+2] = get8(s); - out[z+1] = get8(s); - out[z+0] = get8(s); - z += 3; - a = (easy == 2 ? get8(s) : 255); - if (target == 4) out[z++] = a; - } - } else { - for (i=0; i < (int) s->img_x; ++i) { - uint32 v = (bpp == 16 ? get16le(s) : get32le(s)); - int a; - out[z++] = shiftsigned(v & mr, rshift, rcount); - out[z++] = shiftsigned(v & mg, gshift, gcount); - out[z++] = shiftsigned(v & mb, bshift, bcount); - a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); - if (target == 4) out[z++] = a; - } - } - skip(s, pad); - } - } - if (flip_vertically) { - stbi_uc t; - for (j=0; j < (int) s->img_y>>1; ++j) { - stbi_uc *p1 = out + j *s->img_x*target; - stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; - for (i=0; i < (int) s->img_x*target; ++i) { - t = p1[i], p1[i] = p2[i], p2[i] = t; - } - } - } - - if (req_comp && req_comp != target) { - out = convert_format(out, target, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // convert_format frees input on failure - } - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = target; - return out; -} - -#ifndef STBI_NO_STDIO -stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp) -{ - stbi_uc *data; - FILE *f = fopen(filename, "rb"); - if (!f) return NULL; - data = stbi_bmp_load_from_file(f, x,y,comp,req_comp); - fclose(f); - return data; -} - -stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_file(&s, f); - return bmp_load(&s, x,y,comp,req_comp); -} -#endif - -stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_mem(&s, buffer, len); - return bmp_load(&s, x,y,comp,req_comp); -} - -// Targa Truevision - TGA -// by Jonathan Dummer - -static int tga_test(stbi *s) -{ - int sz; - get8u(s); // discard Offset - sz = get8u(s); // color type - if( sz > 1 ) return 0; // only RGB or indexed allowed - sz = get8u(s); // image type - if( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE - get16(s); // discard palette start - get16(s); // discard palette length - get8(s); // discard bits per palette color entry - get16(s); // discard x origin - get16(s); // discard y origin - if( get16(s) < 1 ) return 0; // test width - if( get16(s) < 1 ) return 0; // test height - sz = get8(s); // bits per pixel - if( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) return 0; // only RGB or RGBA or grey allowed - return 1; // seems to have passed everything -} - -#ifndef STBI_NO_STDIO -int stbi_tga_test_file (FILE *f) -{ - stbi s; - int r,n = ftell(f); - start_file(&s, f); - r = tga_test(&s); - fseek(f,n,SEEK_SET); - return r; -} -#endif - -int stbi_tga_test_memory (stbi_uc const *buffer, int len) -{ - stbi s; - start_mem(&s, buffer, len); - return tga_test(&s); -} - -static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) -{ - // read in the TGA header stuff - int tga_offset = get8u(s); - int tga_indexed = get8u(s); - int tga_image_type = get8u(s); - int tga_is_RLE = 0; - int tga_palette_start = get16le(s); - int tga_palette_len = get16le(s); - int tga_palette_bits = get8u(s); - int tga_x_origin = get16le(s); - int tga_y_origin = get16le(s); - int tga_width = get16le(s); - int tga_height = get16le(s); - int tga_bits_per_pixel = get8u(s); - int tga_inverted = get8u(s); - // image data - unsigned char *tga_data; - unsigned char *tga_palette = NULL; - int i, j; - unsigned char raw_data[4]; - unsigned char trans_data[4]; - int RLE_count = 0; - int RLE_repeating = 0; - int read_next_pixel = 1; - // do a tiny bit of precessing - if( tga_image_type >= 8 ) - { - tga_image_type -= 8; - tga_is_RLE = 1; - } - /* int tga_alpha_bits = tga_inverted & 15; */ - tga_inverted = 1 - ((tga_inverted >> 5) & 1); - - // error check - if( //(tga_indexed) || - (tga_width < 1) || (tga_height < 1) || - (tga_image_type < 1) || (tga_image_type > 3) || - ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && - (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) - ) - { - return NULL; - } - - // If I'm paletted, then I'll use the number of bits from the palette - if( tga_indexed ) - { - tga_bits_per_pixel = tga_palette_bits; - } - - // tga info - *x = tga_width; - *y = tga_height; - if( (req_comp < 1) || (req_comp > 4) ) - { - // just use whatever the file was - req_comp = tga_bits_per_pixel / 8; - *comp = req_comp; - } else - { - // force a new number of components - *comp = tga_bits_per_pixel/8; - } - tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp ); - - // skip to the data's starting position (offset usually = 0) - skip(s, tga_offset ); - // do I need to load a palette? - if( tga_indexed ) - { - // any data to skip? (offset usually = 0) - skip(s, tga_palette_start ); - // load the palette - tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 ); - getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 ); - } - // load the data - for( i = 0; i < tga_width * tga_height; ++i ) - { - // if I'm in RLE mode, do I need to get a RLE chunk? - if( tga_is_RLE ) - { - if( RLE_count == 0 ) - { - // yep, get the next byte as a RLE command - int RLE_cmd = get8u(s); - RLE_count = 1 + (RLE_cmd & 127); - RLE_repeating = RLE_cmd >> 7; - read_next_pixel = 1; - } else if( !RLE_repeating ) - { - read_next_pixel = 1; - } - } else - { - read_next_pixel = 1; - } - // OK, if I need to read a pixel, do it now - if( read_next_pixel ) - { - // load however much data we did have - if( tga_indexed ) - { - // read in 1 byte, then perform the lookup - int pal_idx = get8u(s); - if( pal_idx >= tga_palette_len ) - { - // invalid index - pal_idx = 0; - } - pal_idx *= tga_bits_per_pixel / 8; - for( j = 0; j*8 < tga_bits_per_pixel; ++j ) - { - raw_data[j] = tga_palette[pal_idx+j]; - } - } else - { - // read in the data raw - for( j = 0; j*8 < tga_bits_per_pixel; ++j ) - { - raw_data[j] = get8u(s); - } - } - // convert raw to the intermediate format - switch( tga_bits_per_pixel ) - { - case 8: - // Luminous => RGBA - trans_data[0] = raw_data[0]; - trans_data[1] = raw_data[0]; - trans_data[2] = raw_data[0]; - trans_data[3] = 255; - break; - case 16: - // Luminous,Alpha => RGBA - trans_data[0] = raw_data[0]; - trans_data[1] = raw_data[0]; - trans_data[2] = raw_data[0]; - trans_data[3] = raw_data[1]; - break; - case 24: - // BGR => RGBA - trans_data[0] = raw_data[2]; - trans_data[1] = raw_data[1]; - trans_data[2] = raw_data[0]; - trans_data[3] = 255; - break; - case 32: - // BGRA => RGBA - trans_data[0] = raw_data[2]; - trans_data[1] = raw_data[1]; - trans_data[2] = raw_data[0]; - trans_data[3] = raw_data[3]; - break; - } - // clear the reading flag for the next pixel - read_next_pixel = 0; - } // end of reading a pixel - // convert to final format - switch( req_comp ) - { - case 1: - // RGBA => Luminance - tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); - break; - case 2: - // RGBA => Luminance,Alpha - tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); - tga_data[i*req_comp+1] = trans_data[3]; - break; - case 3: - // RGBA => RGB - tga_data[i*req_comp+0] = trans_data[0]; - tga_data[i*req_comp+1] = trans_data[1]; - tga_data[i*req_comp+2] = trans_data[2]; - break; - case 4: - // RGBA => RGBA - tga_data[i*req_comp+0] = trans_data[0]; - tga_data[i*req_comp+1] = trans_data[1]; - tga_data[i*req_comp+2] = trans_data[2]; - tga_data[i*req_comp+3] = trans_data[3]; - break; - } - // in case we're in RLE mode, keep counting down - --RLE_count; - } - // do I need to invert the image? - if( tga_inverted ) - { - for( j = 0; j*2 < tga_height; ++j ) - { - int index1 = j * tga_width * req_comp; - int index2 = (tga_height - 1 - j) * tga_width * req_comp; - for( i = tga_width * req_comp; i > 0; --i ) - { - unsigned char temp = tga_data[index1]; - tga_data[index1] = tga_data[index2]; - tga_data[index2] = temp; - ++index1; - ++index2; - } - } - } - // clear my palette, if I had one - if( tga_palette != NULL ) - { - free( tga_palette ); - } - // the things I do to get rid of an error message, and yet keep - // Microsoft's C compilers happy... [8^( - tga_palette_start = tga_palette_len = tga_palette_bits = - tga_x_origin = tga_y_origin = 0; - // OK, done - return tga_data; -} - -#ifndef STBI_NO_STDIO -stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp) -{ - stbi_uc *data; - FILE *f = fopen(filename, "rb"); - if (!f) return NULL; - data = stbi_tga_load_from_file(f, x,y,comp,req_comp); - fclose(f); - return data; -} - -stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_file(&s, f); - return tga_load(&s, x,y,comp,req_comp); -} -#endif - -stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_mem(&s, buffer, len); - return tga_load(&s, x,y,comp,req_comp); -} - - -// ************************************************************************************************* -// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicholas Schulz, tweaked by STB - -static int psd_test(stbi *s) -{ - if (get32(s) != 0x38425053) return 0; // "8BPS" - else return 1; -} - -#ifndef STBI_NO_STDIO -int stbi_psd_test_file(FILE *f) -{ - stbi s; - int r,n = ftell(f); - start_file(&s, f); - r = psd_test(&s); - fseek(f,n,SEEK_SET); - return r; -} -#endif - -int stbi_psd_test_memory(stbi_uc const *buffer, int len) -{ - stbi s; - start_mem(&s, buffer, len); - return psd_test(&s); -} - -static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) -{ - int pixelCount; - int channelCount, compression; - int channel, i, count, len; - int w,h; - uint8 *out; - - // Check identifier - if (get32(s) != 0x38425053) // "8BPS" - return epuc("not PSD", "Corrupt PSD image"); - - // Check file type version. - if (get16(s) != 1) - return epuc("wrong version", "Unsupported version of PSD image"); - - // Skip 6 reserved bytes. - skip(s, 6 ); - - // Read the number of channels (R, G, B, A, etc). - channelCount = get16(s); - if (channelCount < 0 || channelCount > 16) - return epuc("wrong channel count", "Unsupported number of channels in PSD image"); - - // Read the rows and columns of the image. - h = get32(s); - w = get32(s); - - // Make sure the depth is 8 bits. - if (get16(s) != 8) - return epuc("unsupported bit depth", "PSD bit depth is not 8 bit"); - - // Make sure the color mode is RGB. - // Valid options are: - // 0: Bitmap - // 1: Grayscale - // 2: Indexed color - // 3: RGB color - // 4: CMYK color - // 7: Multichannel - // 8: Duotone - // 9: Lab color - if (get16(s) != 3) - return epuc("wrong color format", "PSD is not in RGB color format"); - - // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) - skip(s,get32(s) ); - - // Skip the image resources. (resolution, pen tool paths, etc) - skip(s, get32(s) ); - - // Skip the reserved data. - skip(s, get32(s) ); - - // Find out if the data is compressed. - // Known values: - // 0: no compression - // 1: RLE compressed - compression = get16(s); - if (compression > 1) - return epuc("bad compression", "PSD has an unknown compression format"); - - // Create the destination image. - out = (stbi_uc *) malloc(4 * w*h); - if (!out) return epuc("outofmem", "Out of memory"); - pixelCount = w*h; - - // Initialize the data to zero. - //memset( out, 0, pixelCount * 4 ); - - // Finally, the image data. - if (compression) { - // RLE as used by .PSD and .TIFF - // Loop until you get the number of unpacked bytes you are expecting: - // Read the next source byte into n. - // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. - // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. - // Else if n is 128, noop. - // Endloop - - // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, - // which we're going to just skip. - skip(s, h * channelCount * 2 ); - - // Read the RLE data by channel. - for (channel = 0; channel < 4; channel++) { - uint8 *p; - - p = out+channel; - if (channel >= channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; - } else { - // Read the RLE data. - count = 0; - while (count < pixelCount) { - len = get8(s); - if (len == 128) { - // No-op. - } else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - count += len; - while (len) { - *p = get8(s); - p += 4; - len--; - } - } else if (len > 128) { - uint32 val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len ^= 0x0FF; - len += 2; - val = get8(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } - } - } - } - - } else { - // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit value for each pixel in the image. - - // Read the data by channel. - for (channel = 0; channel < 4; channel++) { - uint8 *p; - - p = out + channel; - if (channel > channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; - } else { - // Read the data. - count = 0; - for (i = 0; i < pixelCount; i++) - *p = get8(s), p += 4; - } - } - } - - if (req_comp && req_comp != 4) { - out = convert_format(out, 4, req_comp, w, h); - if (out == NULL) return out; // convert_format frees input on failure - } - - if (comp) *comp = channelCount; - *y = h; - *x = w; - - return out; -} - -#ifndef STBI_NO_STDIO -stbi_uc *stbi_psd_load(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - stbi_uc *data; - FILE *f = fopen(filename, "rb"); - if (!f) return NULL; - data = stbi_psd_load_from_file(f, x,y,comp,req_comp); - fclose(f); - return data; -} - -stbi_uc *stbi_psd_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_file(&s, f); - return psd_load(&s, x,y,comp,req_comp); -} -#endif - -stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_mem(&s, buffer, len); - return psd_load(&s, x,y,comp,req_comp); -} - - -// ************************************************************************************************* -// Radiance RGBE HDR loader -// originally by Nicolas Schulz -#ifndef STBI_NO_HDR -static int hdr_test(stbi *s) -{ - char *signature = "#?RADIANCE\n"; - int i; - for (i=0; signature[i]; ++i) - if (get8(s) != signature[i]) - return 0; - return 1; -} - -int stbi_hdr_test_memory(stbi_uc const *buffer, int len) -{ - stbi s; - start_mem(&s, buffer, len); - return hdr_test(&s); -} - -#ifndef STBI_NO_STDIO -int stbi_hdr_test_file(FILE *f) -{ - stbi s; - int r,n = ftell(f); - start_file(&s, f); - r = hdr_test(&s); - fseek(f,n,SEEK_SET); - return r; -} -#endif - -#define HDR_BUFLEN 1024 -static char *hdr_gettoken(stbi *z, char *buffer) -{ - int len=0; - char *s = buffer, c = '\0'; - - c = get8(z); - - while (!at_eof(z) && c != '\n') { - buffer[len++] = c; - if (len == HDR_BUFLEN-1) { - // flush to end of line - while (!at_eof(z) && get8(z) != '\n') - ; - break; - } - c = get8(z); - } - - buffer[len] = 0; - return buffer; -} - -static void hdr_convert(float *output, stbi_uc *input, int req_comp) -{ - if( input[3] != 0 ) { - float f1; - // Exponent - f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); - if (req_comp <= 2) - output[0] = (input[0] + input[1] + input[2]) * f1 / 3; - else { - output[0] = input[0] * f1; - output[1] = input[1] * f1; - output[2] = input[2] * f1; - } - if (req_comp == 2) output[1] = 1; - if (req_comp == 4) output[3] = 1; - } else { - switch (req_comp) { - case 4: output[3] = 1; /* fallthrough */ - case 3: output[0] = output[1] = output[2] = 0; - break; - case 2: output[1] = 1; /* fallthrough */ - case 1: output[0] = 0; - break; - } - } -} - - -static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) -{ - char buffer[HDR_BUFLEN]; - char *token; - int valid = 0; - int width, height; - stbi_uc *scanline; - float *hdr_data; - int len; - unsigned char count, value; - int i, j, k, c1,c2, z; - - - // Check identifier - if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) - return epf("not HDR", "Corrupt HDR image"); - - // Parse header - while(1) { - token = hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) return epf("unsupported format", "Unsupported HDR format"); - - // Parse width and height - // can't use sscanf() if we're not using stdio! - token = hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); - token += 3; - height = strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); - token += 3; - width = strtol(token, NULL, 10); - - *x = width; - *y = height; - - *comp = 3; - if (req_comp == 0) req_comp = 3; - - // Read data - hdr_data = (float *) malloc(height * width * req_comp * sizeof(float)); - - // Load image data - // image data is stored as some number of sca - if( width < 8 || width >= 32768) { - // Read flat data - for (j=0; j < height; ++j) { - for (i=0; i < width; ++i) { - stbi_uc rgbe[4]; - main_decode_loop: - getn(s, rgbe, 4); - hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); - } - } - } else { - // Read RLE-encoded data - scanline = NULL; - - for (j = 0; j < height; ++j) { - c1 = get8(s); - c2 = get8(s); - len = get8(s); - if (c1 != 2 || c2 != 2 || (len & 0x80)) { - // not run-length encoded, so we have to actually use THIS data as a decoded - // pixel (note this can't be a valid pixel--one of RGB must be >= 128) - stbi_uc rgbe[4] = { c1,c2,len, get8(s) }; - hdr_convert(hdr_data, rgbe, req_comp); - i = 1; - j = 0; - free(scanline); - goto main_decode_loop; // yes, this is fucking insane; blame the fucking insane format - } - len <<= 8; - len |= get8(s); - if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4); - - for (k = 0; k < 4; ++k) { - i = 0; - while (i < width) { - count = get8(s); - if (count > 128) { - // Run - value = get8(s); - count -= 128; - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = value; - } else { - // Dump - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = get8(s); - } - } - } - for (i=0; i < width; ++i) - hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); - } - free(scanline); - } - - return hdr_data; -} - -#ifndef STBI_NO_STDIO -float *stbi_hdr_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_file(&s,f); - return hdr_load(&s,x,y,comp,req_comp); -} -#endif - -float *stbi_hdr_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi s; - start_mem(&s,buffer, len); - return hdr_load(&s,x,y,comp,req_comp); -} - -#endif // STBI_NO_HDR - -/////////////////////// write image /////////////////////// - -#ifndef STBI_NO_WRITE - -static void write8(FILE *f, int x) { uint8 z = (uint8) x; fwrite(&z,1,1,f); } - -static void writefv(FILE *f, char *fmt, va_list v) -{ - while (*fmt) { - switch (*fmt++) { - case ' ': break; - case '1': { uint8 x = va_arg(v, int); write8(f,x); break; } - case '2': { int16 x = va_arg(v, int); write8(f,x); write8(f,x>>8); break; } - case '4': { int32 x = va_arg(v, int); write8(f,x); write8(f,x>>8); write8(f,x>>16); write8(f,x>>24); break; } - default: - assert(0); - va_end(v); - return; - } - } -} - -static void writef(FILE *f, char *fmt, ...) -{ - va_list v; - va_start(v, fmt); - writefv(f,fmt,v); - va_end(v); -} - -static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad) -{ - uint8 bg[3] = { 255, 0, 255}, px[3]; - uint32 zero = 0; - int i,j,k, j_end; - - if (vdir < 0) - j_end = -1, j = y-1; - else - j_end = y, j = 0; - - for (; j != j_end; j += vdir) { - for (i=0; i < x; ++i) { - uint8 *d = (uint8 *) data + (j*x+i)*comp; - if (write_alpha < 0) - fwrite(&d[comp-1], 1, 1, f); - switch (comp) { - case 1: - case 2: writef(f, "111", d[0],d[0],d[0]); - break; - case 4: - if (!write_alpha) { - for (k=0; k < 3; ++k) - px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255; - writef(f, "111", px[1-rgb_dir],px[1],px[1+rgb_dir]); - break; - } - /* FALLTHROUGH */ - case 3: - writef(f, "111", d[1-rgb_dir],d[1],d[1+rgb_dir]); - break; - } - if (write_alpha > 0) - fwrite(&d[comp-1], 1, 1, f); - } - fwrite(&zero,scanline_pad,1,f); - } -} - -static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, char *fmt, ...) -{ - FILE *f = fopen(filename, "wb"); - if (f) { - va_list v; - va_start(v, fmt); - writefv(f, fmt, v); - va_end(v); - write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad); - fclose(f); - } - return f != NULL; -} - -int stbi_write_bmp(char const *filename, int x, int y, int comp, void *data) -{ - int pad = (-x*3) & 3; - return outfile(filename,-1,-1,x,y,comp,data,0,pad, - "11 4 22 4" "4 44 22 444444", - 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header - 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header -} - -int stbi_write_tga(char const *filename, int x, int y, int comp, void *data) -{ - int has_alpha = !(comp & 1); - return outfile(filename, -1,-1, x, y, comp, data, has_alpha, 0, - "111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha); -} - -// any other image formats that do interleaved rgb data? -// PNG: requires adler32,crc32 -- significant amount of code -// PSD: no, channels output separately -// TIFF: no, stripwise-interleaved... i think - -#endif // STBI_NO_WRITE - -#endif // STBI_HEADER_FILE_ONLY - diff --git a/clutter/cogl/cogl/tesselator/GL/glu.h b/clutter/cogl/cogl/tesselator/GL/glu.h deleted file mode 100644 index 026ca5a..0000000 --- a/clutter/cogl/cogl/tesselator/GL/glu.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -/* This is just a wrapper to use our simplified version of glu.h so - that the tesselator code can still #include */ - -#include "../tesselator.h" - -/* These aren't defined on GLES and we don't really want the - tesselator code to use them but we're also trying to avoid - modifying the C files so we just force them to be empty here */ - -#undef GLAPI -#define GLAPI - -#undef GLAPIENTRY -#define GLAPIENTRY - -/* GLES doesn't define a GLdouble type so lets just force it to a - regular double */ -#define GLdouble double diff --git a/clutter/cogl/cogl/tesselator/README b/clutter/cogl/cogl/tesselator/README deleted file mode 100644 index 66a6011..0000000 --- a/clutter/cogl/cogl/tesselator/README +++ /dev/null @@ -1,446 +0,0 @@ -/* -*/ - -General Polygon Tesselation ---------------------------- - - This note describes a tesselator for polygons consisting of one or - more closed contours. It is backward-compatible with the current - OpenGL Utilities tesselator, and is intended to replace it. Here is - a summary of the major differences: - - - input contours can be intersecting, self-intersecting, or degenerate. - - - supports a choice of several winding rules for determining which parts - of the polygon are on the "interior". This makes it possible to do - CSG operations on polygons. - - - boundary extraction: instead of tesselating the polygon, returns a - set of closed contours which separate the interior from the exterior. - - - returns the output as a small number of triangle fans and strips, - rather than a list of independent triangles (when possible). - - - output is available as an explicit mesh (a quad-edge structure), - in addition to the normal callback interface. - - - the algorithm used is extremely robust. - - -The interface -------------- - - The tesselator state is maintained in a "tesselator object". - These are allocated and destroyed using - - GLUtesselator *gluNewTess( void ); - void gluDeleteTess( GLUtesselator *tess ); - - Several tesselator objects may be used simultaneously. - - Inputs - ------ - - The input contours are specified with the following routines: - - void gluTessBeginPolygon( GLUtesselator *tess ); - void gluTessBeginContour( GLUtesselator *tess ); - void gluTessVertex( GLUtesselator *tess, GLUcoord coords[3], void *data ); - void gluTessEndContour( GLUtesselator *tess ); - void gluTessEndPolygon( GLUtesselator *tess ); - - Within each BeginPolygon/EndPolygon pair, there can be zero or more - calls to BeginContour/EndContour. Within each contour, there are zero - or more calls to gluTessVertex(). The vertices specify a closed - contour (the last vertex of each contour is automatically linked to - the first). - - "coords" give the coordinates of the vertex in 3-space. For useful - results, all vertices should lie in some plane, since the vertices - are projected onto a plane before tesselation. "data" is a pointer - to a user-defined vertex structure, which typically contains other - information such as color, texture coordinates, normal, etc. It is - used to refer to the vertex during rendering. - - The library can be compiled in single- or double-precision; the type - GLUcoord represents either "float" or "double" accordingly. The GLU - version will be available in double-precision only. Compile with - GLU_TESS_API_FLOAT defined to get the single-precision version. - - When EndPolygon is called, the tesselation algorithm determines - which regions are interior to the given contours, according to one - of several "winding rules" described below. The interior regions - are then tesselated, and the output is provided as callbacks. - - - Rendering Callbacks - ------------------- - - Callbacks are specified by the client using - - void gluTessCallback( GLUtesselator *tess, GLenum which, void (*fn)()); - - If "fn" is NULL, any previously defined callback is discarded. - - The callbacks used to provide output are: /* which == */ - - void begin( GLenum type ); /* GLU_TESS_BEGIN */ - void edgeFlag( GLboolean flag ); /* GLU_TESS_EDGE_FLAG */ - void vertex( void *data ); /* GLU_TESS_VERTEX */ - void end( void ); /* GLU_TESS_END */ - - Any of the callbacks may be left undefined; if so, the corresponding - information will not be supplied during rendering. - - The "begin" callback indicates the start of a primitive; type is one - of GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES (but see the - notes on "boundary extraction" below). - - It is followed by any number of "vertex" callbacks, which supply the - vertices in the same order as expected by the corresponding glBegin() - call. After the last vertex of a given primitive, there is a callback - to "end". - - If the "edgeFlag" callback is provided, no triangle fans or strips - will be used. When edgeFlag is called, if "flag" is GL_TRUE then each - vertex which follows begins an edge which lies on the polygon boundary - (ie. an edge which separates an interior region from an exterior one). - If "flag" is GL_FALSE, each vertex which follows begins an edge which lies - in the polygon interior. "edgeFlag" will be called before the first - call to "vertex". - - Other Callbacks - --------------- - - void mesh( GLUmesh *mesh ); /* GLU_TESS_MESH */ - - - Returns an explicit mesh, represented using the quad-edge structure - (Guibas/Stolfi '85). Other implementations of this interface might - use a different mesh structure, so this is available only only as an - SGI extension. When the mesh is no longer needed, it should be freed - using - - void gluDeleteMesh( GLUmesh *mesh ); - - There is a brief description of this data structure in the include - file "mesh.h". For the full details, see L. Guibas and J. Stolfi, - Primitives for the manipulation of general subdivisions and the - computation of Voronoi diagrams, ACM Transactions on Graphics, - 4(2):74-123, April 1985. For an introduction, see the course notes - for CS348a, "Mathematical Foundations of Computer Graphics", - available at the Stanford bookstore (and taught during the fall - quarter). - - void error( GLenum errno ); /* GLU_TESS_ERROR */ - - - errno is one of GLU_TESS_MISSING_BEGIN_POLYGON, - GLU_TESS_MISSING_END_POLYGON, - GLU_TESS_MISSING_BEGIN_CONTOUR, - GLU_TESS_MISSING_END_CONTOUR, - GLU_TESS_COORD_TOO_LARGE, - GLU_TESS_NEED_COMBINE_CALLBACK - - The first four are obvious. The interface recovers from these - errors by inserting the missing call(s). - - GLU_TESS_COORD_TOO_LARGE says that some vertex coordinate exceeded - the predefined constant GLU_TESS_MAX_COORD in absolute value, and - that the value has been clamped. (Coordinate values must be small - enough so that two can be multiplied together without overflow.) - - GLU_TESS_NEED_COMBINE_CALLBACK says that the algorithm detected an - intersection between two edges in the input data, and the "combine" - callback (below) was not provided. No output will be generated. - - - void combine( GLUcoord coords[3], void *data[4], /* GLU_TESS_COMBINE */ - GLUcoord weight[4], void **outData ); - - - When the algorithm detects an intersection, or wishes to merge - features, it needs to create a new vertex. The vertex is defined - as a linear combination of up to 4 existing vertices, referenced - by data[0..3]. The coefficients of the linear combination are - given by weight[0..3]; these weights always sum to 1.0. All vertex - pointers are valid even when some of the weights are zero. - "coords" gives the location of the new vertex. - - The user must allocate another vertex, interpolate parameters - using "data" and "weights", and return the new vertex pointer in - "outData". This handle is supplied during rendering callbacks. - For example, if the polygon lies in an arbitrary plane in 3-space, - and we associate a color with each vertex, the combine callback might - look like this: - - void myCombine( GLUcoord coords[3], VERTEX *d[4], - GLUcoord w[4], VERTEX **dataOut ) - { - VERTEX *new = new_vertex(); - - new->x = coords[0]; - new->y = coords[1]; - new->z = coords[2]; - new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r; - new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g; - new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b; - new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a; - *dataOut = new; - } - - If the algorithm detects an intersection, then the "combine" callback - must be defined, and must write a non-NULL pointer into "dataOut". - Otherwise the GLU_TESS_NEED_COMBINE_CALLBACK error occurs, and no - output is generated. This is the only error that can occur during - tesselation and rendering. - - - Control over Tesselation - ------------------------ - - void gluTessProperty( GLUtesselator *tess, GLenum which, GLUcoord value ); - - Properties defined: - - - GLU_TESS_WINDING_RULE. Possible values: - - GLU_TESS_WINDING_ODD - GLU_TESS_WINDING_NONZERO - GLU_TESS_WINDING_POSITIVE - GLU_TESS_WINDING_NEGATIVE - GLU_TESS_WINDING_ABS_GEQ_TWO - - The input contours parition the plane into regions. A winding - rule determines which of these regions are inside the polygon. - - For a single contour C, the winding number of a point x is simply - the signed number of revolutions we make around x as we travel - once around C (where CCW is positive). When there are several - contours, the individual winding numbers are summed. This - procedure associates a signed integer value with each point x in - the plane. Note that the winding number is the same for all - points in a single region. - - The winding rule classifies a region as "inside" if its winding - number belongs to the chosen category (odd, nonzero, positive, - negative, or absolute value of at least two). The current GLU - tesselator implements the "odd" rule. The "nonzero" rule is another - common way to define the interior. The other three rules are - useful for polygon CSG operations (see below). - - - GLU_TESS_BOUNDARY_ONLY. Values: TRUE (non-zero) or FALSE (zero). - - If TRUE, returns a set of closed contours which separate the - polygon interior and exterior (rather than a tesselation). - Exterior contours are oriented CCW with respect to the normal, - interior contours are oriented CW. The GLU_TESS_BEGIN callback - uses the type GL_LINE_LOOP for each contour. - - - GLU_TESS_TOLERANCE. Value: a real number between 0.0 and 1.0. - - This specifies a tolerance for merging features to reduce the size - of the output. For example, two vertices which are very close to - each other might be replaced by a single vertex. The tolerance - is multiplied by the largest coordinate magnitude of any input vertex; - this specifies the maximum distance that any feature can move as the - result of a single merge operation. If a single feature takes part - in several merge operations, the total distance moved could be larger. - - Feature merging is completely optional; the tolerance is only a hint. - The implementation is free to merge in some cases and not in others, - or to never merge features at all. The default tolerance is zero. - - The current implementation merges vertices only if they are exactly - coincident, regardless of the current tolerance. A vertex is - spliced into an edge only if the implementation is unable to - distinguish which side of the edge the vertex lies on. - Two edges are merged only when both endpoints are identical. - - - void gluTessNormal( GLUtesselator *tess, - GLUcoord x, GLUcoord y, GLUcoord z ) - - - Lets the user supply the polygon normal, if known. All input data - is projected into a plane perpendicular to the normal before - tesselation. All output triangles are oriented CCW with - respect to the normal (CW orientation can be obtained by - reversing the sign of the supplied normal). For example, if - you know that all polygons lie in the x-y plane, call - "gluTessNormal(tess, 0.0, 0.0, 1.0)" before rendering any polygons. - - - If the supplied normal is (0,0,0) (the default value), the - normal is determined as follows. The direction of the normal, - up to its sign, is found by fitting a plane to the vertices, - without regard to how the vertices are connected. It is - expected that the input data lies approximately in plane; - otherwise projection perpendicular to the computed normal may - substantially change the geometry. The sign of the normal is - chosen so that the sum of the signed areas of all input contours - is non-negative (where a CCW contour has positive area). - - - The supplied normal persists until it is changed by another - call to gluTessNormal. - - - Backward compatibility with the GLU tesselator - ---------------------------------------------- - - The preferred interface is the one described above. The following - routines are obsolete, and are provided only for backward compatibility: - - typedef GLUtesselator GLUtriangulatorObj; /* obsolete name */ - - void gluBeginPolygon( GLUtesselator *tess ); - void gluNextContour( GLUtesselator *tess, GLenum type ); - void gluEndPolygon( GLUtesselator *tess ); - - "type" is one of GLU_EXTERIOR, GLU_INTERIOR, GLU_CCW, GLU_CW, or - GLU_UNKNOWN. It is ignored by the current GLU tesselator. - - GLU_BEGIN, GLU_VERTEX, GLU_END, GLU_ERROR, and GLU_EDGE_FLAG are defined - as synonyms for GLU_TESS_BEGIN, GLU_TESS_VERTEX, GLU_TESS_END, - GLU_TESS_ERROR, and GLU_TESS_EDGE_FLAG. - - -Polygon CSG operations ----------------------- - - The features of the tesselator make it easy to find the union, difference, - or intersection of several polygons. - - First, assume that each polygon is defined so that the winding number - is 0 for each exterior region, and 1 for each interior region. Under - this model, CCW contours define the outer boundary of the polygon, and - CW contours define holes. Contours may be nested, but a nested - contour must be oriented oppositely from the contour that contains it. - - If the original polygons do not satisfy this description, they can be - converted to this form by first running the tesselator with the - GLU_TESS_BOUNDARY_ONLY property turned on. This returns a list of - contours satisfying the restriction above. By allocating two - tesselator objects, the callbacks from one tesselator can be fed - directly to the input of another. - - Given two or more polygons of the form above, CSG operations can be - implemented as follows: - - Union - Draw all the input contours as a single polygon. The winding number - of each resulting region is the number of original polygons - which cover it. The union can be extracted using the - GLU_TESS_WINDING_NONZERO or GLU_TESS_WINDING_POSITIVE winding rules. - Note that with the nonzero rule, we would get the same result if - all contour orientations were reversed. - - Intersection (two polygons at a time only) - Draw a single polygon using the contours from both input polygons. - Extract the result using GLU_TESS_WINDING_ABS_GEQ_TWO. (Since this - winding rule looks at the absolute value, reversing all contour - orientations does not change the result.) - - Difference - - Suppose we want to compute A \ (B union C union D). Draw a single - polygon consisting of the unmodified contours from A, followed by - the contours of B,C,D with the vertex order reversed (this changes - the winding number of the interior regions to -1). To extract the - result, use the GLU_TESS_WINDING_POSITIVE rule. - - If B,C,D are the result of a GLU_TESS_BOUNDARY_ONLY call, an - alternative to reversing the vertex order is to reverse the sign of - the supplied normal. For example in the x-y plane, call - gluTessNormal( tess, 0.0, 0.0, -1.0 ). - - -Performance ------------ - - The tesselator is not intended for immediate-mode rendering; when - possible the output should be cached in a user structure or display - list. General polygon tesselation is an inherently difficult problem, - especially given the goal of extreme robustness. - - The implementation makes an effort to output a small number of fans - and strips; this should improve the rendering performance when the - output is used in a display list. - - Single-contour input polygons are first tested to see whether they can - be rendered as a triangle fan with respect to the first vertex (to - avoid running the full decomposition algorithm on convex polygons). - Non-convex polygons may be rendered by this "fast path" as well, if - the algorithm gets lucky in its choice of a starting vertex. - - For best performance follow these guidelines: - - - supply the polygon normal, if available, using gluTessNormal(). - This represents about 10% of the computation time. For example, - if all polygons lie in the x-y plane, use gluTessNormal(tess,0,0,1). - - - render many polygons using the same tesselator object, rather than - allocating a new tesselator for each one. (In a multi-threaded, - multi-processor environment you may get better performance using - several tesselators.) - - -Comparison with the GLU tesselator ----------------------------------- - - On polygons which make it through the "fast path", the tesselator is - 3 to 5 times faster than the GLU tesselator. - - On polygons which don't make it through the fast path (but which don't - have self-intersections or degeneracies), it is about 2 times slower. - - On polygons with self-intersections or degeneraces, there is nothing - to compare against. - - The new tesselator generates many more fans and strips, reducing the - number of vertices that need to be sent to the hardware. - - Key to the statistics: - - vert number of input vertices on all contours - cntr number of input contours - tri number of triangles in all output primitives - strip number of triangle strips - fan number of triangle fans - ind number of independent triangles - ms number of milliseconds for tesselation - (on a 150MHz R4400 Indy) - - Convex polygon examples: - -New: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.0459 ms -Old: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.149 ms -New: 4 vert, 1 cntr, 2 tri, 0 strip, 1 fan, 0 ind, 0.0459 ms -Old: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.161 ms -New: 36 vert, 1 cntr, 34 tri, 0 strip, 1 fan, 0 ind, 0.153 ms -Old: 36 vert, 1 cntr, 34 tri, 0 strip, 0 fan, 34 ind, 0.621 ms - - Concave single-contour polygons: - -New: 5 vert, 1 cntr, 3 tri, 0 strip, 1 fan, 0 ind, 0.052 ms -Old: 5 vert, 1 cntr, 3 tri, 0 strip, 0 fan, 3 ind, 0.252 ms -New: 19 vert, 1 cntr, 17 tri, 2 strip, 2 fan, 1 ind, 0.911 ms -Old: 19 vert, 1 cntr, 17 tri, 0 strip, 0 fan, 17 ind, 0.529 ms -New: 151 vert, 1 cntr, 149 tri, 13 strip, 18 fan, 3 ind, 6.82 ms -Old: 151 vert, 1 cntr, 149 tri, 0 strip, 3 fan, 143 ind, 2.7 ms -New: 574 vert, 1 cntr, 572 tri, 59 strip, 54 fan, 11 ind, 26.6 ms -Old: 574 vert, 1 cntr, 572 tri, 0 strip, 31 fan, 499 ind, 12.4 ms - - Multiple contours, but no intersections: - -New: 7 vert, 2 cntr, 7 tri, 1 strip, 0 fan, 0 ind, 0.527 ms -Old: 7 vert, 2 cntr, 7 tri, 0 strip, 0 fan, 7 ind, 0.274 ms -New: 81 vert, 6 cntr, 89 tri, 9 strip, 7 fan, 6 ind, 3.88 ms -Old: 81 vert, 6 cntr, 89 tri, 0 strip, 13 fan, 61 ind, 2.2 ms -New: 391 vert, 19 cntr, 413 tri, 37 strip, 32 fan, 26 ind, 20.2 ms -Old: 391 vert, 19 cntr, 413 tri, 0 strip, 25 fan, 363 ind, 8.68 ms - - Self-intersecting and degenerate examples: - -Bowtie: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.483 ms -Star: 5 vert, 1 cntr, 5 tri, 0 strip, 0 fan, 5 ind, 0.91 ms -Random: 24 vert, 7 cntr, 46 tri, 2 strip, 12 fan, 7 ind, 5.32 ms -Font: 333 vert, 2 cntr, 331 tri, 32 strip, 16 fan, 3 ind, 14.1 ms -: 167 vert, 35 cntr, 254 tri, 8 strip, 56 fan, 52 ind, 46.3 ms -: 78 vert, 1 cntr, 2675 tri, 148 strip, 207 fan, 180 ind, 243 ms -: 12480 vert, 2 cntr, 12478 tri, 736 strip,1275 fan, 5 ind, 1010 ms diff --git a/clutter/cogl/cogl/tesselator/dict-list.h b/clutter/cogl/cogl/tesselator/dict-list.h deleted file mode 100644 index 11331a7..0000000 --- a/clutter/cogl/cogl/tesselator/dict-list.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __dict_list_h_ -#define __dict_list_h_ - -/* Use #define's so that another heap implementation can use this one */ - -#define DictKey DictListKey -#define Dict DictList -#define DictNode DictListNode - -#define dictNewDict(frame,leq) __gl_dictListNewDict(frame,leq) -#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict) - -#define dictSearch(dict,key) __gl_dictListSearch(dict,key) -#define dictInsert(dict,key) __gl_dictListInsert(dict,key) -#define dictInsertBefore(dict,node,key) __gl_dictListInsertBefore(dict,node,key) -#define dictDelete(dict,node) __gl_dictListDelete(dict,node) - -#define dictKey(n) __gl_dictListKey(n) -#define dictSucc(n) __gl_dictListSucc(n) -#define dictPred(n) __gl_dictListPred(n) -#define dictMin(d) __gl_dictListMin(d) -#define dictMax(d) __gl_dictListMax(d) - - - -typedef void *DictKey; -typedef struct Dict Dict; -typedef struct DictNode DictNode; - -Dict *dictNewDict( - void *frame, - int (*leq)(void *frame, DictKey key1, DictKey key2) ); - -void dictDeleteDict( Dict *dict ); - -/* Search returns the node with the smallest key greater than or equal - * to the given key. If there is no such key, returns a node whose - * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc. - */ -DictNode *dictSearch( Dict *dict, DictKey key ); -DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key ); -void dictDelete( Dict *dict, DictNode *node ); - -#define __gl_dictListKey(n) ((n)->key) -#define __gl_dictListSucc(n) ((n)->next) -#define __gl_dictListPred(n) ((n)->prev) -#define __gl_dictListMin(d) ((d)->head.next) -#define __gl_dictListMax(d) ((d)->head.prev) -#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k))) - - -/*** Private data structures ***/ - -struct DictNode { - DictKey key; - DictNode *next; - DictNode *prev; -}; - -struct Dict { - DictNode head; - void *frame; - int (*leq)(void *frame, DictKey key1, DictKey key2); -}; - -#endif diff --git a/clutter/cogl/cogl/tesselator/dict.c b/clutter/cogl/cogl/tesselator/dict.c deleted file mode 100644 index 49d4f75..0000000 --- a/clutter/cogl/cogl/tesselator/dict.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include "dict-list.h" -#include "memalloc.h" - -/* really __gl_dictListNewDict */ -Dict *dictNewDict( void *frame, - int (*leq)(void *frame, DictKey key1, DictKey key2) ) -{ - Dict *dict = (Dict *) memAlloc( sizeof( Dict )); - DictNode *head; - - if (dict == NULL) return NULL; - - head = &dict->head; - - head->key = NULL; - head->next = head; - head->prev = head; - - dict->frame = frame; - dict->leq = leq; - - return dict; -} - -/* really __gl_dictListDeleteDict */ -void dictDeleteDict( Dict *dict ) -{ - DictNode *node, *next; - - for( node = dict->head.next; node != &dict->head; node = next ) { - next = node->next; - memFree( node ); - } - memFree( dict ); -} - -/* really __gl_dictListInsertBefore */ -DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key ) -{ - DictNode *newNode; - - do { - node = node->prev; - } while( node->key != NULL && ! (*dict->leq)(dict->frame, node->key, key)); - - newNode = (DictNode *) memAlloc( sizeof( DictNode )); - if (newNode == NULL) return NULL; - - newNode->key = key; - newNode->next = node->next; - node->next->prev = newNode; - newNode->prev = node; - node->next = newNode; - - return newNode; -} - -/* really __gl_dictListDelete */ -void dictDelete( Dict *dict, DictNode *node ) /*ARGSUSED*/ -{ - node->next->prev = node->prev; - node->prev->next = node->next; - memFree( node ); -} - -/* really __gl_dictListSearch */ -DictNode *dictSearch( Dict *dict, DictKey key ) -{ - DictNode *node = &dict->head; - - do { - node = node->next; - } while( node->key != NULL && ! (*dict->leq)(dict->frame, key, node->key)); - - return node; -} diff --git a/clutter/cogl/cogl/tesselator/dict.h b/clutter/cogl/cogl/tesselator/dict.h deleted file mode 100644 index 11331a7..0000000 --- a/clutter/cogl/cogl/tesselator/dict.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __dict_list_h_ -#define __dict_list_h_ - -/* Use #define's so that another heap implementation can use this one */ - -#define DictKey DictListKey -#define Dict DictList -#define DictNode DictListNode - -#define dictNewDict(frame,leq) __gl_dictListNewDict(frame,leq) -#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict) - -#define dictSearch(dict,key) __gl_dictListSearch(dict,key) -#define dictInsert(dict,key) __gl_dictListInsert(dict,key) -#define dictInsertBefore(dict,node,key) __gl_dictListInsertBefore(dict,node,key) -#define dictDelete(dict,node) __gl_dictListDelete(dict,node) - -#define dictKey(n) __gl_dictListKey(n) -#define dictSucc(n) __gl_dictListSucc(n) -#define dictPred(n) __gl_dictListPred(n) -#define dictMin(d) __gl_dictListMin(d) -#define dictMax(d) __gl_dictListMax(d) - - - -typedef void *DictKey; -typedef struct Dict Dict; -typedef struct DictNode DictNode; - -Dict *dictNewDict( - void *frame, - int (*leq)(void *frame, DictKey key1, DictKey key2) ); - -void dictDeleteDict( Dict *dict ); - -/* Search returns the node with the smallest key greater than or equal - * to the given key. If there is no such key, returns a node whose - * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc. - */ -DictNode *dictSearch( Dict *dict, DictKey key ); -DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key ); -void dictDelete( Dict *dict, DictNode *node ); - -#define __gl_dictListKey(n) ((n)->key) -#define __gl_dictListSucc(n) ((n)->next) -#define __gl_dictListPred(n) ((n)->prev) -#define __gl_dictListMin(d) ((d)->head.next) -#define __gl_dictListMax(d) ((d)->head.prev) -#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k))) - - -/*** Private data structures ***/ - -struct DictNode { - DictKey key; - DictNode *next; - DictNode *prev; -}; - -struct Dict { - DictNode head; - void *frame; - int (*leq)(void *frame, DictKey key1, DictKey key2); -}; - -#endif diff --git a/clutter/cogl/cogl/tesselator/geom.c b/clutter/cogl/cogl/tesselator/geom.c deleted file mode 100644 index 35b36a3..0000000 --- a/clutter/cogl/cogl/tesselator/geom.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include -#include "mesh.h" -#include "geom.h" - -int __gl_vertLeq( GLUvertex *u, GLUvertex *v ) -{ - /* Returns TRUE if u is lexicographically <= v. */ - - return VertLeq( u, v ); -} - -GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w ) -{ - /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w), - * evaluates the t-coord of the edge uw at the s-coord of the vertex v. - * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v. - * If uw is vertical (and thus passes thru v), the result is zero. - * - * The calculation is extremely accurate and stable, even when v - * is very close to u or w. In particular if we set v->t = 0 and - * let r be the negated result (this evaluates (uw)(v->s)), then - * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t). - */ - GLdouble gapL, gapR; - - assert( VertLeq( u, v ) && VertLeq( v, w )); - - gapL = v->s - u->s; - gapR = w->s - v->s; - - if( gapL + gapR > 0 ) { - if( gapL < gapR ) { - return (v->t - u->t) + (u->t - w->t) * (gapL / (gapL + gapR)); - } else { - return (v->t - w->t) + (w->t - u->t) * (gapR / (gapL + gapR)); - } - } - /* vertical line */ - return 0; -} - -GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w ) -{ - /* Returns a number whose sign matches EdgeEval(u,v,w) but which - * is cheaper to evaluate. Returns > 0, == 0 , or < 0 - * as v is above, on, or below the edge uw. - */ - GLdouble gapL, gapR; - - assert( VertLeq( u, v ) && VertLeq( v, w )); - - gapL = v->s - u->s; - gapR = w->s - v->s; - - if( gapL + gapR > 0 ) { - return (v->t - w->t) * gapL + (v->t - u->t) * gapR; - } - /* vertical line */ - return 0; -} - - -/*********************************************************************** - * Define versions of EdgeSign, EdgeEval with s and t transposed. - */ - -GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w ) -{ - /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w), - * evaluates the t-coord of the edge uw at the s-coord of the vertex v. - * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v. - * If uw is vertical (and thus passes thru v), the result is zero. - * - * The calculation is extremely accurate and stable, even when v - * is very close to u or w. In particular if we set v->s = 0 and - * let r be the negated result (this evaluates (uw)(v->t)), then - * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s). - */ - GLdouble gapL, gapR; - - assert( TransLeq( u, v ) && TransLeq( v, w )); - - gapL = v->t - u->t; - gapR = w->t - v->t; - - if( gapL + gapR > 0 ) { - if( gapL < gapR ) { - return (v->s - u->s) + (u->s - w->s) * (gapL / (gapL + gapR)); - } else { - return (v->s - w->s) + (w->s - u->s) * (gapR / (gapL + gapR)); - } - } - /* vertical line */ - return 0; -} - -GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w ) -{ - /* Returns a number whose sign matches TransEval(u,v,w) but which - * is cheaper to evaluate. Returns > 0, == 0 , or < 0 - * as v is above, on, or below the edge uw. - */ - GLdouble gapL, gapR; - - assert( TransLeq( u, v ) && TransLeq( v, w )); - - gapL = v->t - u->t; - gapR = w->t - v->t; - - if( gapL + gapR > 0 ) { - return (v->s - w->s) * gapL + (v->s - u->s) * gapR; - } - /* vertical line */ - return 0; -} - - -int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w ) -{ - /* For almost-degenerate situations, the results are not reliable. - * Unless the floating-point arithmetic can be performed without - * rounding errors, *any* implementation will give incorrect results - * on some degenerate inputs, so the client must have some way to - * handle this situation. - */ - return (u->s*(v->t - w->t) + v->s*(w->t - u->t) + w->s*(u->t - v->t)) >= 0; -} - -/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b), - * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces - * this in the rare case that one argument is slightly negative. - * The implementation is extremely stable numerically. - * In particular it guarantees that the result r satisfies - * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate - * even when a and b differ greatly in magnitude. - */ -#define RealInterpolate(a,x,b,y) \ - (a = (a < 0) ? 0 : a, b = (b < 0) ? 0 : b, \ - ((a <= b) ? ((b == 0) ? ((x+y) / 2) \ - : (x + (y-x) * (a/(a+b)))) \ - : (y + (x-y) * (b/(a+b))))) - -#ifndef FOR_TRITE_TEST_PROGRAM -#define Interpolate(a,x,b,y) RealInterpolate(a,x,b,y) -#else - -/* Claim: the ONLY property the sweep algorithm relies on is that - * MIN(x,y) <= r <= MAX(x,y). This is a nasty way to test that. - */ -#include -extern int RandomInterpolate; - -GLdouble Interpolate( GLdouble a, GLdouble x, GLdouble b, GLdouble y) -{ -printf("*********************%d\n",RandomInterpolate); - if( RandomInterpolate ) { - a = 1.2 * drand48() - 0.1; - a = (a < 0) ? 0 : ((a > 1) ? 1 : a); - b = 1.0 - a; - } - return RealInterpolate(a,x,b,y); -} - -#endif - -#define Swap(a,b) do { GLUvertex *t = a; a = b; b = t; } while (0) - -void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1, - GLUvertex *o2, GLUvertex *d2, - GLUvertex *v ) -/* Given edges (o1,d1) and (o2,d2), compute their point of intersection. - * The computed point is guaranteed to lie in the intersection of the - * bounding rectangles defined by each edge. - */ -{ - GLdouble z1, z2; - - /* This is certainly not the most efficient way to find the intersection - * of two line segments, but it is very numerically stable. - * - * Strategy: find the two middle vertices in the VertLeq ordering, - * and interpolate the intersection s-value from these. Then repeat - * using the TransLeq ordering to find the intersection t-value. - */ - - if( ! VertLeq( o1, d1 )) { Swap( o1, d1 ); } - if( ! VertLeq( o2, d2 )) { Swap( o2, d2 ); } - if( ! VertLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); } - - if( ! VertLeq( o2, d1 )) { - /* Technically, no intersection -- do our best */ - v->s = (o2->s + d1->s) / 2; - } else if( VertLeq( d1, d2 )) { - /* Interpolate between o2 and d1 */ - z1 = EdgeEval( o1, o2, d1 ); - z2 = EdgeEval( o2, d1, d2 ); - if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } - v->s = Interpolate( z1, o2->s, z2, d1->s ); - } else { - /* Interpolate between o2 and d2 */ - z1 = EdgeSign( o1, o2, d1 ); - z2 = -EdgeSign( o1, d2, d1 ); - if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } - v->s = Interpolate( z1, o2->s, z2, d2->s ); - } - - /* Now repeat the process for t */ - - if( ! TransLeq( o1, d1 )) { Swap( o1, d1 ); } - if( ! TransLeq( o2, d2 )) { Swap( o2, d2 ); } - if( ! TransLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); } - - if( ! TransLeq( o2, d1 )) { - /* Technically, no intersection -- do our best */ - v->t = (o2->t + d1->t) / 2; - } else if( TransLeq( d1, d2 )) { - /* Interpolate between o2 and d1 */ - z1 = TransEval( o1, o2, d1 ); - z2 = TransEval( o2, d1, d2 ); - if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } - v->t = Interpolate( z1, o2->t, z2, d1->t ); - } else { - /* Interpolate between o2 and d2 */ - z1 = TransSign( o1, o2, d1 ); - z2 = -TransSign( o1, d2, d1 ); - if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; } - v->t = Interpolate( z1, o2->t, z2, d2->t ); - } -} diff --git a/clutter/cogl/cogl/tesselator/geom.h b/clutter/cogl/cogl/tesselator/geom.h deleted file mode 100644 index 5cb76c7..0000000 --- a/clutter/cogl/cogl/tesselator/geom.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __geom_h_ -#define __geom_h_ - -#include "mesh.h" - -#ifdef NO_BRANCH_CONDITIONS -/* MIPS architecture has special instructions to evaluate boolean - * conditions -- more efficient than branching, IF you can get the - * compiler to generate the right instructions (SGI compiler doesn't) - */ -#define VertEq(u,v) (((u)->s == (v)->s) & ((u)->t == (v)->t)) -#define VertLeq(u,v) (((u)->s < (v)->s) | \ - ((u)->s == (v)->s & (u)->t <= (v)->t)) -#else -#define VertEq(u,v) ((u)->s == (v)->s && (u)->t == (v)->t) -#define VertLeq(u,v) (((u)->s < (v)->s) || \ - ((u)->s == (v)->s && (u)->t <= (v)->t)) -#endif - -#define EdgeEval(u,v,w) __gl_edgeEval(u,v,w) -#define EdgeSign(u,v,w) __gl_edgeSign(u,v,w) - -/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */ - -#define TransLeq(u,v) (((u)->t < (v)->t) || \ - ((u)->t == (v)->t && (u)->s <= (v)->s)) -#define TransEval(u,v,w) __gl_transEval(u,v,w) -#define TransSign(u,v,w) __gl_transSign(u,v,w) - - -#define EdgeGoesLeft(e) VertLeq( (e)->Dst, (e)->Org ) -#define EdgeGoesRight(e) VertLeq( (e)->Org, (e)->Dst ) - -#undef ABS -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#define VertL1dist(u,v) (ABS(u->s - v->s) + ABS(u->t - v->t)) - -#define VertCCW(u,v,w) __gl_vertCCW(u,v,w) - -int __gl_vertLeq( GLUvertex *u, GLUvertex *v ); -GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w ); -GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w ); -GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w ); -GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w ); -int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w ); -void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1, - GLUvertex *o2, GLUvertex *d2, - GLUvertex *v ); - -#endif diff --git a/clutter/cogl/cogl/tesselator/gluos.h b/clutter/cogl/cogl/tesselator/gluos.h deleted file mode 100644 index d6c3ae9..0000000 --- a/clutter/cogl/cogl/tesselator/gluos.h +++ /dev/null @@ -1 +0,0 @@ -/* This is a stub header to avoid having to change tess.c */ diff --git a/clutter/cogl/cogl/tesselator/memalloc.h b/clutter/cogl/cogl/tesselator/memalloc.h deleted file mode 100644 index 0293e15..0000000 --- a/clutter/cogl/cogl/tesselator/memalloc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/* This is a simple replacement for memalloc from the SGI tesselator - code to force it to use glib's allocation instead */ - -#ifndef __MEMALLOC_H__ -#define __MEMALLOC_H__ - -#include - -#define memRealloc g_realloc -#define memAlloc g_malloc -#define memFree g_free -#define memInit(x) 1 - -/* tess.c defines TRUE and FALSE itself unconditionally so we need to - undefine it from the glib headers */ -#undef TRUE -#undef FALSE - -#endif /* __MEMALLOC_H__ */ diff --git a/clutter/cogl/cogl/tesselator/mesh.c b/clutter/cogl/cogl/tesselator/mesh.c deleted file mode 100644 index 36cb3a7..0000000 --- a/clutter/cogl/cogl/tesselator/mesh.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include -#include -#include "mesh.h" -#include "memalloc.h" - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -static GLUvertex *allocVertex() -{ - return (GLUvertex *)memAlloc( sizeof( GLUvertex )); -} - -static GLUface *allocFace() -{ - return (GLUface *)memAlloc( sizeof( GLUface )); -} - -/************************ Utility Routines ************************/ - -/* Allocate and free half-edges in pairs for efficiency. - * The *only* place that should use this fact is allocation/free. - */ -typedef struct { GLUhalfEdge e, eSym; } EdgePair; - -/* MakeEdge creates a new pair of half-edges which form their own loop. - * No vertex or face structures are allocated, but these must be assigned - * before the current edge operation is completed. - */ -static GLUhalfEdge *MakeEdge( GLUhalfEdge *eNext ) -{ - GLUhalfEdge *e; - GLUhalfEdge *eSym; - GLUhalfEdge *ePrev; - EdgePair *pair = (EdgePair *)memAlloc( sizeof( EdgePair )); - if (pair == NULL) return NULL; - - e = &pair->e; - eSym = &pair->eSym; - - /* Make sure eNext points to the first edge of the edge pair */ - if( eNext->Sym < eNext ) { eNext = eNext->Sym; } - - /* Insert in circular doubly-linked list before eNext. - * Note that the prev pointer is stored in Sym->next. - */ - ePrev = eNext->Sym->next; - eSym->next = ePrev; - ePrev->Sym->next = e; - e->next = eNext; - eNext->Sym->next = eSym; - - e->Sym = eSym; - e->Onext = e; - e->Lnext = eSym; - e->Org = NULL; - e->Lface = NULL; - e->winding = 0; - e->activeRegion = NULL; - - eSym->Sym = e; - eSym->Onext = eSym; - eSym->Lnext = e; - eSym->Org = NULL; - eSym->Lface = NULL; - eSym->winding = 0; - eSym->activeRegion = NULL; - - return e; -} - -/* Splice( a, b ) is best described by the Guibas/Stolfi paper or the - * CS348a notes (see mesh.h). Basically it modifies the mesh so that - * a->Onext and b->Onext are exchanged. This can have various effects - * depending on whether a and b belong to different face or vertex rings. - * For more explanation see __gl_meshSplice() below. - */ -static void Splice( GLUhalfEdge *a, GLUhalfEdge *b ) -{ - GLUhalfEdge *aOnext = a->Onext; - GLUhalfEdge *bOnext = b->Onext; - - aOnext->Sym->Lnext = b; - bOnext->Sym->Lnext = a; - a->Onext = bOnext; - b->Onext = aOnext; -} - -/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the - * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives - * a place to insert the new vertex in the global vertex list. We insert - * the new vertex *before* vNext so that algorithms which walk the vertex - * list will not see the newly created vertices. - */ -static void MakeVertex( GLUvertex *newVertex, - GLUhalfEdge *eOrig, GLUvertex *vNext ) -{ - GLUhalfEdge *e; - GLUvertex *vPrev; - GLUvertex *vNew = newVertex; - - assert(vNew != NULL); - - /* insert in circular doubly-linked list before vNext */ - vPrev = vNext->prev; - vNew->prev = vPrev; - vPrev->next = vNew; - vNew->next = vNext; - vNext->prev = vNew; - - vNew->anEdge = eOrig; - vNew->data = NULL; - /* leave coords, s, t undefined */ - - /* fix other edges on this vertex loop */ - e = eOrig; - do { - e->Org = vNew; - e = e->Onext; - } while( e != eOrig ); -} - -/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left - * face of all edges in the face loop to which eOrig belongs. "fNext" gives - * a place to insert the new face in the global face list. We insert - * the new face *before* fNext so that algorithms which walk the face - * list will not see the newly created faces. - */ -static void MakeFace( GLUface *newFace, GLUhalfEdge *eOrig, GLUface *fNext ) -{ - GLUhalfEdge *e; - GLUface *fPrev; - GLUface *fNew = newFace; - - assert(fNew != NULL); - - /* insert in circular doubly-linked list before fNext */ - fPrev = fNext->prev; - fNew->prev = fPrev; - fPrev->next = fNew; - fNew->next = fNext; - fNext->prev = fNew; - - fNew->anEdge = eOrig; - fNew->data = NULL; - fNew->trail = NULL; - fNew->marked = FALSE; - - /* The new face is marked "inside" if the old one was. This is a - * convenience for the common case where a face has been split in two. - */ - fNew->inside = fNext->inside; - - /* fix other edges on this face loop */ - e = eOrig; - do { - e->Lface = fNew; - e = e->Lnext; - } while( e != eOrig ); -} - -/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym), - * and removes from the global edge list. - */ -static void KillEdge( GLUhalfEdge *eDel ) -{ - GLUhalfEdge *ePrev, *eNext; - - /* Half-edges are allocated in pairs, see EdgePair above */ - if( eDel->Sym < eDel ) { eDel = eDel->Sym; } - - /* delete from circular doubly-linked list */ - eNext = eDel->next; - ePrev = eDel->Sym->next; - eNext->Sym->next = ePrev; - ePrev->Sym->next = eNext; - - memFree( eDel ); -} - - -/* KillVertex( vDel ) destroys a vertex and removes it from the global - * vertex list. It updates the vertex loop to point to a given new vertex. - */ -static void KillVertex( GLUvertex *vDel, GLUvertex *newOrg ) -{ - GLUhalfEdge *e, *eStart = vDel->anEdge; - GLUvertex *vPrev, *vNext; - - /* change the origin of all affected edges */ - e = eStart; - do { - e->Org = newOrg; - e = e->Onext; - } while( e != eStart ); - - /* delete from circular doubly-linked list */ - vPrev = vDel->prev; - vNext = vDel->next; - vNext->prev = vPrev; - vPrev->next = vNext; - - memFree( vDel ); -} - -/* KillFace( fDel ) destroys a face and removes it from the global face - * list. It updates the face loop to point to a given new face. - */ -static void KillFace( GLUface *fDel, GLUface *newLface ) -{ - GLUhalfEdge *e, *eStart = fDel->anEdge; - GLUface *fPrev, *fNext; - - /* change the left face of all affected edges */ - e = eStart; - do { - e->Lface = newLface; - e = e->Lnext; - } while( e != eStart ); - - /* delete from circular doubly-linked list */ - fPrev = fDel->prev; - fNext = fDel->next; - fNext->prev = fPrev; - fPrev->next = fNext; - - memFree( fDel ); -} - - -/****************** Basic Edge Operations **********************/ - -/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face). - * The loop consists of the two new half-edges. - */ -GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh ) -{ - GLUvertex *newVertex1= allocVertex(); - GLUvertex *newVertex2= allocVertex(); - GLUface *newFace= allocFace(); - GLUhalfEdge *e; - - /* if any one is null then all get freed */ - if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) { - if (newVertex1 != NULL) memFree(newVertex1); - if (newVertex2 != NULL) memFree(newVertex2); - if (newFace != NULL) memFree(newFace); - return NULL; - } - - e = MakeEdge( &mesh->eHead ); - if (e == NULL) { - memFree(newVertex1); - memFree(newVertex2); - memFree(newFace); - return NULL; - } - - MakeVertex( newVertex1, e, &mesh->vHead ); - MakeVertex( newVertex2, e->Sym, &mesh->vHead ); - MakeFace( newFace, e, &mesh->fHead ); - return e; -} - - -/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the - * mesh connectivity and topology. It changes the mesh so that - * eOrg->Onext <- OLD( eDst->Onext ) - * eDst->Onext <- OLD( eOrg->Onext ) - * where OLD(...) means the value before the meshSplice operation. - * - * This can have two effects on the vertex structure: - * - if eOrg->Org != eDst->Org, the two vertices are merged together - * - if eOrg->Org == eDst->Org, the origin is split into two vertices - * In both cases, eDst->Org is changed and eOrg->Org is untouched. - * - * Similarly (and independently) for the face structure, - * - if eOrg->Lface == eDst->Lface, one loop is split into two - * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one - * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected. - * - * Some special cases: - * If eDst == eOrg, the operation has no effect. - * If eDst == eOrg->Lnext, the new face will have a single edge. - * If eDst == eOrg->Lprev, the old face will have a single edge. - * If eDst == eOrg->Onext, the new vertex will have a single edge. - * If eDst == eOrg->Oprev, the old vertex will have a single edge. - */ -int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst ) -{ - int joiningLoops = FALSE; - int joiningVertices = FALSE; - - if( eOrg == eDst ) return 1; - - if( eDst->Org != eOrg->Org ) { - /* We are merging two disjoint vertices -- destroy eDst->Org */ - joiningVertices = TRUE; - KillVertex( eDst->Org, eOrg->Org ); - } - if( eDst->Lface != eOrg->Lface ) { - /* We are connecting two disjoint loops -- destroy eDst->Lface */ - joiningLoops = TRUE; - KillFace( eDst->Lface, eOrg->Lface ); - } - - /* Change the edge structure */ - Splice( eDst, eOrg ); - - if( ! joiningVertices ) { - GLUvertex *newVertex= allocVertex(); - if (newVertex == NULL) return 0; - - /* We split one vertex into two -- the new vertex is eDst->Org. - * Make sure the old vertex points to a valid half-edge. - */ - MakeVertex( newVertex, eDst, eOrg->Org ); - eOrg->Org->anEdge = eOrg; - } - if( ! joiningLoops ) { - GLUface *newFace= allocFace(); - if (newFace == NULL) return 0; - - /* We split one loop into two -- the new loop is eDst->Lface. - * Make sure the old face points to a valid half-edge. - */ - MakeFace( newFace, eDst, eOrg->Lface ); - eOrg->Lface->anEdge = eOrg; - } - - return 1; -} - - -/* __gl_meshDelete( eDel ) removes the edge eDel. There are several cases: - * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop - * eDel->Lface is deleted. Otherwise, we are splitting one loop into two; - * the newly created loop will contain eDel->Dst. If the deletion of eDel - * would create isolated vertices, those are deleted as well. - * - * This function could be implemented as two calls to __gl_meshSplice - * plus a few calls to memFree, but this would allocate and delete - * unnecessary vertices and faces. - */ -int __gl_meshDelete( GLUhalfEdge *eDel ) -{ - GLUhalfEdge *eDelSym = eDel->Sym; - int joiningLoops = FALSE; - - /* First step: disconnect the origin vertex eDel->Org. We make all - * changes to get a consistent mesh in this "intermediate" state. - */ - if( eDel->Lface != eDel->Rface ) { - /* We are joining two loops into one -- remove the left face */ - joiningLoops = TRUE; - KillFace( eDel->Lface, eDel->Rface ); - } - - if( eDel->Onext == eDel ) { - KillVertex( eDel->Org, NULL ); - } else { - /* Make sure that eDel->Org and eDel->Rface point to valid half-edges */ - eDel->Rface->anEdge = eDel->Oprev; - eDel->Org->anEdge = eDel->Onext; - - Splice( eDel, eDel->Oprev ); - if( ! joiningLoops ) { - GLUface *newFace= allocFace(); - if (newFace == NULL) return 0; - - /* We are splitting one loop into two -- create a new loop for eDel. */ - MakeFace( newFace, eDel, eDel->Lface ); - } - } - - /* Claim: the mesh is now in a consistent state, except that eDel->Org - * may have been deleted. Now we disconnect eDel->Dst. - */ - if( eDelSym->Onext == eDelSym ) { - KillVertex( eDelSym->Org, NULL ); - KillFace( eDelSym->Lface, NULL ); - } else { - /* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */ - eDel->Lface->anEdge = eDelSym->Oprev; - eDelSym->Org->anEdge = eDelSym->Onext; - Splice( eDelSym, eDelSym->Oprev ); - } - - /* Any isolated vertices or faces have already been freed. */ - KillEdge( eDel ); - - return 1; -} - - -/******************** Other Edge Operations **********************/ - -/* All these routines can be implemented with the basic edge - * operations above. They are provided for convenience and efficiency. - */ - - -/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that - * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. - * eOrg and eNew will have the same left face. - */ -GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg ) -{ - GLUhalfEdge *eNewSym; - GLUhalfEdge *eNew = MakeEdge( eOrg ); - if (eNew == NULL) return NULL; - - eNewSym = eNew->Sym; - - /* Connect the new edge appropriately */ - Splice( eNew, eOrg->Lnext ); - - /* Set the vertex and face information */ - eNew->Org = eOrg->Dst; - { - GLUvertex *newVertex= allocVertex(); - if (newVertex == NULL) return NULL; - - MakeVertex( newVertex, eNewSym, eNew->Org ); - } - eNew->Lface = eNewSym->Lface = eOrg->Lface; - - return eNew; -} - - -/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew, - * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org. - * eOrg and eNew will have the same left face. - */ -GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg ) -{ - GLUhalfEdge *eNew; - GLUhalfEdge *tempHalfEdge= __gl_meshAddEdgeVertex( eOrg ); - if (tempHalfEdge == NULL) return NULL; - - eNew = tempHalfEdge->Sym; - - /* Disconnect eOrg from eOrg->Dst and connect it to eNew->Org */ - Splice( eOrg->Sym, eOrg->Sym->Oprev ); - Splice( eOrg->Sym, eNew ); - - /* Set the vertex and face information */ - eOrg->Dst = eNew->Org; - eNew->Dst->anEdge = eNew->Sym; /* may have pointed to eOrg->Sym */ - eNew->Rface = eOrg->Rface; - eNew->winding = eOrg->winding; /* copy old winding information */ - eNew->Sym->winding = eOrg->Sym->winding; - - return eNew; -} - - -/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst - * to eDst->Org, and returns the corresponding half-edge eNew. - * If eOrg->Lface == eDst->Lface, this splits one loop into two, - * and the newly created loop is eNew->Lface. Otherwise, two disjoint - * loops are merged into one, and the loop eDst->Lface is destroyed. - * - * If (eOrg == eDst), the new face will have only two edges. - * If (eOrg->Lnext == eDst), the old face is reduced to a single edge. - * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges. - */ -GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst ) -{ - GLUhalfEdge *eNewSym; - int joiningLoops = FALSE; - GLUhalfEdge *eNew = MakeEdge( eOrg ); - if (eNew == NULL) return NULL; - - eNewSym = eNew->Sym; - - if( eDst->Lface != eOrg->Lface ) { - /* We are connecting two disjoint loops -- destroy eDst->Lface */ - joiningLoops = TRUE; - KillFace( eDst->Lface, eOrg->Lface ); - } - - /* Connect the new edge appropriately */ - Splice( eNew, eOrg->Lnext ); - Splice( eNewSym, eDst ); - - /* Set the vertex and face information */ - eNew->Org = eOrg->Dst; - eNewSym->Org = eDst->Org; - eNew->Lface = eNewSym->Lface = eOrg->Lface; - - /* Make sure the old face points to a valid half-edge */ - eOrg->Lface->anEdge = eNewSym; - - if( ! joiningLoops ) { - GLUface *newFace= allocFace(); - if (newFace == NULL) return NULL; - - /* We split one loop into two -- the new loop is eNew->Lface */ - MakeFace( newFace, eNew, eOrg->Lface ); - } - return eNew; -} - - -/******************** Other Operations **********************/ - -/* __gl_meshZapFace( fZap ) destroys a face and removes it from the - * global face list. All edges of fZap will have a NULL pointer as their - * left face. Any edges which also have a NULL pointer as their right face - * are deleted entirely (along with any isolated vertices this produces). - * An entire mesh can be deleted by zapping its faces, one at a time, - * in any order. Zapped faces cannot be used in further mesh operations! - */ -void __gl_meshZapFace( GLUface *fZap ) -{ - GLUhalfEdge *eStart = fZap->anEdge; - GLUhalfEdge *e, *eNext, *eSym; - GLUface *fPrev, *fNext; - - /* walk around face, deleting edges whose right face is also NULL */ - eNext = eStart->Lnext; - do { - e = eNext; - eNext = e->Lnext; - - e->Lface = NULL; - if( e->Rface == NULL ) { - /* delete the edge -- see __gl_MeshDelete above */ - - if( e->Onext == e ) { - KillVertex( e->Org, NULL ); - } else { - /* Make sure that e->Org points to a valid half-edge */ - e->Org->anEdge = e->Onext; - Splice( e, e->Oprev ); - } - eSym = e->Sym; - if( eSym->Onext == eSym ) { - KillVertex( eSym->Org, NULL ); - } else { - /* Make sure that eSym->Org points to a valid half-edge */ - eSym->Org->anEdge = eSym->Onext; - Splice( eSym, eSym->Oprev ); - } - KillEdge( e ); - } - } while( e != eStart ); - - /* delete from circular doubly-linked list */ - fPrev = fZap->prev; - fNext = fZap->next; - fNext->prev = fPrev; - fPrev->next = fNext; - - memFree( fZap ); -} - - -/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices, - * and no loops (what we usually call a "face"). - */ -GLUmesh *__gl_meshNewMesh( void ) -{ - GLUvertex *v; - GLUface *f; - GLUhalfEdge *e; - GLUhalfEdge *eSym; - GLUmesh *mesh = (GLUmesh *)memAlloc( sizeof( GLUmesh )); - if (mesh == NULL) { - return NULL; - } - - v = &mesh->vHead; - f = &mesh->fHead; - e = &mesh->eHead; - eSym = &mesh->eHeadSym; - - v->next = v->prev = v; - v->anEdge = NULL; - v->data = NULL; - - f->next = f->prev = f; - f->anEdge = NULL; - f->data = NULL; - f->trail = NULL; - f->marked = FALSE; - f->inside = FALSE; - - e->next = e; - e->Sym = eSym; - e->Onext = NULL; - e->Lnext = NULL; - e->Org = NULL; - e->Lface = NULL; - e->winding = 0; - e->activeRegion = NULL; - - eSym->next = eSym; - eSym->Sym = e; - eSym->Onext = NULL; - eSym->Lnext = NULL; - eSym->Org = NULL; - eSym->Lface = NULL; - eSym->winding = 0; - eSym->activeRegion = NULL; - - return mesh; -} - - -/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in - * both meshes, and returns the new mesh (the old meshes are destroyed). - */ -GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 ) -{ - GLUface *f1 = &mesh1->fHead; - GLUvertex *v1 = &mesh1->vHead; - GLUhalfEdge *e1 = &mesh1->eHead; - GLUface *f2 = &mesh2->fHead; - GLUvertex *v2 = &mesh2->vHead; - GLUhalfEdge *e2 = &mesh2->eHead; - - /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */ - if( f2->next != f2 ) { - f1->prev->next = f2->next; - f2->next->prev = f1->prev; - f2->prev->next = f1; - f1->prev = f2->prev; - } - - if( v2->next != v2 ) { - v1->prev->next = v2->next; - v2->next->prev = v1->prev; - v2->prev->next = v1; - v1->prev = v2->prev; - } - - if( e2->next != e2 ) { - e1->Sym->next->Sym->next = e2->next; - e2->next->Sym->next = e1->Sym->next; - e2->Sym->next->Sym->next = e1; - e1->Sym->next = e2->Sym->next; - } - - memFree( mesh2 ); - return mesh1; -} - - -#ifdef DELETE_BY_ZAPPING - -/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. - */ -void __gl_meshDeleteMesh( GLUmesh *mesh ) -{ - GLUface *fHead = &mesh->fHead; - - while( fHead->next != fHead ) { - __gl_meshZapFace( fHead->next ); - } - assert( mesh->vHead.next == &mesh->vHead ); - - memFree( mesh ); -} - -#else - -/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. - */ -void __gl_meshDeleteMesh( GLUmesh *mesh ) -{ - GLUface *f, *fNext; - GLUvertex *v, *vNext; - GLUhalfEdge *e, *eNext; - - for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) { - fNext = f->next; - memFree( f ); - } - - for( v = mesh->vHead.next; v != &mesh->vHead; v = vNext ) { - vNext = v->next; - memFree( v ); - } - - for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) { - /* One call frees both e and e->Sym (see EdgePair above) */ - eNext = e->next; - memFree( e ); - } - - memFree( mesh ); -} - -#endif - -#ifndef NDEBUG - -/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency. - */ -void __gl_meshCheckMesh( GLUmesh *mesh ) -{ - GLUface *fHead = &mesh->fHead; - GLUvertex *vHead = &mesh->vHead; - GLUhalfEdge *eHead = &mesh->eHead; - GLUface *f, *fPrev; - GLUvertex *v, *vPrev; - GLUhalfEdge *e, *ePrev; - - fPrev = fHead; - for( fPrev = fHead ; (f = fPrev->next) != fHead; fPrev = f) { - assert( f->prev == fPrev ); - e = f->anEdge; - do { - assert( e->Sym != e ); - assert( e->Sym->Sym == e ); - assert( e->Lnext->Onext->Sym == e ); - assert( e->Onext->Sym->Lnext == e ); - assert( e->Lface == f ); - e = e->Lnext; - } while( e != f->anEdge ); - } - assert( f->prev == fPrev && f->anEdge == NULL && f->data == NULL ); - - vPrev = vHead; - for( vPrev = vHead ; (v = vPrev->next) != vHead; vPrev = v) { - assert( v->prev == vPrev ); - e = v->anEdge; - do { - assert( e->Sym != e ); - assert( e->Sym->Sym == e ); - assert( e->Lnext->Onext->Sym == e ); - assert( e->Onext->Sym->Lnext == e ); - assert( e->Org == v ); - e = e->Onext; - } while( e != v->anEdge ); - } - assert( v->prev == vPrev && v->anEdge == NULL && v->data == NULL ); - - ePrev = eHead; - for( ePrev = eHead ; (e = ePrev->next) != eHead; ePrev = e) { - assert( e->Sym->next == ePrev->Sym ); - assert( e->Sym != e ); - assert( e->Sym->Sym == e ); - assert( e->Org != NULL ); - assert( e->Dst != NULL ); - assert( e->Lnext->Onext->Sym == e ); - assert( e->Onext->Sym->Lnext == e ); - } - assert( e->Sym->next == ePrev->Sym - && e->Sym == &mesh->eHeadSym - && e->Sym->Sym == e - && e->Org == NULL && e->Dst == NULL - && e->Lface == NULL && e->Rface == NULL ); -} - -#endif diff --git a/clutter/cogl/cogl/tesselator/mesh.h b/clutter/cogl/cogl/tesselator/mesh.h deleted file mode 100644 index 690c5f2..0000000 --- a/clutter/cogl/cogl/tesselator/mesh.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __mesh_h_ -#define __mesh_h_ - -#include - -typedef struct GLUmesh GLUmesh; - -typedef struct GLUvertex GLUvertex; -typedef struct GLUface GLUface; -typedef struct GLUhalfEdge GLUhalfEdge; - -typedef struct ActiveRegion ActiveRegion; /* Internal data */ - -/* The mesh structure is similar in spirit, notation, and operations - * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives - * for the manipulation of general subdivisions and the computation of - * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985). - * For a simplified description, see the course notes for CS348a, - * "Mathematical Foundations of Computer Graphics", available at the - * Stanford bookstore (and taught during the fall quarter). - * The implementation also borrows a tiny subset of the graph-based approach - * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction - * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988). - * - * The fundamental data structure is the "half-edge". Two half-edges - * go together to make an edge, but they point in opposite directions. - * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym), - * its origin vertex (Org), the face on its left side (Lface), and the - * adjacent half-edges in the CCW direction around the origin vertex - * (Onext) and around the left face (Lnext). There is also a "next" - * pointer for the global edge list (see below). - * - * The notation used for mesh navigation: - * Sym = the mate of a half-edge (same edge, but opposite direction) - * Onext = edge CCW around origin vertex (keep same origin) - * Dnext = edge CCW around destination vertex (keep same dest) - * Lnext = edge CCW around left face (dest becomes new origin) - * Rnext = edge CCW around right face (origin becomes new dest) - * - * "prev" means to substitute CW for CCW in the definitions above. - * - * The mesh keeps global lists of all vertices, faces, and edges, - * stored as doubly-linked circular lists with a dummy header node. - * The mesh stores pointers to these dummy headers (vHead, fHead, eHead). - * - * The circular edge list is special; since half-edges always occur - * in pairs (e and e->Sym), each half-edge stores a pointer in only - * one direction. Starting at eHead and following the e->next pointers - * will visit each *edge* once (ie. e or e->Sym, but not both). - * e->Sym stores a pointer in the opposite direction, thus it is - * always true that e->Sym->next->Sym->next == e. - * - * Each vertex has a pointer to next and previous vertices in the - * circular list, and a pointer to a half-edge with this vertex as - * the origin (NULL if this is the dummy header). There is also a - * field "data" for client data. - * - * Each face has a pointer to the next and previous faces in the - * circular list, and a pointer to a half-edge with this face as - * the left face (NULL if this is the dummy header). There is also - * a field "data" for client data. - * - * Note that what we call a "face" is really a loop; faces may consist - * of more than one loop (ie. not simply connected), but there is no - * record of this in the data structure. The mesh may consist of - * several disconnected regions, so it may not be possible to visit - * the entire mesh by starting at a half-edge and traversing the edge - * structure. - * - * The mesh does NOT support isolated vertices; a vertex is deleted along - * with its last edge. Similarly when two faces are merged, one of the - * faces is deleted (see __gl_meshDelete below). For mesh operations, - * all face (loop) and vertex pointers must not be NULL. However, once - * mesh manipulation is finished, __gl_MeshZapFace can be used to delete - * faces of the mesh, one at a time. All external faces can be "zapped" - * before the mesh is returned to the client; then a NULL face indicates - * a region which is not part of the output polygon. - */ - -struct GLUvertex { - GLUvertex *next; /* next vertex (never NULL) */ - GLUvertex *prev; /* previous vertex (never NULL) */ - GLUhalfEdge *anEdge; /* a half-edge with this origin */ - void *data; /* client's data */ - - /* Internal data (keep hidden) */ - GLdouble coords[3]; /* vertex location in 3D */ - GLdouble s, t; /* projection onto the sweep plane */ - long pqHandle; /* to allow deletion from priority queue */ -}; - -struct GLUface { - GLUface *next; /* next face (never NULL) */ - GLUface *prev; /* previous face (never NULL) */ - GLUhalfEdge *anEdge; /* a half edge with this left face */ - void *data; /* room for client's data */ - - /* Internal data (keep hidden) */ - GLUface *trail; /* "stack" for conversion to strips */ - GLboolean marked; /* flag for conversion to strips */ - GLboolean inside; /* this face is in the polygon interior */ -}; - -struct GLUhalfEdge { - GLUhalfEdge *next; /* doubly-linked list (prev==Sym->next) */ - GLUhalfEdge *Sym; /* same edge, opposite direction */ - GLUhalfEdge *Onext; /* next edge CCW around origin */ - GLUhalfEdge *Lnext; /* next edge CCW around left face */ - GLUvertex *Org; /* origin vertex (Overtex too long) */ - GLUface *Lface; /* left face */ - - /* Internal data (keep hidden) */ - ActiveRegion *activeRegion; /* a region with this upper edge (sweep.c) */ - int winding; /* change in winding number when crossing - from the right face to the left face */ -}; - -#define Rface Sym->Lface -#define Dst Sym->Org - -#define Oprev Sym->Lnext -#define Lprev Onext->Sym -#define Dprev Lnext->Sym -#define Rprev Sym->Onext -#define Dnext Rprev->Sym /* 3 pointers */ -#define Rnext Oprev->Sym /* 3 pointers */ - - -struct GLUmesh { - GLUvertex vHead; /* dummy header for vertex list */ - GLUface fHead; /* dummy header for face list */ - GLUhalfEdge eHead; /* dummy header for edge list */ - GLUhalfEdge eHeadSym; /* and its symmetric counterpart */ -}; - -/* The mesh operations below have three motivations: completeness, - * convenience, and efficiency. The basic mesh operations are MakeEdge, - * Splice, and Delete. All the other edge operations can be implemented - * in terms of these. The other operations are provided for convenience - * and/or efficiency. - * - * When a face is split or a vertex is added, they are inserted into the - * global list *before* the existing vertex or face (ie. e->Org or e->Lface). - * This makes it easier to process all vertices or faces in the global lists - * without worrying about processing the same data twice. As a convenience, - * when a face is split, the "inside" flag is copied from the old face. - * Other internal data (v->data, v->activeRegion, f->data, f->marked, - * f->trail, e->winding) is set to zero. - * - * ********************** Basic Edge Operations ************************** - * - * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop. - * The loop (face) consists of the two new half-edges. - * - * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the - * mesh connectivity and topology. It changes the mesh so that - * eOrg->Onext <- OLD( eDst->Onext ) - * eDst->Onext <- OLD( eOrg->Onext ) - * where OLD(...) means the value before the meshSplice operation. - * - * This can have two effects on the vertex structure: - * - if eOrg->Org != eDst->Org, the two vertices are merged together - * - if eOrg->Org == eDst->Org, the origin is split into two vertices - * In both cases, eDst->Org is changed and eOrg->Org is untouched. - * - * Similarly (and independently) for the face structure, - * - if eOrg->Lface == eDst->Lface, one loop is split into two - * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one - * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected. - * - * __gl_meshDelete( eDel ) removes the edge eDel. There are several cases: - * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop - * eDel->Lface is deleted. Otherwise, we are splitting one loop into two; - * the newly created loop will contain eDel->Dst. If the deletion of eDel - * would create isolated vertices, those are deleted as well. - * - * ********************** Other Edge Operations ************************** - * - * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that - * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. - * eOrg and eNew will have the same left face. - * - * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew, - * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org. - * eOrg and eNew will have the same left face. - * - * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst - * to eDst->Org, and returns the corresponding half-edge eNew. - * If eOrg->Lface == eDst->Lface, this splits one loop into two, - * and the newly created loop is eNew->Lface. Otherwise, two disjoint - * loops are merged into one, and the loop eDst->Lface is destroyed. - * - * ************************ Other Operations ***************************** - * - * __gl_meshNewMesh() creates a new mesh with no edges, no vertices, - * and no loops (what we usually call a "face"). - * - * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in - * both meshes, and returns the new mesh (the old meshes are destroyed). - * - * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. - * - * __gl_meshZapFace( fZap ) destroys a face and removes it from the - * global face list. All edges of fZap will have a NULL pointer as their - * left face. Any edges which also have a NULL pointer as their right face - * are deleted entirely (along with any isolated vertices this produces). - * An entire mesh can be deleted by zapping its faces, one at a time, - * in any order. Zapped faces cannot be used in further mesh operations! - * - * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency. - */ - -GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh ); -int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst ); -int __gl_meshDelete( GLUhalfEdge *eDel ); - -GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg ); -GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg ); -GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst ); - -GLUmesh *__gl_meshNewMesh( void ); -GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 ); -void __gl_meshDeleteMesh( GLUmesh *mesh ); -void __gl_meshZapFace( GLUface *fZap ); - -#ifdef NDEBUG -#define __gl_meshCheckMesh( mesh ) -#else -void __gl_meshCheckMesh( GLUmesh *mesh ); -#endif - -#endif diff --git a/clutter/cogl/cogl/tesselator/normal.c b/clutter/cogl/cogl/tesselator/normal.c deleted file mode 100644 index 9a3bd43..0000000 --- a/clutter/cogl/cogl/tesselator/normal.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include "mesh.h" -#include "tess.h" -#include "normal.h" -#include -#include - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define Dot(u,v) (u[0]*v[0] + u[1]*v[1] + u[2]*v[2]) - -#if 0 -static void Normalize( GLdouble v[3] ) -{ - GLdouble len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - - assert( len > 0 ); - len = sqrt( len ); - v[0] /= len; - v[1] /= len; - v[2] /= len; -} -#endif - -#undef ABS -#define ABS(x) ((x) < 0 ? -(x) : (x)) - -static int LongAxis( GLdouble v[3] ) -{ - int i = 0; - - if( ABS(v[1]) > ABS(v[0]) ) { i = 1; } - if( ABS(v[2]) > ABS(v[i]) ) { i = 2; } - return i; -} - -static void ComputeNormal( GLUtesselator *tess, GLdouble norm[3] ) -{ - GLUvertex *v, *v1, *v2; - GLdouble c, tLen2, maxLen2; - GLdouble maxVal[3], minVal[3], d1[3], d2[3], tNorm[3]; - GLUvertex *maxVert[3], *minVert[3]; - GLUvertex *vHead = &tess->mesh->vHead; - int i; - - maxVal[0] = maxVal[1] = maxVal[2] = -2 * GLU_TESS_MAX_COORD; - minVal[0] = minVal[1] = minVal[2] = 2 * GLU_TESS_MAX_COORD; - - for( v = vHead->next; v != vHead; v = v->next ) { - for( i = 0; i < 3; ++i ) { - c = v->coords[i]; - if( c < minVal[i] ) { minVal[i] = c; minVert[i] = v; } - if( c > maxVal[i] ) { maxVal[i] = c; maxVert[i] = v; } - } - } - - /* Find two vertices separated by at least 1/sqrt(3) of the maximum - * distance between any two vertices - */ - i = 0; - if( maxVal[1] - minVal[1] > maxVal[0] - minVal[0] ) { i = 1; } - if( maxVal[2] - minVal[2] > maxVal[i] - minVal[i] ) { i = 2; } - if( minVal[i] >= maxVal[i] ) { - /* All vertices are the same -- normal doesn't matter */ - norm[0] = 0; norm[1] = 0; norm[2] = 1; - return; - } - - /* Look for a third vertex which forms the triangle with maximum area - * (Length of normal == twice the triangle area) - */ - maxLen2 = 0; - v1 = minVert[i]; - v2 = maxVert[i]; - d1[0] = v1->coords[0] - v2->coords[0]; - d1[1] = v1->coords[1] - v2->coords[1]; - d1[2] = v1->coords[2] - v2->coords[2]; - for( v = vHead->next; v != vHead; v = v->next ) { - d2[0] = v->coords[0] - v2->coords[0]; - d2[1] = v->coords[1] - v2->coords[1]; - d2[2] = v->coords[2] - v2->coords[2]; - tNorm[0] = d1[1]*d2[2] - d1[2]*d2[1]; - tNorm[1] = d1[2]*d2[0] - d1[0]*d2[2]; - tNorm[2] = d1[0]*d2[1] - d1[1]*d2[0]; - tLen2 = tNorm[0]*tNorm[0] + tNorm[1]*tNorm[1] + tNorm[2]*tNorm[2]; - if( tLen2 > maxLen2 ) { - maxLen2 = tLen2; - norm[0] = tNorm[0]; - norm[1] = tNorm[1]; - norm[2] = tNorm[2]; - } - } - - if( maxLen2 <= 0 ) { - /* All points lie on a single line -- any decent normal will do */ - norm[0] = norm[1] = norm[2] = 0; - norm[LongAxis(d1)] = 1; - } -} - - -static void CheckOrientation( GLUtesselator *tess ) -{ - GLdouble area; - GLUface *f, *fHead = &tess->mesh->fHead; - GLUvertex *v, *vHead = &tess->mesh->vHead; - GLUhalfEdge *e; - - /* When we compute the normal automatically, we choose the orientation - * so that the sum of the signed areas of all contours is non-negative. - */ - area = 0; - for( f = fHead->next; f != fHead; f = f->next ) { - e = f->anEdge; - if( e->winding <= 0 ) continue; - do { - area += (e->Org->s - e->Dst->s) * (e->Org->t + e->Dst->t); - e = e->Lnext; - } while( e != f->anEdge ); - } - if( area < 0 ) { - /* Reverse the orientation by flipping all the t-coordinates */ - for( v = vHead->next; v != vHead; v = v->next ) { - v->t = - v->t; - } - tess->tUnit[0] = - tess->tUnit[0]; - tess->tUnit[1] = - tess->tUnit[1]; - tess->tUnit[2] = - tess->tUnit[2]; - } -} - -#ifdef FOR_TRITE_TEST_PROGRAM -#include -extern int RandomSweep; -#define S_UNIT_X (RandomSweep ? (2*drand48()-1) : 1.0) -#define S_UNIT_Y (RandomSweep ? (2*drand48()-1) : 0.0) -#else -#if defined(SLANTED_SWEEP) -/* The "feature merging" is not intended to be complete. There are - * special cases where edges are nearly parallel to the sweep line - * which are not implemented. The algorithm should still behave - * robustly (ie. produce a reasonable tesselation) in the presence - * of such edges, however it may miss features which could have been - * merged. We could minimize this effect by choosing the sweep line - * direction to be something unusual (ie. not parallel to one of the - * coordinate axes). - */ -#define S_UNIT_X 0.50941539564955385 /* Pre-normalized */ -#define S_UNIT_Y 0.86052074622010633 -#else -#define S_UNIT_X 1.0 -#define S_UNIT_Y 0.0 -#endif -#endif - -/* Determine the polygon normal and project vertices onto the plane - * of the polygon. - */ -void __gl_projectPolygon( GLUtesselator *tess ) -{ - GLUvertex *v, *vHead = &tess->mesh->vHead; - GLdouble norm[3]; - GLdouble *sUnit, *tUnit; - int i, computedNormal = FALSE; - - norm[0] = tess->normal[0]; - norm[1] = tess->normal[1]; - norm[2] = tess->normal[2]; - if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) { - ComputeNormal( tess, norm ); - computedNormal = TRUE; - } - sUnit = tess->sUnit; - tUnit = tess->tUnit; - i = LongAxis( norm ); - -#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT) - /* Choose the initial sUnit vector to be approximately perpendicular - * to the normal. - */ - Normalize( norm ); - - sUnit[i] = 0; - sUnit[(i+1)%3] = S_UNIT_X; - sUnit[(i+2)%3] = S_UNIT_Y; - - /* Now make it exactly perpendicular */ - w = Dot( sUnit, norm ); - sUnit[0] -= w * norm[0]; - sUnit[1] -= w * norm[1]; - sUnit[2] -= w * norm[2]; - Normalize( sUnit ); - - /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */ - tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1]; - tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2]; - tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0]; - Normalize( tUnit ); -#else - /* Project perpendicular to a coordinate axis -- better numerically */ - sUnit[i] = 0; - sUnit[(i+1)%3] = S_UNIT_X; - sUnit[(i+2)%3] = S_UNIT_Y; - - tUnit[i] = 0; - tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y; - tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X; -#endif - - /* Project the vertices onto the sweep plane */ - for( v = vHead->next; v != vHead; v = v->next ) { - v->s = Dot( v->coords, sUnit ); - v->t = Dot( v->coords, tUnit ); - } - if( computedNormal ) { - CheckOrientation( tess ); - } -} diff --git a/clutter/cogl/cogl/tesselator/normal.h b/clutter/cogl/cogl/tesselator/normal.h deleted file mode 100644 index c376ca4..0000000 --- a/clutter/cogl/cogl/tesselator/normal.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __normal_h_ -#define __normal_h_ - -#include "tess.h" - -/* __gl_projectPolygon( tess ) determines the polygon normal - * and project vertices onto the plane of the polygon. - */ -void __gl_projectPolygon( GLUtesselator *tess ); - -#endif diff --git a/clutter/cogl/cogl/tesselator/priorityq-heap.c b/clutter/cogl/cogl/tesselator/priorityq-heap.c deleted file mode 100644 index 52698b5..0000000 --- a/clutter/cogl/cogl/tesselator/priorityq-heap.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include -#include "priorityq-heap.h" -#include "memalloc.h" - -#define INIT_SIZE 32 - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#ifdef FOR_TRITE_TEST_PROGRAM -#define LEQ(x,y) (*pq->leq)(x,y) -#else -/* Violates modularity, but a little faster */ -#include "geom.h" -#define LEQ(x,y) VertLeq((GLUvertex *)x, (GLUvertex *)y) -#endif - -/* really __gl_pqHeapNewPriorityQ */ -PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) ) -{ - PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ )); - if (pq == NULL) return NULL; - - pq->size = 0; - pq->max = INIT_SIZE; - pq->nodes = (PQnode *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->nodes[0]) ); - if (pq->nodes == NULL) { - memFree(pq); - return NULL; - } - - pq->handles = (PQhandleElem *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->handles[0]) ); - if (pq->handles == NULL) { - memFree(pq->nodes); - memFree(pq); - return NULL; - } - - pq->initialized = FALSE; - pq->freeList = 0; - pq->leq = leq; - - pq->nodes[1].handle = 1; /* so that Minimum() returns NULL */ - pq->handles[1].key = NULL; - return pq; -} - -/* really __gl_pqHeapDeletePriorityQ */ -void pqDeletePriorityQ( PriorityQ *pq ) -{ - memFree( pq->handles ); - memFree( pq->nodes ); - memFree( pq ); -} - - -static void FloatDown( PriorityQ *pq, long curr ) -{ - PQnode *n = pq->nodes; - PQhandleElem *h = pq->handles; - PQhandle hCurr, hChild; - long child; - - hCurr = n[curr].handle; - for( ;; ) { - child = curr << 1; - if( child < pq->size && LEQ( h[n[child+1].handle].key, - h[n[child].handle].key )) { - ++child; - } - - assert(child <= pq->max); - - hChild = n[child].handle; - if( child > pq->size || LEQ( h[hCurr].key, h[hChild].key )) { - n[curr].handle = hCurr; - h[hCurr].node = curr; - break; - } - n[curr].handle = hChild; - h[hChild].node = curr; - curr = child; - } -} - - -static void FloatUp( PriorityQ *pq, long curr ) -{ - PQnode *n = pq->nodes; - PQhandleElem *h = pq->handles; - PQhandle hCurr, hParent; - long parent; - - hCurr = n[curr].handle; - for( ;; ) { - parent = curr >> 1; - hParent = n[parent].handle; - if( parent == 0 || LEQ( h[hParent].key, h[hCurr].key )) { - n[curr].handle = hCurr; - h[hCurr].node = curr; - break; - } - n[curr].handle = hParent; - h[hParent].node = curr; - curr = parent; - } -} - -/* really __gl_pqHeapInit */ -void pqInit( PriorityQ *pq ) -{ - long i; - - /* This method of building a heap is O(n), rather than O(n lg n). */ - - for( i = pq->size; i >= 1; --i ) { - FloatDown( pq, i ); - } - pq->initialized = TRUE; -} - -/* really __gl_pqHeapInsert */ -/* returns LONG_MAX iff out of memory */ -PQhandle pqInsert( PriorityQ *pq, PQkey keyNew ) -{ - long curr; - PQhandle free_handle; - - curr = ++ pq->size; - if( (curr*2) > pq->max ) { - PQnode *saveNodes= pq->nodes; - PQhandleElem *saveHandles= pq->handles; - - /* If the heap overflows, double its size. */ - pq->max <<= 1; - pq->nodes = (PQnode *)memRealloc( pq->nodes, - (size_t) - ((pq->max + 1) * sizeof( pq->nodes[0] ))); - if (pq->nodes == NULL) { - pq->nodes = saveNodes; /* restore ptr to free upon return */ - return LONG_MAX; - } - pq->handles = (PQhandleElem *)memRealloc( pq->handles, - (size_t) - ((pq->max + 1) * - sizeof( pq->handles[0] ))); - if (pq->handles == NULL) { - pq->handles = saveHandles; /* restore ptr to free upon return */ - return LONG_MAX; - } - } - - if( pq->freeList == 0 ) { - free_handle = curr; - } else { - free_handle = pq->freeList; - pq->freeList = pq->handles[free_handle].node; - } - - pq->nodes[curr].handle = free_handle; - pq->handles[free_handle].node = curr; - pq->handles[free_handle].key = keyNew; - - if( pq->initialized ) { - FloatUp( pq, curr ); - } - assert(free_handle != LONG_MAX); - return free_handle; -} - -/* really __gl_pqHeapExtractMin */ -PQkey pqExtractMin( PriorityQ *pq ) -{ - PQnode *n = pq->nodes; - PQhandleElem *h = pq->handles; - PQhandle hMin = n[1].handle; - PQkey min = h[hMin].key; - - if( pq->size > 0 ) { - n[1].handle = n[pq->size].handle; - h[n[1].handle].node = 1; - - h[hMin].key = NULL; - h[hMin].node = pq->freeList; - pq->freeList = hMin; - - if( -- pq->size > 0 ) { - FloatDown( pq, 1 ); - } - } - return min; -} - -/* really __gl_pqHeapDelete */ -void pqDelete( PriorityQ *pq, PQhandle hCurr ) -{ - PQnode *n = pq->nodes; - PQhandleElem *h = pq->handles; - long curr; - - assert( hCurr >= 1 && hCurr <= pq->max && h[hCurr].key != NULL ); - - curr = h[hCurr].node; - n[curr].handle = n[pq->size].handle; - h[n[curr].handle].node = curr; - - if( curr <= -- pq->size ) { - if( curr <= 1 || LEQ( h[n[curr>>1].handle].key, h[n[curr].handle].key )) { - FloatDown( pq, curr ); - } else { - FloatUp( pq, curr ); - } - } - h[hCurr].key = NULL; - h[hCurr].node = pq->freeList; - pq->freeList = hCurr; -} diff --git a/clutter/cogl/cogl/tesselator/priorityq-heap.h b/clutter/cogl/cogl/tesselator/priorityq-heap.h deleted file mode 100644 index dc9aaef..0000000 --- a/clutter/cogl/cogl/tesselator/priorityq-heap.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __priorityq_heap_h_ -#define __priorityq_heap_h_ - -/* Use #define's so that another heap implementation can use this one */ - -#define PQkey PQHeapKey -#define PQhandle PQHeapHandle -#define PriorityQ PriorityQHeap - -#define pqNewPriorityQ(leq) __gl_pqHeapNewPriorityQ(leq) -#define pqDeletePriorityQ(pq) __gl_pqHeapDeletePriorityQ(pq) - -/* The basic operations are insertion of a new key (pqInsert), - * and examination/extraction of a key whose value is minimum - * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete); - * for this purpose pqInsert returns a "handle" which is supplied - * as the argument. - * - * An initial heap may be created efficiently by calling pqInsert - * repeatedly, then calling pqInit. In any case pqInit must be called - * before any operations other than pqInsert are used. - * - * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key. - * This may also be tested with pqIsEmpty. - */ -#define pqInit(pq) __gl_pqHeapInit(pq) -#define pqInsert(pq,key) __gl_pqHeapInsert(pq,key) -#define pqMinimum(pq) __gl_pqHeapMinimum(pq) -#define pqExtractMin(pq) __gl_pqHeapExtractMin(pq) -#define pqDelete(pq,handle) __gl_pqHeapDelete(pq,handle) -#define pqIsEmpty(pq) __gl_pqHeapIsEmpty(pq) - - -/* Since we support deletion the data structure is a little more - * complicated than an ordinary heap. "nodes" is the heap itself; - * active nodes are stored in the range 1..pq->size. When the - * heap exceeds its allocated size (pq->max), its size doubles. - * The children of node i are nodes 2i and 2i+1. - * - * Each node stores an index into an array "handles". Each handle - * stores a key, plus a pointer back to the node which currently - * represents that key (ie. nodes[handles[i].node].handle == i). - */ - -typedef void *PQkey; -typedef long PQhandle; -typedef struct PriorityQ PriorityQ; - -typedef struct { PQhandle handle; } PQnode; -typedef struct { PQkey key; PQhandle node; } PQhandleElem; - -struct PriorityQ { - PQnode *nodes; - PQhandleElem *handles; - long size, max; - PQhandle freeList; - int initialized; - int (*leq)(PQkey key1, PQkey key2); -}; - -PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) ); -void pqDeletePriorityQ( PriorityQ *pq ); - -void pqInit( PriorityQ *pq ); -PQhandle pqInsert( PriorityQ *pq, PQkey key ); -PQkey pqExtractMin( PriorityQ *pq ); -void pqDelete( PriorityQ *pq, PQhandle handle ); - - -#define __gl_pqHeapMinimum(pq) ((pq)->handles[(pq)->nodes[1].handle].key) -#define __gl_pqHeapIsEmpty(pq) ((pq)->size == 0) - -#endif diff --git a/clutter/cogl/cogl/tesselator/priorityq-sort.h b/clutter/cogl/cogl/tesselator/priorityq-sort.h deleted file mode 100644 index 746cf5f..0000000 --- a/clutter/cogl/cogl/tesselator/priorityq-sort.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __priorityq_sort_h_ -#define __priorityq_sort_h_ - -#include "priorityq-heap.h" - -#undef PQkey -#undef PQhandle -#undef PriorityQ -#undef pqNewPriorityQ -#undef pqDeletePriorityQ -#undef pqInit -#undef pqInsert -#undef pqMinimum -#undef pqExtractMin -#undef pqDelete -#undef pqIsEmpty - -/* Use #define's so that another heap implementation can use this one */ - -#define PQkey PQSortKey -#define PQhandle PQSortHandle -#define PriorityQ PriorityQSort - -#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq) -#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq) - -/* The basic operations are insertion of a new key (pqInsert), - * and examination/extraction of a key whose value is minimum - * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete); - * for this purpose pqInsert returns a "handle" which is supplied - * as the argument. - * - * An initial heap may be created efficiently by calling pqInsert - * repeatedly, then calling pqInit. In any case pqInit must be called - * before any operations other than pqInsert are used. - * - * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key. - * This may also be tested with pqIsEmpty. - */ -#define pqInit(pq) __gl_pqSortInit(pq) -#define pqInsert(pq,key) __gl_pqSortInsert(pq,key) -#define pqMinimum(pq) __gl_pqSortMinimum(pq) -#define pqExtractMin(pq) __gl_pqSortExtractMin(pq) -#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle) -#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq) - - -/* Since we support deletion the data structure is a little more - * complicated than an ordinary heap. "nodes" is the heap itself; - * active nodes are stored in the range 1..pq->size. When the - * heap exceeds its allocated size (pq->max), its size doubles. - * The children of node i are nodes 2i and 2i+1. - * - * Each node stores an index into an array "handles". Each handle - * stores a key, plus a pointer back to the node which currently - * represents that key (ie. nodes[handles[i].node].handle == i). - */ - -typedef PQHeapKey PQkey; -typedef PQHeapHandle PQhandle; -typedef struct PriorityQ PriorityQ; - -struct PriorityQ { - PriorityQHeap *heap; - PQkey *keys; - PQkey **order; - PQhandle size, max; - int initialized; - int (*leq)(PQkey key1, PQkey key2); -}; - -PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) ); -void pqDeletePriorityQ( PriorityQ *pq ); - -int pqInit( PriorityQ *pq ); -PQhandle pqInsert( PriorityQ *pq, PQkey key ); -PQkey pqExtractMin( PriorityQ *pq ); -void pqDelete( PriorityQ *pq, PQhandle handle ); - -PQkey pqMinimum( PriorityQ *pq ); -int pqIsEmpty( PriorityQ *pq ); - -#endif diff --git a/clutter/cogl/cogl/tesselator/priorityq.c b/clutter/cogl/cogl/tesselator/priorityq.c deleted file mode 100644 index c6b99cc..0000000 --- a/clutter/cogl/cogl/tesselator/priorityq.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include -#include -#include /* LONG_MAX */ -#include "memalloc.h" - -/* Include all the code for the regular heap-based queue here. */ - -#include "priorityq-heap.c" - -/* Now redefine all the function names to map to their "Sort" versions. */ - -#include "priorityq-sort.h" - -/* really __gl_pqSortNewPriorityQ */ -PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) ) -{ - PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ )); - if (pq == NULL) return NULL; - - pq->heap = __gl_pqHeapNewPriorityQ( leq ); - if (pq->heap == NULL) { - memFree(pq); - return NULL; - } - - pq->keys = (PQHeapKey *)memAlloc( INIT_SIZE * sizeof(pq->keys[0]) ); - if (pq->keys == NULL) { - __gl_pqHeapDeletePriorityQ(pq->heap); - memFree(pq); - return NULL; - } - - pq->size = 0; - pq->max = INIT_SIZE; - pq->initialized = FALSE; - pq->leq = leq; - return pq; -} - -/* really __gl_pqSortDeletePriorityQ */ -void pqDeletePriorityQ( PriorityQ *pq ) -{ - assert(pq != NULL); - if (pq->heap != NULL) __gl_pqHeapDeletePriorityQ( pq->heap ); - if (pq->order != NULL) memFree( pq->order ); - if (pq->keys != NULL) memFree( pq->keys ); - memFree( pq ); -} - - -#define LT(x,y) (! LEQ(y,x)) -#define GT(x,y) (! LEQ(x,y)) -#define Swap(a,b) do{PQkey *tmp = *a; *a = *b; *b = tmp;}while(0) - -/* really __gl_pqSortInit */ -int pqInit( PriorityQ *pq ) -{ - PQkey **p, **r, **i, **j, *piv; - struct { PQkey **p, **r; } Stack[50], *top = Stack; - unsigned long seed = 2016473283; - - /* Create an array of indirect pointers to the keys, so that we - * the handles we have returned are still valid. - */ -/* - pq->order = (PQHeapKey **)memAlloc( (size_t) - (pq->size * sizeof(pq->order[0])) ); -*/ - pq->order = (PQHeapKey **)memAlloc( (size_t) - ((pq->size+1) * sizeof(pq->order[0])) ); -/* the previous line is a patch to compensate for the fact that IBM */ -/* machines return a null on a malloc of zero bytes (unlike SGI), */ -/* so we have to put in this defense to guard against a memory */ -/* fault four lines down. from fossum@austin.ibm.com. */ - if (pq->order == NULL) return 0; - - p = pq->order; - r = p + pq->size - 1; - for( piv = pq->keys, i = p; i <= r; ++piv, ++i ) { - *i = piv; - } - - /* Sort the indirect pointers in descending order, - * using randomized Quicksort - */ - top->p = p; top->r = r; ++top; - while( --top >= Stack ) { - p = top->p; - r = top->r; - while( r > p + 10 ) { - seed = seed * 1539415821 + 1; - i = p + seed % (r - p + 1); - piv = *i; - *i = *p; - *p = piv; - i = p - 1; - j = r + 1; - do { - do { ++i; } while( GT( **i, *piv )); - do { --j; } while( LT( **j, *piv )); - Swap( i, j ); - } while( i < j ); - Swap( i, j ); /* Undo last swap */ - if( i - p < r - j ) { - top->p = j+1; top->r = r; ++top; - r = i-1; - } else { - top->p = p; top->r = i-1; ++top; - p = j+1; - } - } - /* Insertion sort small lists */ - for( i = p+1; i <= r; ++i ) { - piv = *i; - for( j = i; j > p && LT( **(j-1), *piv ); --j ) { - *j = *(j-1); - } - *j = piv; - } - } - pq->max = pq->size; - pq->initialized = TRUE; - __gl_pqHeapInit( pq->heap ); /* always succeeds */ - -#ifndef NDEBUG - p = pq->order; - r = p + pq->size - 1; - for( i = p; i < r; ++i ) { - assert( LEQ( **(i+1), **i )); - } -#endif - - return 1; -} - -/* really __gl_pqSortInsert */ -/* returns LONG_MAX iff out of memory */ -PQhandle pqInsert( PriorityQ *pq, PQkey keyNew ) -{ - long curr; - - if( pq->initialized ) { - return __gl_pqHeapInsert( pq->heap, keyNew ); - } - curr = pq->size; - if( ++ pq->size >= pq->max ) { - PQkey *saveKey= pq->keys; - - /* If the heap overflows, double its size. */ - pq->max <<= 1; - pq->keys = (PQHeapKey *)memRealloc( pq->keys, - (size_t) - (pq->max * sizeof( pq->keys[0] ))); - if (pq->keys == NULL) { - pq->keys = saveKey; /* restore ptr to free upon return */ - return LONG_MAX; - } - } - assert(curr != LONG_MAX); - pq->keys[curr] = keyNew; - - /* Negative handles index the sorted array. */ - return -(curr+1); -} - -/* really __gl_pqSortExtractMin */ -PQkey pqExtractMin( PriorityQ *pq ) -{ - PQkey sortMin, heapMin; - - if( pq->size == 0 ) { - return __gl_pqHeapExtractMin( pq->heap ); - } - sortMin = *(pq->order[pq->size-1]); - if( ! __gl_pqHeapIsEmpty( pq->heap )) { - heapMin = __gl_pqHeapMinimum( pq->heap ); - if( LEQ( heapMin, sortMin )) { - return __gl_pqHeapExtractMin( pq->heap ); - } - } - do { - -- pq->size; - } while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL ); - return sortMin; -} - -/* really __gl_pqSortMinimum */ -PQkey pqMinimum( PriorityQ *pq ) -{ - PQkey sortMin, heapMin; - - if( pq->size == 0 ) { - return __gl_pqHeapMinimum( pq->heap ); - } - sortMin = *(pq->order[pq->size-1]); - if( ! __gl_pqHeapIsEmpty( pq->heap )) { - heapMin = __gl_pqHeapMinimum( pq->heap ); - if( LEQ( heapMin, sortMin )) { - return heapMin; - } - } - return sortMin; -} - -/* really __gl_pqSortIsEmpty */ -int pqIsEmpty( PriorityQ *pq ) -{ - return (pq->size == 0) && __gl_pqHeapIsEmpty( pq->heap ); -} - -/* really __gl_pqSortDelete */ -void pqDelete( PriorityQ *pq, PQhandle curr ) -{ - if( curr >= 0 ) { - __gl_pqHeapDelete( pq->heap, curr ); - return; - } - curr = -(curr+1); - assert( curr < pq->max && pq->keys[curr] != NULL ); - - pq->keys[curr] = NULL; - while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL ) { - -- pq->size; - } -} diff --git a/clutter/cogl/cogl/tesselator/priorityq.h b/clutter/cogl/cogl/tesselator/priorityq.h deleted file mode 100644 index 746cf5f..0000000 --- a/clutter/cogl/cogl/tesselator/priorityq.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __priorityq_sort_h_ -#define __priorityq_sort_h_ - -#include "priorityq-heap.h" - -#undef PQkey -#undef PQhandle -#undef PriorityQ -#undef pqNewPriorityQ -#undef pqDeletePriorityQ -#undef pqInit -#undef pqInsert -#undef pqMinimum -#undef pqExtractMin -#undef pqDelete -#undef pqIsEmpty - -/* Use #define's so that another heap implementation can use this one */ - -#define PQkey PQSortKey -#define PQhandle PQSortHandle -#define PriorityQ PriorityQSort - -#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq) -#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq) - -/* The basic operations are insertion of a new key (pqInsert), - * and examination/extraction of a key whose value is minimum - * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete); - * for this purpose pqInsert returns a "handle" which is supplied - * as the argument. - * - * An initial heap may be created efficiently by calling pqInsert - * repeatedly, then calling pqInit. In any case pqInit must be called - * before any operations other than pqInsert are used. - * - * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key. - * This may also be tested with pqIsEmpty. - */ -#define pqInit(pq) __gl_pqSortInit(pq) -#define pqInsert(pq,key) __gl_pqSortInsert(pq,key) -#define pqMinimum(pq) __gl_pqSortMinimum(pq) -#define pqExtractMin(pq) __gl_pqSortExtractMin(pq) -#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle) -#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq) - - -/* Since we support deletion the data structure is a little more - * complicated than an ordinary heap. "nodes" is the heap itself; - * active nodes are stored in the range 1..pq->size. When the - * heap exceeds its allocated size (pq->max), its size doubles. - * The children of node i are nodes 2i and 2i+1. - * - * Each node stores an index into an array "handles". Each handle - * stores a key, plus a pointer back to the node which currently - * represents that key (ie. nodes[handles[i].node].handle == i). - */ - -typedef PQHeapKey PQkey; -typedef PQHeapHandle PQhandle; -typedef struct PriorityQ PriorityQ; - -struct PriorityQ { - PriorityQHeap *heap; - PQkey *keys; - PQkey **order; - PQhandle size, max; - int initialized; - int (*leq)(PQkey key1, PQkey key2); -}; - -PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) ); -void pqDeletePriorityQ( PriorityQ *pq ); - -int pqInit( PriorityQ *pq ); -PQhandle pqInsert( PriorityQ *pq, PQkey key ); -PQkey pqExtractMin( PriorityQ *pq ); -void pqDelete( PriorityQ *pq, PQhandle handle ); - -PQkey pqMinimum( PriorityQ *pq ); -int pqIsEmpty( PriorityQ *pq ); - -#endif diff --git a/clutter/cogl/cogl/tesselator/render.c b/clutter/cogl/cogl/tesselator/render.c deleted file mode 100644 index bca836f..0000000 --- a/clutter/cogl/cogl/tesselator/render.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include -#include -#include "mesh.h" -#include "tess.h" -#include "render.h" - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/* This structure remembers the information we need about a primitive - * to be able to render it later, once we have determined which - * primitive is able to use the most triangles. - */ -struct FaceCount { - long size; /* number of triangles used */ - GLUhalfEdge *eStart; /* edge where this primitive starts */ - void (*render)(GLUtesselator *, GLUhalfEdge *, long); - /* routine to render this primitive */ -}; - -static struct FaceCount MaximumFan( GLUhalfEdge *eOrig ); -static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig ); - -static void RenderFan( GLUtesselator *tess, GLUhalfEdge *eStart, long size ); -static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *eStart, long size ); -static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *eStart, - long size ); - -static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig ); -static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *head ); - - - -/************************ Strips and Fans decomposition ******************/ - -/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle - * fans, strips, and separate triangles. A substantial effort is made - * to use as few rendering primitives as possible (ie. to make the fans - * and strips as large as possible). - * - * The rendering output is provided as callbacks (see the api). - */ -void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh ) -{ - GLUface *f; - - /* Make a list of separate triangles so we can render them all at once */ - tess->lonelyTriList = NULL; - - for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) { - f->marked = FALSE; - } - for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) { - - /* We examine all faces in an arbitrary order. Whenever we find - * an unprocessed face F, we output a group of faces including F - * whose size is maximum. - */ - if( f->inside && ! f->marked ) { - RenderMaximumFaceGroup( tess, f ); - assert( f->marked ); - } - } - if( tess->lonelyTriList != NULL ) { - RenderLonelyTriangles( tess, tess->lonelyTriList ); - tess->lonelyTriList = NULL; - } -} - - -static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig ) -{ - /* We want to find the largest triangle fan or strip of unmarked faces - * which includes the given face fOrig. There are 3 possible fans - * passing through fOrig (one centered at each vertex), and 3 possible - * strips (one for each CCW permutation of the vertices). Our strategy - * is to try all of these, and take the primitive which uses the most - * triangles (a greedy approach). - */ - GLUhalfEdge *e = fOrig->anEdge; - struct FaceCount max, newFace; - - max.size = 1; - max.eStart = e; - max.render = &RenderTriangle; - - if( ! tess->flagBoundary ) { - newFace = MaximumFan( e ); if( newFace.size > max.size ) { max = newFace; } - newFace = MaximumFan( e->Lnext ); if( newFace.size > max.size ) { max = newFace; } - newFace = MaximumFan( e->Lprev ); if( newFace.size > max.size ) { max = newFace; } - - newFace = MaximumStrip( e ); if( newFace.size > max.size ) { max = newFace; } - newFace = MaximumStrip( e->Lnext ); if( newFace.size > max.size ) { max = newFace; } - newFace = MaximumStrip( e->Lprev ); if( newFace.size > max.size ) { max = newFace; } - } - (*(max.render))( tess, max.eStart, max.size ); -} - - -/* Macros which keep track of faces we have marked temporarily, and allow - * us to backtrack when necessary. With triangle fans, this is not - * really necessary, since the only awkward case is a loop of triangles - * around a single origin vertex. However with strips the situation is - * more complicated, and we need a general tracking method like the - * one here. - */ -#define Marked(f) (! (f)->inside || (f)->marked) - -#define AddToTrail(f,t) ((f)->trail = (t), (t) = (f), (f)->marked = TRUE) - -#define FreeTrail(t) do { \ - while( (t) != NULL ) { \ - (t)->marked = FALSE; t = (t)->trail; \ - } \ - } while(0) /* absorb trailing semicolon */ - - - -static struct FaceCount MaximumFan( GLUhalfEdge *eOrig ) -{ - /* eOrig->Lface is the face we want to render. We want to find the size - * of a maximal fan around eOrig->Org. To do this we just walk around - * the origin vertex as far as possible in both directions. - */ - struct FaceCount newFace = { 0, NULL, &RenderFan }; - GLUface *trail = NULL; - GLUhalfEdge *e; - - for( e = eOrig; ! Marked( e->Lface ); e = e->Onext ) { - AddToTrail( e->Lface, trail ); - ++newFace.size; - } - for( e = eOrig; ! Marked( e->Rface ); e = e->Oprev ) { - AddToTrail( e->Rface, trail ); - ++newFace.size; - } - newFace.eStart = e; - /*LINTED*/ - FreeTrail( trail ); - return newFace; -} - - -#define IsEven(n) (((n) & 1) == 0) - -static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig ) -{ - /* Here we are looking for a maximal strip that contains the vertices - * eOrig->Org, eOrig->Dst, eOrig->Lnext->Dst (in that order or the - * reverse, such that all triangles are oriented CCW). - * - * Again we walk forward and backward as far as possible. However for - * strips there is a twist: to get CCW orientations, there must be - * an *even* number of triangles in the strip on one side of eOrig. - * We walk the strip starting on a side with an even number of triangles; - * if both side have an odd number, we are forced to shorten one side. - */ - struct FaceCount newFace = { 0, NULL, &RenderStrip }; - long headSize = 0, tailSize = 0; - GLUface *trail = NULL; - GLUhalfEdge *e, *eTail, *eHead; - - for( e = eOrig; ! Marked( e->Lface ); ++tailSize, e = e->Onext ) { - AddToTrail( e->Lface, trail ); - ++tailSize; - e = e->Dprev; - if( Marked( e->Lface )) break; - AddToTrail( e->Lface, trail ); - } - eTail = e; - - for( e = eOrig; ! Marked( e->Rface ); ++headSize, e = e->Dnext ) { - AddToTrail( e->Rface, trail ); - ++headSize; - e = e->Oprev; - if( Marked( e->Rface )) break; - AddToTrail( e->Rface, trail ); - } - eHead = e; - - newFace.size = tailSize + headSize; - if( IsEven( tailSize )) { - newFace.eStart = eTail->Sym; - } else if( IsEven( headSize )) { - newFace.eStart = eHead; - } else { - /* Both sides have odd length, we must shorten one of them. In fact, - * we must start from eHead to guarantee inclusion of eOrig->Lface. - */ - --newFace.size; - newFace.eStart = eHead->Onext; - } - /*LINTED*/ - FreeTrail( trail ); - return newFace; -} - - -static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *e, long size ) -{ - /* Just add the triangle to a triangle list, so we can render all - * the separate triangles at once. - */ - assert( size == 1 ); - AddToTrail( e->Lface, tess->lonelyTriList ); -} - - -static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *f ) -{ - /* Now we render all the separate triangles which could not be - * grouped into a triangle fan or strip. - */ - GLUhalfEdge *e; - int newState; - int edgeState = -1; /* force edge state output for first vertex */ - - CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLES ); - - for( ; f != NULL; f = f->trail ) { - /* Loop once for each edge (there will always be 3 edges) */ - - e = f->anEdge; - do { - if( tess->flagBoundary ) { - /* Set the "edge state" to TRUE just before we output the - * first vertex of each edge on the polygon boundary. - */ - newState = ! e->Rface->inside; - if( edgeState != newState ) { - edgeState = newState; - CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA( edgeState ); - } - } - CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); - - e = e->Lnext; - } while( e != f->anEdge ); - } - CALL_END_OR_END_DATA(); -} - - -static void RenderFan( GLUtesselator *tess, GLUhalfEdge *e, long size ) -{ - /* Render as many CCW triangles as possible in a fan starting from - * edge "e". The fan *should* contain exactly "size" triangles - * (otherwise we've goofed up somewhere). - */ - CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_FAN ); - CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); - CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); - - while( ! Marked( e->Lface )) { - e->Lface->marked = TRUE; - --size; - e = e->Onext; - CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); - } - - assert( size == 0 ); - CALL_END_OR_END_DATA(); -} - - -static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *e, long size ) -{ - /* Render as many CCW triangles as possible in a strip starting from - * edge "e". The strip *should* contain exactly "size" triangles - * (otherwise we've goofed up somewhere). - */ - CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_STRIP ); - CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); - CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); - - while( ! Marked( e->Lface )) { - e->Lface->marked = TRUE; - --size; - e = e->Dprev; - CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); - if( Marked( e->Lface )) break; - - e->Lface->marked = TRUE; - --size; - e = e->Onext; - CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data ); - } - - assert( size == 0 ); - CALL_END_OR_END_DATA(); -} - - -/************************ Boundary contour decomposition ******************/ - -/* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one - * contour for each face marked "inside". The rendering output is - * provided as callbacks (see the api). - */ -void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh ) -{ - GLUface *f; - GLUhalfEdge *e; - - for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) { - if( f->inside ) { - CALL_BEGIN_OR_BEGIN_DATA( GL_LINE_LOOP ); - e = f->anEdge; - do { - CALL_VERTEX_OR_VERTEX_DATA( e->Org->data ); - e = e->Lnext; - } while( e != f->anEdge ); - CALL_END_OR_END_DATA(); - } - } -} - - -/************************ Quick-and-dirty decomposition ******************/ - -#define SIGN_INCONSISTENT 2 - -static int ComputeNormal( GLUtesselator *tess, GLdouble norm[3], int check ) -/* - * If check==FALSE, we compute the polygon normal and place it in norm[]. - * If check==TRUE, we check that each triangle in the fan from v0 has a - * consistent orientation with respect to norm[]. If triangles are - * consistently oriented CCW, return 1; if CW, return -1; if all triangles - * are degenerate return 0; otherwise (no consistent orientation) return - * SIGN_INCONSISTENT. - */ -{ - CachedVertex *v0 = tess->cache; - CachedVertex *vn = v0 + tess->cacheCount; - CachedVertex *vc; - GLdouble dot, xc, yc, zc, xp, yp, zp, n[3]; - int sign = 0; - - /* Find the polygon normal. It is important to get a reasonable - * normal even when the polygon is self-intersecting (eg. a bowtie). - * Otherwise, the computed normal could be very tiny, but perpendicular - * to the true plane of the polygon due to numerical noise. Then all - * the triangles would appear to be degenerate and we would incorrectly - * decompose the polygon as a fan (or simply not render it at all). - * - * We use a sum-of-triangles normal algorithm rather than the more - * efficient sum-of-trapezoids method (used in CheckOrientation() - * in normal.c). This lets us explicitly reverse the signed area - * of some triangles to get a reasonable normal in the self-intersecting - * case. - */ - if( ! check ) { - norm[0] = norm[1] = norm[2] = 0.0; - } - - vc = v0 + 1; - xc = vc->coords[0] - v0->coords[0]; - yc = vc->coords[1] - v0->coords[1]; - zc = vc->coords[2] - v0->coords[2]; - while( ++vc < vn ) { - xp = xc; yp = yc; zp = zc; - xc = vc->coords[0] - v0->coords[0]; - yc = vc->coords[1] - v0->coords[1]; - zc = vc->coords[2] - v0->coords[2]; - - /* Compute (vp - v0) cross (vc - v0) */ - n[0] = yp*zc - zp*yc; - n[1] = zp*xc - xp*zc; - n[2] = xp*yc - yp*xc; - - dot = n[0]*norm[0] + n[1]*norm[1] + n[2]*norm[2]; - if( ! check ) { - /* Reverse the contribution of back-facing triangles to get - * a reasonable normal for self-intersecting polygons (see above) - */ - if( dot >= 0 ) { - norm[0] += n[0]; norm[1] += n[1]; norm[2] += n[2]; - } else { - norm[0] -= n[0]; norm[1] -= n[1]; norm[2] -= n[2]; - } - } else if( dot != 0 ) { - /* Check the new orientation for consistency with previous triangles */ - if( dot > 0 ) { - if( sign < 0 ) return SIGN_INCONSISTENT; - sign = 1; - } else { - if( sign > 0 ) return SIGN_INCONSISTENT; - sign = -1; - } - } - } - return sign; -} - -/* __gl_renderCache( tess ) takes a single contour and tries to render it - * as a triangle fan. This handles convex polygons, as well as some - * non-convex polygons if we get lucky. - * - * Returns TRUE if the polygon was successfully rendered. The rendering - * output is provided as callbacks (see the api). - */ -GLboolean __gl_renderCache( GLUtesselator *tess ) -{ - CachedVertex *v0 = tess->cache; - CachedVertex *vn = v0 + tess->cacheCount; - CachedVertex *vc; - GLdouble norm[3]; - int sign; - - if( tess->cacheCount < 3 ) { - /* Degenerate contour -- no output */ - return TRUE; - } - - norm[0] = tess->normal[0]; - norm[1] = tess->normal[1]; - norm[2] = tess->normal[2]; - if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) { - ComputeNormal( tess, norm, FALSE ); - } - - sign = ComputeNormal( tess, norm, TRUE ); - if( sign == SIGN_INCONSISTENT ) { - /* Fan triangles did not have a consistent orientation */ - return FALSE; - } - if( sign == 0 ) { - /* All triangles were degenerate */ - return TRUE; - } - - /* Make sure we do the right thing for each winding rule */ - switch( tess->windingRule ) { - case GLU_TESS_WINDING_ODD: - case GLU_TESS_WINDING_NONZERO: - break; - case GLU_TESS_WINDING_POSITIVE: - if( sign < 0 ) return TRUE; - break; - case GLU_TESS_WINDING_NEGATIVE: - if( sign > 0 ) return TRUE; - break; - case GLU_TESS_WINDING_ABS_GEQ_TWO: - return TRUE; - } - - CALL_BEGIN_OR_BEGIN_DATA( tess->boundaryOnly ? GL_LINE_LOOP - : (tess->cacheCount > 3) ? GL_TRIANGLE_FAN - : GL_TRIANGLES ); - - CALL_VERTEX_OR_VERTEX_DATA( v0->data ); - if( sign > 0 ) { - for( vc = v0+1; vc < vn; ++vc ) { - CALL_VERTEX_OR_VERTEX_DATA( vc->data ); - } - } else { - for( vc = vn-1; vc > v0; --vc ) { - CALL_VERTEX_OR_VERTEX_DATA( vc->data ); - } - } - CALL_END_OR_END_DATA(); - return TRUE; -} diff --git a/clutter/cogl/cogl/tesselator/render.h b/clutter/cogl/cogl/tesselator/render.h deleted file mode 100644 index a298c9a..0000000 --- a/clutter/cogl/cogl/tesselator/render.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __render_h_ -#define __render_h_ - -#include "mesh.h" - -/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle - * fans, strips, and separate triangles. A substantial effort is made - * to use as few rendering primitives as possible (ie. to make the fans - * and strips as large as possible). - * - * The rendering output is provided as callbacks (see the api). - */ -void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh ); -void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh ); - -GLboolean __gl_renderCache( GLUtesselator *tess ); - -#endif diff --git a/clutter/cogl/cogl/tesselator/sweep.c b/clutter/cogl/cogl/tesselator/sweep.c deleted file mode 100644 index eca828f..0000000 --- a/clutter/cogl/cogl/tesselator/sweep.c +++ /dev/null @@ -1,1361 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include -#include -#include /* longjmp */ -#include /* LONG_MAX */ - -#include "mesh.h" -#include "geom.h" -#include "tess.h" -#include "dict.h" -#include "priorityq.h" -#include "memalloc.h" -#include "sweep.h" - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#ifdef FOR_TRITE_TEST_PROGRAM -extern void DebugEvent( GLUtesselator *tess ); -#else -#define DebugEvent( tess ) -#endif - -/* - * Invariants for the Edge Dictionary. - * - each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2) - * at any valid location of the sweep event - * - if EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2 - * share a common endpoint - * - for each e, e->Dst has been processed, but not e->Org - * - each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org) - * where "event" is the current sweep line event. - * - no edge e has zero length - * - * Invariants for the Mesh (the processed portion). - * - the portion of the mesh left of the sweep line is a planar graph, - * ie. there is *some* way to embed it in the plane - * - no processed edge has zero length - * - no two processed vertices have identical coordinates - * - each "inside" region is monotone, ie. can be broken into two chains - * of monotonically increasing vertices according to VertLeq(v1,v2) - * - a non-invariant: these chains may intersect (very slightly) - * - * Invariants for the Sweep. - * - if none of the edges incident to the event vertex have an activeRegion - * (ie. none of these edges are in the edge dictionary), then the vertex - * has only right-going edges. - * - if an edge is marked "fixUpperEdge" (it is a temporary edge introduced - * by ConnectRightVertex), then it is the only right-going edge from - * its associated vertex. (This says that these edges exist only - * when it is necessary.) - */ - -#undef MAX -#undef MIN -#define MAX(x,y) ((x) >= (y) ? (x) : (y)) -#define MIN(x,y) ((x) <= (y) ? (x) : (y)) - -/* When we merge two edges into one, we need to compute the combined - * winding of the new edge. - */ -#define AddWinding(eDst,eSrc) (eDst->winding += eSrc->winding, \ - eDst->Sym->winding += eSrc->Sym->winding) - -static void SweepEvent( GLUtesselator *tess, GLUvertex *vEvent ); -static void WalkDirtyRegions( GLUtesselator *tess, ActiveRegion *regUp ); -static int CheckForRightSplice( GLUtesselator *tess, ActiveRegion *regUp ); - -static int EdgeLeq( GLUtesselator *tess, ActiveRegion *reg1, - ActiveRegion *reg2 ) -/* - * Both edges must be directed from right to left (this is the canonical - * direction for the upper edge of each region). - * - * The strategy is to evaluate a "t" value for each edge at the - * current sweep line position, given by tess->event. The calculations - * are designed to be very stable, but of course they are not perfect. - * - * Special case: if both edge destinations are at the sweep event, - * we sort the edges by slope (they would otherwise compare equally). - */ -{ - GLUvertex *event = tess->event; - GLUhalfEdge *e1, *e2; - GLdouble t1, t2; - - e1 = reg1->eUp; - e2 = reg2->eUp; - - if( e1->Dst == event ) { - if( e2->Dst == event ) { - /* Two edges right of the sweep line which meet at the sweep event. - * Sort them by slope. - */ - if( VertLeq( e1->Org, e2->Org )) { - return EdgeSign( e2->Dst, e1->Org, e2->Org ) <= 0; - } - return EdgeSign( e1->Dst, e2->Org, e1->Org ) >= 0; - } - return EdgeSign( e2->Dst, event, e2->Org ) <= 0; - } - if( e2->Dst == event ) { - return EdgeSign( e1->Dst, event, e1->Org ) >= 0; - } - - /* General case - compute signed distance *from* e1, e2 to event */ - t1 = EdgeEval( e1->Dst, event, e1->Org ); - t2 = EdgeEval( e2->Dst, event, e2->Org ); - return (t1 >= t2); -} - - -static void DeleteRegion( GLUtesselator *tess, ActiveRegion *reg ) -{ - if( reg->fixUpperEdge ) { - /* It was created with zero winding number, so it better be - * deleted with zero winding number (ie. it better not get merged - * with a real edge). - */ - assert( reg->eUp->winding == 0 ); - } - reg->eUp->activeRegion = NULL; - dictDelete( tess->dict, reg->nodeUp ); /* __gl_dictListDelete */ - memFree( reg ); -} - - -static int FixUpperEdge( ActiveRegion *reg, GLUhalfEdge *newEdge ) -/* - * Replace an upper edge which needs fixing (see ConnectRightVertex). - */ -{ - assert( reg->fixUpperEdge ); - if ( !__gl_meshDelete( reg->eUp ) ) return 0; - reg->fixUpperEdge = FALSE; - reg->eUp = newEdge; - newEdge->activeRegion = reg; - - return 1; -} - -static ActiveRegion *TopLeftRegion( ActiveRegion *reg ) -{ - GLUvertex *org = reg->eUp->Org; - GLUhalfEdge *e; - - /* Find the region above the uppermost edge with the same origin */ - do { - reg = RegionAbove( reg ); - } while( reg->eUp->Org == org ); - - /* If the edge above was a temporary edge introduced by ConnectRightVertex, - * now is the time to fix it. - */ - if( reg->fixUpperEdge ) { - e = __gl_meshConnect( RegionBelow(reg)->eUp->Sym, reg->eUp->Lnext ); - if (e == NULL) return NULL; - if ( !FixUpperEdge( reg, e ) ) return NULL; - reg = RegionAbove( reg ); - } - return reg; -} - -static ActiveRegion *TopRightRegion( ActiveRegion *reg ) -{ - GLUvertex *dst = reg->eUp->Dst; - - /* Find the region above the uppermost edge with the same destination */ - do { - reg = RegionAbove( reg ); - } while( reg->eUp->Dst == dst ); - return reg; -} - -static ActiveRegion *AddRegionBelow( GLUtesselator *tess, - ActiveRegion *regAbove, - GLUhalfEdge *eNewUp ) -/* - * Add a new active region to the sweep line, *somewhere* below "regAbove" - * (according to where the new edge belongs in the sweep-line dictionary). - * The upper edge of the new region will be "eNewUp". - * Winding number and "inside" flag are not updated. - */ -{ - ActiveRegion *regNew = (ActiveRegion *)memAlloc( sizeof( ActiveRegion )); - if (regNew == NULL) longjmp(tess->env,1); - - regNew->eUp = eNewUp; - /* __gl_dictListInsertBefore */ - regNew->nodeUp = dictInsertBefore( tess->dict, regAbove->nodeUp, regNew ); - if (regNew->nodeUp == NULL) longjmp(tess->env,1); - regNew->fixUpperEdge = FALSE; - regNew->sentinel = FALSE; - regNew->dirty = FALSE; - - eNewUp->activeRegion = regNew; - return regNew; -} - -static GLboolean IsWindingInside( GLUtesselator *tess, int n ) -{ - switch( tess->windingRule ) { - case GLU_TESS_WINDING_ODD: - return (n & 1); - case GLU_TESS_WINDING_NONZERO: - return (n != 0); - case GLU_TESS_WINDING_POSITIVE: - return (n > 0); - case GLU_TESS_WINDING_NEGATIVE: - return (n < 0); - case GLU_TESS_WINDING_ABS_GEQ_TWO: - return (n >= 2) || (n <= -2); - } - /*LINTED*/ - assert( FALSE ); - /*NOTREACHED*/ - return GL_FALSE; /* avoid compiler complaints */ -} - - -static void ComputeWinding( GLUtesselator *tess, ActiveRegion *reg ) -{ - reg->windingNumber = RegionAbove(reg)->windingNumber + reg->eUp->winding; - reg->inside = IsWindingInside( tess, reg->windingNumber ); -} - - -static void FinishRegion( GLUtesselator *tess, ActiveRegion *reg ) -/* - * Delete a region from the sweep line. This happens when the upper - * and lower chains of a region meet (at a vertex on the sweep line). - * The "inside" flag is copied to the appropriate mesh face (we could - * not do this before -- since the structure of the mesh is always - * changing, this face may not have even existed until now). - */ -{ - GLUhalfEdge *e = reg->eUp; - GLUface *f = e->Lface; - - f->inside = reg->inside; - f->anEdge = e; /* optimization for __gl_meshTessellateMonoRegion() */ - DeleteRegion( tess, reg ); -} - - -static GLUhalfEdge *FinishLeftRegions( GLUtesselator *tess, - ActiveRegion *regFirst, ActiveRegion *regLast ) -/* - * We are given a vertex with one or more left-going edges. All affected - * edges should be in the edge dictionary. Starting at regFirst->eUp, - * we walk down deleting all regions where both edges have the same - * origin vOrg. At the same time we copy the "inside" flag from the - * active region to the face, since at this point each face will belong - * to at most one region (this was not necessarily true until this point - * in the sweep). The walk stops at the region above regLast; if regLast - * is NULL we walk as far as possible. At the same time we relink the - * mesh if necessary, so that the ordering of edges around vOrg is the - * same as in the dictionary. - */ -{ - ActiveRegion *reg, *regPrev; - GLUhalfEdge *e, *ePrev; - - regPrev = regFirst; - ePrev = regFirst->eUp; - while( regPrev != regLast ) { - regPrev->fixUpperEdge = FALSE; /* placement was OK */ - reg = RegionBelow( regPrev ); - e = reg->eUp; - if( e->Org != ePrev->Org ) { - if( ! reg->fixUpperEdge ) { - /* Remove the last left-going edge. Even though there are no further - * edges in the dictionary with this origin, there may be further - * such edges in the mesh (if we are adding left edges to a vertex - * that has already been processed). Thus it is important to call - * FinishRegion rather than just DeleteRegion. - */ - FinishRegion( tess, regPrev ); - break; - } - /* If the edge below was a temporary edge introduced by - * ConnectRightVertex, now is the time to fix it. - */ - e = __gl_meshConnect( ePrev->Lprev, e->Sym ); - if (e == NULL) longjmp(tess->env,1); - if ( !FixUpperEdge( reg, e ) ) longjmp(tess->env,1); - } - - /* Relink edges so that ePrev->Onext == e */ - if( ePrev->Onext != e ) { - if ( !__gl_meshSplice( e->Oprev, e ) ) longjmp(tess->env,1); - if ( !__gl_meshSplice( ePrev, e ) ) longjmp(tess->env,1); - } - FinishRegion( tess, regPrev ); /* may change reg->eUp */ - ePrev = reg->eUp; - regPrev = reg; - } - return ePrev; -} - - -static void AddRightEdges( GLUtesselator *tess, ActiveRegion *regUp, - GLUhalfEdge *eFirst, GLUhalfEdge *eLast, GLUhalfEdge *eTopLeft, - GLboolean cleanUp ) -/* - * Purpose: insert right-going edges into the edge dictionary, and update - * winding numbers and mesh connectivity appropriately. All right-going - * edges share a common origin vOrg. Edges are inserted CCW starting at - * eFirst; the last edge inserted is eLast->Oprev. If vOrg has any - * left-going edges already processed, then eTopLeft must be the edge - * such that an imaginary upward vertical segment from vOrg would be - * contained between eTopLeft->Oprev and eTopLeft; otherwise eTopLeft - * should be NULL. - */ -{ - ActiveRegion *reg, *regPrev; - GLUhalfEdge *e, *ePrev; - int firstTime = TRUE; - - /* Insert the new right-going edges in the dictionary */ - e = eFirst; - do { - assert( VertLeq( e->Org, e->Dst )); - AddRegionBelow( tess, regUp, e->Sym ); - e = e->Onext; - } while ( e != eLast ); - - /* Walk *all* right-going edges from e->Org, in the dictionary order, - * updating the winding numbers of each region, and re-linking the mesh - * edges to match the dictionary ordering (if necessary). - */ - if( eTopLeft == NULL ) { - eTopLeft = RegionBelow( regUp )->eUp->Rprev; - } - regPrev = regUp; - ePrev = eTopLeft; - for( ;; ) { - reg = RegionBelow( regPrev ); - e = reg->eUp->Sym; - if( e->Org != ePrev->Org ) break; - - if( e->Onext != ePrev ) { - /* Unlink e from its current position, and relink below ePrev */ - if ( !__gl_meshSplice( e->Oprev, e ) ) longjmp(tess->env,1); - if ( !__gl_meshSplice( ePrev->Oprev, e ) ) longjmp(tess->env,1); - } - /* Compute the winding number and "inside" flag for the new regions */ - reg->windingNumber = regPrev->windingNumber - e->winding; - reg->inside = IsWindingInside( tess, reg->windingNumber ); - - /* Check for two outgoing edges with same slope -- process these - * before any intersection tests (see example in __gl_computeInterior). - */ - regPrev->dirty = TRUE; - if( ! firstTime && CheckForRightSplice( tess, regPrev )) { - AddWinding( e, ePrev ); - DeleteRegion( tess, regPrev ); - if ( !__gl_meshDelete( ePrev ) ) longjmp(tess->env,1); - } - firstTime = FALSE; - regPrev = reg; - ePrev = e; - } - regPrev->dirty = TRUE; - assert( regPrev->windingNumber - e->winding == reg->windingNumber ); - - if( cleanUp ) { - /* Check for intersections between newly adjacent edges. */ - WalkDirtyRegions( tess, regPrev ); - } -} - - -static void CallCombine( GLUtesselator *tess, GLUvertex *isect, - void *data[4], GLfloat weights[4], int needed ) -{ - GLdouble coords[3]; - - /* Copy coord data in case the callback changes it. */ - coords[0] = isect->coords[0]; - coords[1] = isect->coords[1]; - coords[2] = isect->coords[2]; - - isect->data = NULL; - CALL_COMBINE_OR_COMBINE_DATA( coords, data, weights, &isect->data ); - if( isect->data == NULL ) { - if( ! needed ) { - isect->data = data[0]; - } else if( ! tess->fatalError ) { - /* The only way fatal error is when two edges are found to intersect, - * but the user has not provided the callback necessary to handle - * generated intersection points. - */ - CALL_ERROR_OR_ERROR_DATA( GLU_TESS_NEED_COMBINE_CALLBACK ); - tess->fatalError = TRUE; - } - } -} - -static void SpliceMergeVertices( GLUtesselator *tess, GLUhalfEdge *e1, - GLUhalfEdge *e2 ) -/* - * Two vertices with idential coordinates are combined into one. - * e1->Org is kept, while e2->Org is discarded. - */ -{ - void *data[4] = { NULL, NULL, NULL, NULL }; - GLfloat weights[4] = { 0.5, 0.5, 0.0, 0.0 }; - - data[0] = e1->Org->data; - data[1] = e2->Org->data; - CallCombine( tess, e1->Org, data, weights, FALSE ); - if ( !__gl_meshSplice( e1, e2 ) ) longjmp(tess->env,1); -} - -static void VertexWeights( GLUvertex *isect, GLUvertex *org, GLUvertex *dst, - GLfloat *weights ) -/* - * Find some weights which describe how the intersection vertex is - * a linear combination of "org" and "dest". Each of the two edges - * which generated "isect" is allocated 50% of the weight; each edge - * splits the weight between its org and dst according to the - * relative distance to "isect". - */ -{ - GLdouble t1 = VertL1dist( org, isect ); - GLdouble t2 = VertL1dist( dst, isect ); - - weights[0] = 0.5 * t2 / (t1 + t2); - weights[1] = 0.5 * t1 / (t1 + t2); - isect->coords[0] += weights[0]*org->coords[0] + weights[1]*dst->coords[0]; - isect->coords[1] += weights[0]*org->coords[1] + weights[1]*dst->coords[1]; - isect->coords[2] += weights[0]*org->coords[2] + weights[1]*dst->coords[2]; -} - - -static void GetIntersectData( GLUtesselator *tess, GLUvertex *isect, - GLUvertex *orgUp, GLUvertex *dstUp, - GLUvertex *orgLo, GLUvertex *dstLo ) -/* - * We've computed a new intersection point, now we need a "data" pointer - * from the user so that we can refer to this new vertex in the - * rendering callbacks. - */ -{ - void *data[4]; - GLfloat weights[4]; - - data[0] = orgUp->data; - data[1] = dstUp->data; - data[2] = orgLo->data; - data[3] = dstLo->data; - - isect->coords[0] = isect->coords[1] = isect->coords[2] = 0; - VertexWeights( isect, orgUp, dstUp, &weights[0] ); - VertexWeights( isect, orgLo, dstLo, &weights[2] ); - - CallCombine( tess, isect, data, weights, TRUE ); -} - -static int CheckForRightSplice( GLUtesselator *tess, ActiveRegion *regUp ) -/* - * Check the upper and lower edge of "regUp", to make sure that the - * eUp->Org is above eLo, or eLo->Org is below eUp (depending on which - * origin is leftmost). - * - * The main purpose is to splice right-going edges with the same - * dest vertex and nearly identical slopes (ie. we can't distinguish - * the slopes numerically). However the splicing can also help us - * to recover from numerical errors. For example, suppose at one - * point we checked eUp and eLo, and decided that eUp->Org is barely - * above eLo. Then later, we split eLo into two edges (eg. from - * a splice operation like this one). This can change the result of - * our test so that now eUp->Org is incident to eLo, or barely below it. - * We must correct this condition to maintain the dictionary invariants. - * - * One possibility is to check these edges for intersection again - * (ie. CheckForIntersect). This is what we do if possible. However - * CheckForIntersect requires that tess->event lies between eUp and eLo, - * so that it has something to fall back on when the intersection - * calculation gives us an unusable answer. So, for those cases where - * we can't check for intersection, this routine fixes the problem - * by just splicing the offending vertex into the other edge. - * This is a guaranteed solution, no matter how degenerate things get. - * Basically this is a combinatorial solution to a numerical problem. - */ -{ - ActiveRegion *regLo = RegionBelow(regUp); - GLUhalfEdge *eUp = regUp->eUp; - GLUhalfEdge *eLo = regLo->eUp; - - if( VertLeq( eUp->Org, eLo->Org )) { - if( EdgeSign( eLo->Dst, eUp->Org, eLo->Org ) > 0 ) return FALSE; - - /* eUp->Org appears to be below eLo */ - if( ! VertEq( eUp->Org, eLo->Org )) { - /* Splice eUp->Org into eLo */ - if ( __gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1); - if ( !__gl_meshSplice( eUp, eLo->Oprev ) ) longjmp(tess->env,1); - regUp->dirty = regLo->dirty = TRUE; - - } else if( eUp->Org != eLo->Org ) { - /* merge the two vertices, discarding eUp->Org */ - pqDelete( tess->pq, eUp->Org->pqHandle ); /* __gl_pqSortDelete */ - SpliceMergeVertices( tess, eLo->Oprev, eUp ); - } - } else { - if( EdgeSign( eUp->Dst, eLo->Org, eUp->Org ) < 0 ) return FALSE; - - /* eLo->Org appears to be above eUp, so splice eLo->Org into eUp */ - RegionAbove(regUp)->dirty = regUp->dirty = TRUE; - if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1); - if ( !__gl_meshSplice( eLo->Oprev, eUp ) ) longjmp(tess->env,1); - } - return TRUE; -} - -static int CheckForLeftSplice( GLUtesselator *tess, ActiveRegion *regUp ) -/* - * Check the upper and lower edge of "regUp", to make sure that the - * eUp->Dst is above eLo, or eLo->Dst is below eUp (depending on which - * destination is rightmost). - * - * Theoretically, this should always be true. However, splitting an edge - * into two pieces can change the results of previous tests. For example, - * suppose at one point we checked eUp and eLo, and decided that eUp->Dst - * is barely above eLo. Then later, we split eLo into two edges (eg. from - * a splice operation like this one). This can change the result of - * the test so that now eUp->Dst is incident to eLo, or barely below it. - * We must correct this condition to maintain the dictionary invariants - * (otherwise new edges might get inserted in the wrong place in the - * dictionary, and bad stuff will happen). - * - * We fix the problem by just splicing the offending vertex into the - * other edge. - */ -{ - ActiveRegion *regLo = RegionBelow(regUp); - GLUhalfEdge *eUp = regUp->eUp; - GLUhalfEdge *eLo = regLo->eUp; - GLUhalfEdge *e; - - assert( ! VertEq( eUp->Dst, eLo->Dst )); - - if( VertLeq( eUp->Dst, eLo->Dst )) { - if( EdgeSign( eUp->Dst, eLo->Dst, eUp->Org ) < 0 ) return FALSE; - - /* eLo->Dst is above eUp, so splice eLo->Dst into eUp */ - RegionAbove(regUp)->dirty = regUp->dirty = TRUE; - e = __gl_meshSplitEdge( eUp ); - if (e == NULL) longjmp(tess->env,1); - if ( !__gl_meshSplice( eLo->Sym, e ) ) longjmp(tess->env,1); - e->Lface->inside = regUp->inside; - } else { - if( EdgeSign( eLo->Dst, eUp->Dst, eLo->Org ) > 0 ) return FALSE; - - /* eUp->Dst is below eLo, so splice eUp->Dst into eLo */ - regUp->dirty = regLo->dirty = TRUE; - e = __gl_meshSplitEdge( eLo ); - if (e == NULL) longjmp(tess->env,1); - if ( !__gl_meshSplice( eUp->Lnext, eLo->Sym ) ) longjmp(tess->env,1); - e->Rface->inside = regUp->inside; - } - return TRUE; -} - - -static int CheckForIntersect( GLUtesselator *tess, ActiveRegion *regUp ) -/* - * Check the upper and lower edges of the given region to see if - * they intersect. If so, create the intersection and add it - * to the data structures. - * - * Returns TRUE if adding the new intersection resulted in a recursive - * call to AddRightEdges(); in this case all "dirty" regions have been - * checked for intersections, and possibly regUp has been deleted. - */ -{ - ActiveRegion *regLo = RegionBelow(regUp); - GLUhalfEdge *eUp = regUp->eUp; - GLUhalfEdge *eLo = regLo->eUp; - GLUvertex *orgUp = eUp->Org; - GLUvertex *orgLo = eLo->Org; - GLUvertex *dstUp = eUp->Dst; - GLUvertex *dstLo = eLo->Dst; - GLdouble tMinUp, tMaxLo; - GLUvertex isect, *orgMin; - GLUhalfEdge *e; - - assert( ! VertEq( dstLo, dstUp )); - assert( EdgeSign( dstUp, tess->event, orgUp ) <= 0 ); - assert( EdgeSign( dstLo, tess->event, orgLo ) >= 0 ); - assert( orgUp != tess->event && orgLo != tess->event ); - assert( ! regUp->fixUpperEdge && ! regLo->fixUpperEdge ); - - if( orgUp == orgLo ) return FALSE; /* right endpoints are the same */ - - tMinUp = MIN( orgUp->t, dstUp->t ); - tMaxLo = MAX( orgLo->t, dstLo->t ); - if( tMinUp > tMaxLo ) return FALSE; /* t ranges do not overlap */ - - if( VertLeq( orgUp, orgLo )) { - if( EdgeSign( dstLo, orgUp, orgLo ) > 0 ) return FALSE; - } else { - if( EdgeSign( dstUp, orgLo, orgUp ) < 0 ) return FALSE; - } - - /* At this point the edges intersect, at least marginally */ - DebugEvent( tess ); - - __gl_edgeIntersect( dstUp, orgUp, dstLo, orgLo, &isect ); - /* The following properties are guaranteed: */ - assert( MIN( orgUp->t, dstUp->t ) <= isect.t ); - assert( isect.t <= MAX( orgLo->t, dstLo->t )); - assert( MIN( dstLo->s, dstUp->s ) <= isect.s ); - assert( isect.s <= MAX( orgLo->s, orgUp->s )); - - if( VertLeq( &isect, tess->event )) { - /* The intersection point lies slightly to the left of the sweep line, - * so move it until it''s slightly to the right of the sweep line. - * (If we had perfect numerical precision, this would never happen - * in the first place). The easiest and safest thing to do is - * replace the intersection by tess->event. - */ - isect.s = tess->event->s; - isect.t = tess->event->t; - } - /* Similarly, if the computed intersection lies to the right of the - * rightmost origin (which should rarely happen), it can cause - * unbelievable inefficiency on sufficiently degenerate inputs. - * (If you have the test program, try running test54.d with the - * "X zoom" option turned on). - */ - orgMin = VertLeq( orgUp, orgLo ) ? orgUp : orgLo; - if( VertLeq( orgMin, &isect )) { - isect.s = orgMin->s; - isect.t = orgMin->t; - } - - if( VertEq( &isect, orgUp ) || VertEq( &isect, orgLo )) { - /* Easy case -- intersection at one of the right endpoints */ - (void) CheckForRightSplice( tess, regUp ); - return FALSE; - } - - if( (! VertEq( dstUp, tess->event ) - && EdgeSign( dstUp, tess->event, &isect ) >= 0) - || (! VertEq( dstLo, tess->event ) - && EdgeSign( dstLo, tess->event, &isect ) <= 0 )) - { - /* Very unusual -- the new upper or lower edge would pass on the - * wrong side of the sweep event, or through it. This can happen - * due to very small numerical errors in the intersection calculation. - */ - if( dstLo == tess->event ) { - /* Splice dstLo into eUp, and process the new region(s) */ - if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1); - if ( !__gl_meshSplice( eLo->Sym, eUp ) ) longjmp(tess->env,1); - regUp = TopLeftRegion( regUp ); - if (regUp == NULL) longjmp(tess->env,1); - eUp = RegionBelow(regUp)->eUp; - FinishLeftRegions( tess, RegionBelow(regUp), regLo ); - AddRightEdges( tess, regUp, eUp->Oprev, eUp, eUp, TRUE ); - return TRUE; - } - if( dstUp == tess->event ) { - /* Splice dstUp into eLo, and process the new region(s) */ - if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1); - if ( !__gl_meshSplice( eUp->Lnext, eLo->Oprev ) ) longjmp(tess->env,1); - regLo = regUp; - regUp = TopRightRegion( regUp ); - e = RegionBelow(regUp)->eUp->Rprev; - regLo->eUp = eLo->Oprev; - eLo = FinishLeftRegions( tess, regLo, NULL ); - AddRightEdges( tess, regUp, eLo->Onext, eUp->Rprev, e, TRUE ); - return TRUE; - } - /* Special case: called from ConnectRightVertex. If either - * edge passes on the wrong side of tess->event, split it - * (and wait for ConnectRightVertex to splice it appropriately). - */ - if( EdgeSign( dstUp, tess->event, &isect ) >= 0 ) { - RegionAbove(regUp)->dirty = regUp->dirty = TRUE; - if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1); - eUp->Org->s = tess->event->s; - eUp->Org->t = tess->event->t; - } - if( EdgeSign( dstLo, tess->event, &isect ) <= 0 ) { - regUp->dirty = regLo->dirty = TRUE; - if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1); - eLo->Org->s = tess->event->s; - eLo->Org->t = tess->event->t; - } - /* leave the rest for ConnectRightVertex */ - return FALSE; - } - - /* General case -- split both edges, splice into new vertex. - * When we do the splice operation, the order of the arguments is - * arbitrary as far as correctness goes. However, when the operation - * creates a new face, the work done is proportional to the size of - * the new face. We expect the faces in the processed part of - * the mesh (ie. eUp->Lface) to be smaller than the faces in the - * unprocessed original contours (which will be eLo->Oprev->Lface). - */ - if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1); - if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1); - if ( !__gl_meshSplice( eLo->Oprev, eUp ) ) longjmp(tess->env,1); - eUp->Org->s = isect.s; - eUp->Org->t = isect.t; - eUp->Org->pqHandle = pqInsert( tess->pq, eUp->Org ); /* __gl_pqSortInsert */ - if (eUp->Org->pqHandle == LONG_MAX) { - pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */ - tess->pq = NULL; - longjmp(tess->env,1); - } - GetIntersectData( tess, eUp->Org, orgUp, dstUp, orgLo, dstLo ); - RegionAbove(regUp)->dirty = regUp->dirty = regLo->dirty = TRUE; - return FALSE; -} - -static void WalkDirtyRegions( GLUtesselator *tess, ActiveRegion *regUp ) -/* - * When the upper or lower edge of any region changes, the region is - * marked "dirty". This routine walks through all the dirty regions - * and makes sure that the dictionary invariants are satisfied - * (see the comments at the beginning of this file). Of course - * new dirty regions can be created as we make changes to restore - * the invariants. - */ -{ - ActiveRegion *regLo = RegionBelow(regUp); - GLUhalfEdge *eUp, *eLo; - - for( ;; ) { - /* Find the lowest dirty region (we walk from the bottom up). */ - while( regLo->dirty ) { - regUp = regLo; - regLo = RegionBelow(regLo); - } - if( ! regUp->dirty ) { - regLo = regUp; - regUp = RegionAbove( regUp ); - if( regUp == NULL || ! regUp->dirty ) { - /* We've walked all the dirty regions */ - return; - } - } - regUp->dirty = FALSE; - eUp = regUp->eUp; - eLo = regLo->eUp; - - if( eUp->Dst != eLo->Dst ) { - /* Check that the edge ordering is obeyed at the Dst vertices. */ - if( CheckForLeftSplice( tess, regUp )) { - - /* If the upper or lower edge was marked fixUpperEdge, then - * we no longer need it (since these edges are needed only for - * vertices which otherwise have no right-going edges). - */ - if( regLo->fixUpperEdge ) { - DeleteRegion( tess, regLo ); - if ( !__gl_meshDelete( eLo ) ) longjmp(tess->env,1); - regLo = RegionBelow( regUp ); - eLo = regLo->eUp; - } else if( regUp->fixUpperEdge ) { - DeleteRegion( tess, regUp ); - if ( !__gl_meshDelete( eUp ) ) longjmp(tess->env,1); - regUp = RegionAbove( regLo ); - eUp = regUp->eUp; - } - } - } - if( eUp->Org != eLo->Org ) { - if( eUp->Dst != eLo->Dst - && ! regUp->fixUpperEdge && ! regLo->fixUpperEdge - && (eUp->Dst == tess->event || eLo->Dst == tess->event) ) - { - /* When all else fails in CheckForIntersect(), it uses tess->event - * as the intersection location. To make this possible, it requires - * that tess->event lie between the upper and lower edges, and also - * that neither of these is marked fixUpperEdge (since in the worst - * case it might splice one of these edges into tess->event, and - * violate the invariant that fixable edges are the only right-going - * edge from their associated vertex). - */ - if( CheckForIntersect( tess, regUp )) { - /* WalkDirtyRegions() was called recursively; we're done */ - return; - } - } else { - /* Even though we can't use CheckForIntersect(), the Org vertices - * may violate the dictionary edge ordering. Check and correct this. - */ - (void) CheckForRightSplice( tess, regUp ); - } - } - if( eUp->Org == eLo->Org && eUp->Dst == eLo->Dst ) { - /* A degenerate loop consisting of only two edges -- delete it. */ - AddWinding( eLo, eUp ); - DeleteRegion( tess, regUp ); - if ( !__gl_meshDelete( eUp ) ) longjmp(tess->env,1); - regUp = RegionAbove( regLo ); - } - } -} - - -static void ConnectRightVertex( GLUtesselator *tess, ActiveRegion *regUp, - GLUhalfEdge *eBottomLeft ) -/* - * Purpose: connect a "right" vertex vEvent (one where all edges go left) - * to the unprocessed portion of the mesh. Since there are no right-going - * edges, two regions (one above vEvent and one below) are being merged - * into one. "regUp" is the upper of these two regions. - * - * There are two reasons for doing this (adding a right-going edge): - * - if the two regions being merged are "inside", we must add an edge - * to keep them separated (the combined region would not be monotone). - * - in any case, we must leave some record of vEvent in the dictionary, - * so that we can merge vEvent with features that we have not seen yet. - * For example, maybe there is a vertical edge which passes just to - * the right of vEvent; we would like to splice vEvent into this edge. - * - * However, we don't want to connect vEvent to just any vertex. We don''t - * want the new edge to cross any other edges; otherwise we will create - * intersection vertices even when the input data had no self-intersections. - * (This is a bad thing; if the user's input data has no intersections, - * we don't want to generate any false intersections ourselves.) - * - * Our eventual goal is to connect vEvent to the leftmost unprocessed - * vertex of the combined region (the union of regUp and regLo). - * But because of unseen vertices with all right-going edges, and also - * new vertices which may be created by edge intersections, we don''t - * know where that leftmost unprocessed vertex is. In the meantime, we - * connect vEvent to the closest vertex of either chain, and mark the region - * as "fixUpperEdge". This flag says to delete and reconnect this edge - * to the next processed vertex on the boundary of the combined region. - * Quite possibly the vertex we connected to will turn out to be the - * closest one, in which case we won''t need to make any changes. - */ -{ - GLUhalfEdge *eNew; - GLUhalfEdge *eTopLeft = eBottomLeft->Onext; - ActiveRegion *regLo = RegionBelow(regUp); - GLUhalfEdge *eUp = regUp->eUp; - GLUhalfEdge *eLo = regLo->eUp; - int degenerate = FALSE; - - if( eUp->Dst != eLo->Dst ) { - (void) CheckForIntersect( tess, regUp ); - } - - /* Possible new degeneracies: upper or lower edge of regUp may pass - * through vEvent, or may coincide with new intersection vertex - */ - if( VertEq( eUp->Org, tess->event )) { - if ( !__gl_meshSplice( eTopLeft->Oprev, eUp ) ) longjmp(tess->env,1); - regUp = TopLeftRegion( regUp ); - if (regUp == NULL) longjmp(tess->env,1); - eTopLeft = RegionBelow( regUp )->eUp; - FinishLeftRegions( tess, RegionBelow(regUp), regLo ); - degenerate = TRUE; - } - if( VertEq( eLo->Org, tess->event )) { - if ( !__gl_meshSplice( eBottomLeft, eLo->Oprev ) ) longjmp(tess->env,1); - eBottomLeft = FinishLeftRegions( tess, regLo, NULL ); - degenerate = TRUE; - } - if( degenerate ) { - AddRightEdges( tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE ); - return; - } - - /* Non-degenerate situation -- need to add a temporary, fixable edge. - * Connect to the closer of eLo->Org, eUp->Org. - */ - if( VertLeq( eLo->Org, eUp->Org )) { - eNew = eLo->Oprev; - } else { - eNew = eUp; - } - eNew = __gl_meshConnect( eBottomLeft->Lprev, eNew ); - if (eNew == NULL) longjmp(tess->env,1); - - /* Prevent cleanup, otherwise eNew might disappear before we've even - * had a chance to mark it as a temporary edge. - */ - AddRightEdges( tess, regUp, eNew, eNew->Onext, eNew->Onext, FALSE ); - eNew->Sym->activeRegion->fixUpperEdge = TRUE; - WalkDirtyRegions( tess, regUp ); -} - -/* Because vertices at exactly the same location are merged together - * before we process the sweep event, some degenerate cases can't occur. - * However if someone eventually makes the modifications required to - * merge features which are close together, the cases below marked - * TOLERANCE_NONZERO will be useful. They were debugged before the - * code to merge identical vertices in the main loop was added. - */ -#define TOLERANCE_NONZERO FALSE - -static void ConnectLeftDegenerate( GLUtesselator *tess, - ActiveRegion *regUp, GLUvertex *vEvent ) -/* - * The event vertex lies exacty on an already-processed edge or vertex. - * Adding the new vertex involves splicing it into the already-processed - * part of the mesh. - */ -{ - GLUhalfEdge *e, *eTopLeft, *eTopRight, *eLast; - ActiveRegion *reg; - - e = regUp->eUp; - if( VertEq( e->Org, vEvent )) { - /* e->Org is an unprocessed vertex - just combine them, and wait - * for e->Org to be pulled from the queue - */ - assert( TOLERANCE_NONZERO ); - SpliceMergeVertices( tess, e, vEvent->anEdge ); - return; - } - - if( ! VertEq( e->Dst, vEvent )) { - /* General case -- splice vEvent into edge e which passes through it */ - if (__gl_meshSplitEdge( e->Sym ) == NULL) longjmp(tess->env,1); - if( regUp->fixUpperEdge ) { - /* This edge was fixable -- delete unused portion of original edge */ - if ( !__gl_meshDelete( e->Onext ) ) longjmp(tess->env,1); - regUp->fixUpperEdge = FALSE; - } - if ( !__gl_meshSplice( vEvent->anEdge, e ) ) longjmp(tess->env,1); - SweepEvent( tess, vEvent ); /* recurse */ - return; - } - - /* vEvent coincides with e->Dst, which has already been processed. - * Splice in the additional right-going edges. - */ - assert( TOLERANCE_NONZERO ); - regUp = TopRightRegion( regUp ); - reg = RegionBelow( regUp ); - eTopRight = reg->eUp->Sym; - eTopLeft = eLast = eTopRight->Onext; - if( reg->fixUpperEdge ) { - /* Here e->Dst has only a single fixable edge going right. - * We can delete it since now we have some real right-going edges. - */ - assert( eTopLeft != eTopRight ); /* there are some left edges too */ - DeleteRegion( tess, reg ); - if ( !__gl_meshDelete( eTopRight ) ) longjmp(tess->env,1); - eTopRight = eTopLeft->Oprev; - } - if ( !__gl_meshSplice( vEvent->anEdge, eTopRight ) ) longjmp(tess->env,1); - if( ! EdgeGoesLeft( eTopLeft )) { - /* e->Dst had no left-going edges -- indicate this to AddRightEdges() */ - eTopLeft = NULL; - } - AddRightEdges( tess, regUp, eTopRight->Onext, eLast, eTopLeft, TRUE ); -} - - -static void ConnectLeftVertex( GLUtesselator *tess, GLUvertex *vEvent ) -/* - * Purpose: connect a "left" vertex (one where both edges go right) - * to the processed portion of the mesh. Let R be the active region - * containing vEvent, and let U and L be the upper and lower edge - * chains of R. There are two possibilities: - * - * - the normal case: split R into two regions, by connecting vEvent to - * the rightmost vertex of U or L lying to the left of the sweep line - * - * - the degenerate case: if vEvent is close enough to U or L, we - * merge vEvent into that edge chain. The subcases are: - * - merging with the rightmost vertex of U or L - * - merging with the active edge of U or L - * - merging with an already-processed portion of U or L - */ -{ - ActiveRegion *regUp, *regLo, *reg; - GLUhalfEdge *eUp, *eLo, *eNew; - ActiveRegion tmp; - - /* assert( vEvent->anEdge->Onext->Onext == vEvent->anEdge ); */ - - /* Get a pointer to the active region containing vEvent */ - tmp.eUp = vEvent->anEdge->Sym; - /* __GL_DICTLISTKEY */ /* __gl_dictListSearch */ - regUp = (ActiveRegion *)dictKey( dictSearch( tess->dict, &tmp )); - regLo = RegionBelow( regUp ); - eUp = regUp->eUp; - eLo = regLo->eUp; - - /* Try merging with U or L first */ - if( EdgeSign( eUp->Dst, vEvent, eUp->Org ) == 0 ) { - ConnectLeftDegenerate( tess, regUp, vEvent ); - return; - } - - /* Connect vEvent to rightmost processed vertex of either chain. - * e->Dst is the vertex that we will connect to vEvent. - */ - reg = VertLeq( eLo->Dst, eUp->Dst ) ? regUp : regLo; - - if( regUp->inside || reg->fixUpperEdge) { - if( reg == regUp ) { - eNew = __gl_meshConnect( vEvent->anEdge->Sym, eUp->Lnext ); - if (eNew == NULL) longjmp(tess->env,1); - } else { - GLUhalfEdge *tempHalfEdge= __gl_meshConnect( eLo->Dnext, vEvent->anEdge); - if (tempHalfEdge == NULL) longjmp(tess->env,1); - - eNew = tempHalfEdge->Sym; - } - if( reg->fixUpperEdge ) { - if ( !FixUpperEdge( reg, eNew ) ) longjmp(tess->env,1); - } else { - ComputeWinding( tess, AddRegionBelow( tess, regUp, eNew )); - } - SweepEvent( tess, vEvent ); - } else { - /* The new vertex is in a region which does not belong to the polygon. - * We don''t need to connect this vertex to the rest of the mesh. - */ - AddRightEdges( tess, regUp, vEvent->anEdge, vEvent->anEdge, NULL, TRUE ); - } -} - - -static void SweepEvent( GLUtesselator *tess, GLUvertex *vEvent ) -/* - * Does everything necessary when the sweep line crosses a vertex. - * Updates the mesh and the edge dictionary. - */ -{ - ActiveRegion *regUp, *reg; - GLUhalfEdge *e, *eTopLeft, *eBottomLeft; - - tess->event = vEvent; /* for access in EdgeLeq() */ - DebugEvent( tess ); - - /* Check if this vertex is the right endpoint of an edge that is - * already in the dictionary. In this case we don't need to waste - * time searching for the location to insert new edges. - */ - e = vEvent->anEdge; - while( e->activeRegion == NULL ) { - e = e->Onext; - if( e == vEvent->anEdge ) { - /* All edges go right -- not incident to any processed edges */ - ConnectLeftVertex( tess, vEvent ); - return; - } - } - - /* Processing consists of two phases: first we "finish" all the - * active regions where both the upper and lower edges terminate - * at vEvent (ie. vEvent is closing off these regions). - * We mark these faces "inside" or "outside" the polygon according - * to their winding number, and delete the edges from the dictionary. - * This takes care of all the left-going edges from vEvent. - */ - regUp = TopLeftRegion( e->activeRegion ); - if (regUp == NULL) longjmp(tess->env,1); - reg = RegionBelow( regUp ); - eTopLeft = reg->eUp; - eBottomLeft = FinishLeftRegions( tess, reg, NULL ); - - /* Next we process all the right-going edges from vEvent. This - * involves adding the edges to the dictionary, and creating the - * associated "active regions" which record information about the - * regions between adjacent dictionary edges. - */ - if( eBottomLeft->Onext == eTopLeft ) { - /* No right-going edges -- add a temporary "fixable" edge */ - ConnectRightVertex( tess, regUp, eBottomLeft ); - } else { - AddRightEdges( tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE ); - } -} - - -/* Make the sentinel coordinates big enough that they will never be - * merged with real input features. (Even with the largest possible - * input contour and the maximum tolerance of 1.0, no merging will be - * done with coordinates larger than 3 * GLU_TESS_MAX_COORD). - */ -#define SENTINEL_COORD (4 * GLU_TESS_MAX_COORD) - -static void AddSentinel( GLUtesselator *tess, GLdouble t ) -/* - * We add two sentinel edges above and below all other edges, - * to avoid special cases at the top and bottom. - */ -{ - GLUhalfEdge *e; - ActiveRegion *reg = (ActiveRegion *)memAlloc( sizeof( ActiveRegion )); - if (reg == NULL) longjmp(tess->env,1); - - e = __gl_meshMakeEdge( tess->mesh ); - if (e == NULL) longjmp(tess->env,1); - - e->Org->s = SENTINEL_COORD; - e->Org->t = t; - e->Dst->s = -SENTINEL_COORD; - e->Dst->t = t; - tess->event = e->Dst; /* initialize it */ - - reg->eUp = e; - reg->windingNumber = 0; - reg->inside = FALSE; - reg->fixUpperEdge = FALSE; - reg->sentinel = TRUE; - reg->dirty = FALSE; - reg->nodeUp = dictInsert( tess->dict, reg ); /* __gl_dictListInsertBefore */ - if (reg->nodeUp == NULL) longjmp(tess->env,1); -} - - -static void InitEdgeDict( GLUtesselator *tess ) -/* - * We maintain an ordering of edge intersections with the sweep line. - * This order is maintained in a dynamic dictionary. - */ -{ - /* __gl_dictListNewDict */ - tess->dict = dictNewDict( tess, (int (*)(void *, DictKey, DictKey)) EdgeLeq ); - if (tess->dict == NULL) longjmp(tess->env,1); - - AddSentinel( tess, -SENTINEL_COORD ); - AddSentinel( tess, SENTINEL_COORD ); -} - - -static void DoneEdgeDict( GLUtesselator *tess ) -{ - ActiveRegion *reg; -#ifndef NDEBUG - int fixedEdges = 0; -#endif - - /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */ - while( (reg = (ActiveRegion *)dictKey( dictMin( tess->dict ))) != NULL ) { - /* - * At the end of all processing, the dictionary should contain - * only the two sentinel edges, plus at most one "fixable" edge - * created by ConnectRightVertex(). - */ - if( ! reg->sentinel ) { - assert( reg->fixUpperEdge ); - assert( ++fixedEdges == 1 ); - } - assert( reg->windingNumber == 0 ); - DeleteRegion( tess, reg ); -/* __gl_meshDelete( reg->eUp );*/ - } - dictDeleteDict( tess->dict ); /* __gl_dictListDeleteDict */ -} - - -static void RemoveDegenerateEdges( GLUtesselator *tess ) -/* - * Remove zero-length edges, and contours with fewer than 3 vertices. - */ -{ - GLUhalfEdge *e, *eNext, *eLnext; - GLUhalfEdge *eHead = &tess->mesh->eHead; - - /*LINTED*/ - for( e = eHead->next; e != eHead; e = eNext ) { - eNext = e->next; - eLnext = e->Lnext; - - if( VertEq( e->Org, e->Dst ) && e->Lnext->Lnext != e ) { - /* Zero-length edge, contour has at least 3 edges */ - - SpliceMergeVertices( tess, eLnext, e ); /* deletes e->Org */ - if ( !__gl_meshDelete( e ) ) longjmp(tess->env,1); /* e is a self-loop */ - e = eLnext; - eLnext = e->Lnext; - } - if( eLnext->Lnext == e ) { - /* Degenerate contour (one or two edges) */ - - if( eLnext != e ) { - if( eLnext == eNext || eLnext == eNext->Sym ) { eNext = eNext->next; } - if ( !__gl_meshDelete( eLnext ) ) longjmp(tess->env,1); - } - if( e == eNext || e == eNext->Sym ) { eNext = eNext->next; } - if ( !__gl_meshDelete( e ) ) longjmp(tess->env,1); - } - } -} - -static int InitPriorityQ( GLUtesselator *tess ) -/* - * Insert all vertices into the priority queue which determines the - * order in which vertices cross the sweep line. - */ -{ - PriorityQ *pq; - GLUvertex *v, *vHead; - - /* __gl_pqSortNewPriorityQ */ - pq = tess->pq = pqNewPriorityQ( (int (*)(PQkey, PQkey)) __gl_vertLeq ); - if (pq == NULL) return 0; - - vHead = &tess->mesh->vHead; - for( v = vHead->next; v != vHead; v = v->next ) { - v->pqHandle = pqInsert( pq, v ); /* __gl_pqSortInsert */ - if (v->pqHandle == LONG_MAX) break; - } - if (v != vHead || !pqInit( pq ) ) { /* __gl_pqSortInit */ - pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */ - tess->pq = NULL; - return 0; - } - - return 1; -} - - -static void DonePriorityQ( GLUtesselator *tess ) -{ - pqDeletePriorityQ( tess->pq ); /* __gl_pqSortDeletePriorityQ */ -} - - -static int RemoveDegenerateFaces( GLUmesh *mesh ) -/* - * Delete any degenerate faces with only two edges. WalkDirtyRegions() - * will catch almost all of these, but it won't catch degenerate faces - * produced by splice operations on already-processed edges. - * The two places this can happen are in FinishLeftRegions(), when - * we splice in a "temporary" edge produced by ConnectRightVertex(), - * and in CheckForLeftSplice(), where we splice already-processed - * edges to ensure that our dictionary invariants are not violated - * by numerical errors. - * - * In both these cases it is *very* dangerous to delete the offending - * edge at the time, since one of the routines further up the stack - * will sometimes be keeping a pointer to that edge. - */ -{ - GLUface *f, *fNext; - GLUhalfEdge *e; - - /*LINTED*/ - for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) { - fNext = f->next; - e = f->anEdge; - assert( e->Lnext != e ); - - if( e->Lnext->Lnext == e ) { - /* A face with only two edges */ - AddWinding( e->Onext, e ); - if ( !__gl_meshDelete( e ) ) return 0; - } - } - return 1; -} - -int __gl_computeInterior( GLUtesselator *tess ) -/* - * __gl_computeInterior( tess ) computes the planar arrangement specified - * by the given contours, and further subdivides this arrangement - * into regions. Each region is marked "inside" if it belongs - * to the polygon, according to the rule given by tess->windingRule. - * Each interior region is guaranteed be monotone. - */ -{ - GLUvertex *v, *vNext; - - tess->fatalError = FALSE; - - /* Each vertex defines an event for our sweep line. Start by inserting - * all the vertices in a priority queue. Events are processed in - * lexicographic order, ie. - * - * e1 < e2 iff e1.x < e2.x || (e1.x == e2.x && e1.y < e2.y) - */ - RemoveDegenerateEdges( tess ); - if ( !InitPriorityQ( tess ) ) return 0; /* if error */ - InitEdgeDict( tess ); - - /* __gl_pqSortExtractMin */ - while( (v = (GLUvertex *)pqExtractMin( tess->pq )) != NULL ) { - for( ;; ) { - vNext = (GLUvertex *)pqMinimum( tess->pq ); /* __gl_pqSortMinimum */ - if( vNext == NULL || ! VertEq( vNext, v )) break; - - /* Merge together all vertices at exactly the same location. - * This is more efficient than processing them one at a time, - * simplifies the code (see ConnectLeftDegenerate), and is also - * important for correct handling of certain degenerate cases. - * For example, suppose there are two identical edges A and B - * that belong to different contours (so without this code they would - * be processed by separate sweep events). Suppose another edge C - * crosses A and B from above. When A is processed, we split it - * at its intersection point with C. However this also splits C, - * so when we insert B we may compute a slightly different - * intersection point. This might leave two edges with a small - * gap between them. This kind of error is especially obvious - * when using boundary extraction (GLU_TESS_BOUNDARY_ONLY). - */ - vNext = (GLUvertex *)pqExtractMin( tess->pq ); /* __gl_pqSortExtractMin*/ - SpliceMergeVertices( tess, v->anEdge, vNext->anEdge ); - } - SweepEvent( tess, v ); - } - - /* Set tess->event for debugging purposes */ - /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */ - tess->event = ((ActiveRegion *) dictKey( dictMin( tess->dict )))->eUp->Org; - DebugEvent( tess ); - DoneEdgeDict( tess ); - DonePriorityQ( tess ); - - if ( !RemoveDegenerateFaces( tess->mesh ) ) return 0; - __gl_meshCheckMesh( tess->mesh ); - - return 1; -} diff --git a/clutter/cogl/cogl/tesselator/sweep.h b/clutter/cogl/cogl/tesselator/sweep.h deleted file mode 100644 index feb68b0..0000000 --- a/clutter/cogl/cogl/tesselator/sweep.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __sweep_h_ -#define __sweep_h_ - -#include "mesh.h" - -/* __gl_computeInterior( tess ) computes the planar arrangement specified - * by the given contours, and further subdivides this arrangement - * into regions. Each region is marked "inside" if it belongs - * to the polygon, according to the rule given by tess->windingRule. - * Each interior region is guaranteed be monotone. - */ -int __gl_computeInterior( GLUtesselator *tess ); - - -/* The following is here *only* for access by debugging routines */ - -#include "dict.h" - -/* For each pair of adjacent edges crossing the sweep line, there is - * an ActiveRegion to represent the region between them. The active - * regions are kept in sorted order in a dynamic dictionary. As the - * sweep line crosses each vertex, we update the affected regions. - */ - -struct ActiveRegion { - GLUhalfEdge *eUp; /* upper edge, directed right to left */ - DictNode *nodeUp; /* dictionary node corresponding to eUp */ - int windingNumber; /* used to determine which regions are - * inside the polygon */ - GLboolean inside; /* is this region inside the polygon? */ - GLboolean sentinel; /* marks fake edges at t = +/-infinity */ - GLboolean dirty; /* marks regions where the upper or lower - * edge has changed, but we haven't checked - * whether they intersect yet */ - GLboolean fixUpperEdge; /* marks temporary edges introduced when - * we process a "right vertex" (one without - * any edges leaving to the right) */ -}; - -#define RegionBelow(r) ((ActiveRegion *) dictKey(dictPred((r)->nodeUp))) -#define RegionAbove(r) ((ActiveRegion *) dictKey(dictSucc((r)->nodeUp))) - -#endif diff --git a/clutter/cogl/cogl/tesselator/tess.c b/clutter/cogl/cogl/tesselator/tess.c deleted file mode 100644 index 4a0e8de..0000000 --- a/clutter/cogl/cogl/tesselator/tess.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include -#include -#include -#include "memalloc.h" -#include "tess.h" -#include "mesh.h" -#include "normal.h" -#include "sweep.h" -#include "tessmono.h" -#include "render.h" - -#define GLU_TESS_DEFAULT_TOLERANCE 0.0 -#define GLU_TESS_MESH 100112 /* void (*)(GLUmesh *mesh) */ - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/*ARGSUSED*/ static void GLAPIENTRY noBegin( GLenum type ) {} -/*ARGSUSED*/ static void GLAPIENTRY noEdgeFlag( GLboolean boundaryEdge ) {} -/*ARGSUSED*/ static void GLAPIENTRY noVertex( void *data ) {} -/*ARGSUSED*/ static void GLAPIENTRY noEnd( void ) {} -/*ARGSUSED*/ static void GLAPIENTRY noError( GLenum errnum ) {} -/*ARGSUSED*/ static void GLAPIENTRY noCombine( GLdouble coords[3], void *data[4], - GLfloat weight[4], void **dataOut ) {} -/*ARGSUSED*/ static void GLAPIENTRY noMesh( GLUmesh *mesh ) {} - - -/*ARGSUSED*/ void GLAPIENTRY __gl_noBeginData( GLenum type, - void *polygonData ) {} -/*ARGSUSED*/ void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, - void *polygonData ) {} -/*ARGSUSED*/ void GLAPIENTRY __gl_noVertexData( void *data, - void *polygonData ) {} -/*ARGSUSED*/ void GLAPIENTRY __gl_noEndData( void *polygonData ) {} -/*ARGSUSED*/ void GLAPIENTRY __gl_noErrorData( GLenum errnum, - void *polygonData ) {} -/*ARGSUSED*/ void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], - void *data[4], - GLfloat weight[4], - void **outData, - void *polygonData ) {} - -/* Half-edges are allocated in pairs (see mesh.c) */ -typedef struct { GLUhalfEdge e, eSym; } EdgePair; - -#undef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MAX_FAST_ALLOC (MAX(sizeof(EdgePair), \ - MAX(sizeof(GLUvertex),sizeof(GLUface)))) - - -GLUtesselator * GLAPIENTRY -gluNewTess( void ) -{ - GLUtesselator *tess; - - /* Only initialize fields which can be changed by the api. Other fields - * are initialized where they are used. - */ - - if (memInit( MAX_FAST_ALLOC ) == 0) { - return 0; /* out of memory */ - } - tess = (GLUtesselator *)memAlloc( sizeof( GLUtesselator )); - if (tess == NULL) { - return 0; /* out of memory */ - } - - tess->state = T_DORMANT; - - tess->normal[0] = 0; - tess->normal[1] = 0; - tess->normal[2] = 0; - - tess->relTolerance = GLU_TESS_DEFAULT_TOLERANCE; - tess->windingRule = GLU_TESS_WINDING_ODD; - tess->flagBoundary = FALSE; - tess->boundaryOnly = FALSE; - - tess->callBegin = &noBegin; - tess->callEdgeFlag = &noEdgeFlag; - tess->callVertex = &noVertex; - tess->callEnd = &noEnd; - - tess->callError = &noError; - tess->callCombine = &noCombine; - tess->callMesh = &noMesh; - - tess->callBeginData= &__gl_noBeginData; - tess->callEdgeFlagData= &__gl_noEdgeFlagData; - tess->callVertexData= &__gl_noVertexData; - tess->callEndData= &__gl_noEndData; - tess->callErrorData= &__gl_noErrorData; - tess->callCombineData= &__gl_noCombineData; - - tess->polygonData= NULL; - - return tess; -} - -static void MakeDormant( GLUtesselator *tess ) -{ - /* Return the tessellator to its original dormant state. */ - - if( tess->mesh != NULL ) { - __gl_meshDeleteMesh( tess->mesh ); - } - tess->state = T_DORMANT; - tess->lastEdge = NULL; - tess->mesh = NULL; -} - -#define RequireState( tess, s ) if( tess->state != s ) GotoState(tess,s) - -static void GotoState( GLUtesselator *tess, enum TessState newState ) -{ - while( tess->state != newState ) { - /* We change the current state one level at a time, to get to - * the desired state. - */ - if( tess->state < newState ) { - switch( tess->state ) { - case T_DORMANT: - CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_POLYGON ); - gluTessBeginPolygon( tess, NULL ); - break; - case T_IN_POLYGON: - CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_CONTOUR ); - gluTessBeginContour( tess ); - break; - default: - ; - } - } else { - switch( tess->state ) { - case T_IN_CONTOUR: - CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR ); - gluTessEndContour( tess ); - break; - case T_IN_POLYGON: - CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_POLYGON ); - /* gluTessEndPolygon( tess ) is too much work! */ - MakeDormant( tess ); - break; - default: - ; - } - } - } -} - - -void GLAPIENTRY -gluDeleteTess( GLUtesselator *tess ) -{ - RequireState( tess, T_DORMANT ); - memFree( tess ); -} - - -void GLAPIENTRY -gluTessProperty( GLUtesselator *tess, GLenum which, GLdouble value ) -{ - GLenum windingRule; - - switch( which ) { - case GLU_TESS_TOLERANCE: - if( value < 0.0 || value > 1.0 ) break; - tess->relTolerance = value; - return; - - case GLU_TESS_WINDING_RULE: - windingRule = (GLenum) value; - if( windingRule != value ) break; /* not an integer */ - - switch( windingRule ) { - case GLU_TESS_WINDING_ODD: - case GLU_TESS_WINDING_NONZERO: - case GLU_TESS_WINDING_POSITIVE: - case GLU_TESS_WINDING_NEGATIVE: - case GLU_TESS_WINDING_ABS_GEQ_TWO: - tess->windingRule = windingRule; - return; - default: - break; - } - - case GLU_TESS_BOUNDARY_ONLY: - tess->boundaryOnly = (value != 0); - return; - - default: - CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM ); - return; - } - CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_VALUE ); -} - -/* Returns tessellator property */ -void GLAPIENTRY -gluGetTessProperty( GLUtesselator *tess, GLenum which, GLdouble *value ) -{ - switch (which) { - case GLU_TESS_TOLERANCE: - /* tolerance should be in range [0..1] */ - assert(0.0 <= tess->relTolerance && tess->relTolerance <= 1.0); - *value= tess->relTolerance; - break; - case GLU_TESS_WINDING_RULE: - assert(tess->windingRule == GLU_TESS_WINDING_ODD || - tess->windingRule == GLU_TESS_WINDING_NONZERO || - tess->windingRule == GLU_TESS_WINDING_POSITIVE || - tess->windingRule == GLU_TESS_WINDING_NEGATIVE || - tess->windingRule == GLU_TESS_WINDING_ABS_GEQ_TWO); - *value= tess->windingRule; - break; - case GLU_TESS_BOUNDARY_ONLY: - assert(tess->boundaryOnly == TRUE || tess->boundaryOnly == FALSE); - *value= tess->boundaryOnly; - break; - default: - *value= 0.0; - CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM ); - break; - } -} /* gluGetTessProperty() */ - -void GLAPIENTRY -gluTessNormal( GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z ) -{ - tess->normal[0] = x; - tess->normal[1] = y; - tess->normal[2] = z; -} - -void GLAPIENTRY -gluTessCallback( GLUtesselator *tess, GLenum which, _GLUfuncptr fn) -{ - switch( which ) { - case GLU_TESS_BEGIN: - tess->callBegin = (fn == NULL) ? &noBegin : (void (GLAPIENTRY *)(GLenum)) fn; - return; - case GLU_TESS_BEGIN_DATA: - tess->callBeginData = (fn == NULL) ? - &__gl_noBeginData : (void (GLAPIENTRY *)(GLenum, void *)) fn; - return; - case GLU_TESS_EDGE_FLAG: - tess->callEdgeFlag = (fn == NULL) ? &noEdgeFlag : - (void (GLAPIENTRY *)(GLboolean)) fn; - /* If the client wants boundary edges to be flagged, - * we render everything as separate triangles (no strips or fans). - */ - tess->flagBoundary = (fn != NULL); - return; - case GLU_TESS_EDGE_FLAG_DATA: - tess->callEdgeFlagData= (fn == NULL) ? - &__gl_noEdgeFlagData : (void (GLAPIENTRY *)(GLboolean, void *)) fn; - /* If the client wants boundary edges to be flagged, - * we render everything as separate triangles (no strips or fans). - */ - tess->flagBoundary = (fn != NULL); - return; - case GLU_TESS_VERTEX: - tess->callVertex = (fn == NULL) ? &noVertex : - (void (GLAPIENTRY *)(void *)) fn; - return; - case GLU_TESS_VERTEX_DATA: - tess->callVertexData = (fn == NULL) ? - &__gl_noVertexData : (void (GLAPIENTRY *)(void *, void *)) fn; - return; - case GLU_TESS_END: - tess->callEnd = (fn == NULL) ? &noEnd : (void (GLAPIENTRY *)(void)) fn; - return; - case GLU_TESS_END_DATA: - tess->callEndData = (fn == NULL) ? &__gl_noEndData : - (void (GLAPIENTRY *)(void *)) fn; - return; - case GLU_TESS_ERROR: - tess->callError = (fn == NULL) ? &noError : (void (GLAPIENTRY *)(GLenum)) fn; - return; - case GLU_TESS_ERROR_DATA: - tess->callErrorData = (fn == NULL) ? - &__gl_noErrorData : (void (GLAPIENTRY *)(GLenum, void *)) fn; - return; - case GLU_TESS_COMBINE: - tess->callCombine = (fn == NULL) ? &noCombine : - (void (GLAPIENTRY *)(GLdouble [3],void *[4], GLfloat [4], void ** )) fn; - return; - case GLU_TESS_COMBINE_DATA: - tess->callCombineData = (fn == NULL) ? &__gl_noCombineData : - (void (GLAPIENTRY *)(GLdouble [3], - void *[4], - GLfloat [4], - void **, - void *)) fn; - return; - case GLU_TESS_MESH: - tess->callMesh = (fn == NULL) ? &noMesh : (void (GLAPIENTRY *)(GLUmesh *)) fn; - return; - default: - CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM ); - return; - } -} - -static int AddVertex( GLUtesselator *tess, GLdouble coords[3], void *data ) -{ - GLUhalfEdge *e; - - e = tess->lastEdge; - if( e == NULL ) { - /* Make a self-loop (one vertex, one edge). */ - - e = __gl_meshMakeEdge( tess->mesh ); - if (e == NULL) return 0; - if ( !__gl_meshSplice( e, e->Sym ) ) return 0; - } else { - /* Create a new vertex and edge which immediately follow e - * in the ordering around the left face. - */ - if (__gl_meshSplitEdge( e ) == NULL) return 0; - e = e->Lnext; - } - - /* The new vertex is now e->Org. */ - e->Org->data = data; - e->Org->coords[0] = coords[0]; - e->Org->coords[1] = coords[1]; - e->Org->coords[2] = coords[2]; - - /* The winding of an edge says how the winding number changes as we - * cross from the edge''s right face to its left face. We add the - * vertices in such an order that a CCW contour will add +1 to - * the winding number of the region inside the contour. - */ - e->winding = 1; - e->Sym->winding = -1; - - tess->lastEdge = e; - - return 1; -} - - -static void CacheVertex( GLUtesselator *tess, GLdouble coords[3], void *data ) -{ - CachedVertex *v = &tess->cache[tess->cacheCount]; - - v->data = data; - v->coords[0] = coords[0]; - v->coords[1] = coords[1]; - v->coords[2] = coords[2]; - ++tess->cacheCount; -} - - -static int EmptyCache( GLUtesselator *tess ) -{ - CachedVertex *v = tess->cache; - CachedVertex *vLast; - - tess->mesh = __gl_meshNewMesh(); - if (tess->mesh == NULL) return 0; - - for( vLast = v + tess->cacheCount; v < vLast; ++v ) { - if ( !AddVertex( tess, v->coords, v->data ) ) return 0; - } - tess->cacheCount = 0; - tess->emptyCache = FALSE; - - return 1; -} - - -void GLAPIENTRY -gluTessVertex( GLUtesselator *tess, GLdouble coords[3], void *data ) -{ - int i, tooLarge = FALSE; - GLdouble x, clamped[3]; - - RequireState( tess, T_IN_CONTOUR ); - - if( tess->emptyCache ) { - if ( !EmptyCache( tess ) ) { - CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); - return; - } - tess->lastEdge = NULL; - } - for( i = 0; i < 3; ++i ) { - x = coords[i]; - if( x < - GLU_TESS_MAX_COORD ) { - x = - GLU_TESS_MAX_COORD; - tooLarge = TRUE; - } - if( x > GLU_TESS_MAX_COORD ) { - x = GLU_TESS_MAX_COORD; - tooLarge = TRUE; - } - clamped[i] = x; - } - if( tooLarge ) { - CALL_ERROR_OR_ERROR_DATA( GLU_TESS_COORD_TOO_LARGE ); - } - - if( tess->mesh == NULL ) { - if( tess->cacheCount < TESS_MAX_CACHE ) { - CacheVertex( tess, clamped, data ); - return; - } - if ( !EmptyCache( tess ) ) { - CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); - return; - } - } - if ( !AddVertex( tess, clamped, data ) ) { - CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); - } -} - - -void GLAPIENTRY -gluTessBeginPolygon( GLUtesselator *tess, void *data ) -{ - RequireState( tess, T_DORMANT ); - - tess->state = T_IN_POLYGON; - tess->cacheCount = 0; - tess->emptyCache = FALSE; - tess->mesh = NULL; - - tess->polygonData= data; -} - - -void GLAPIENTRY -gluTessBeginContour( GLUtesselator *tess ) -{ - RequireState( tess, T_IN_POLYGON ); - - tess->state = T_IN_CONTOUR; - tess->lastEdge = NULL; - if( tess->cacheCount > 0 ) { - /* Just set a flag so we don't get confused by empty contours - * -- these can be generated accidentally with the obsolete - * NextContour() interface. - */ - tess->emptyCache = TRUE; - } -} - - -void GLAPIENTRY -gluTessEndContour( GLUtesselator *tess ) -{ - RequireState( tess, T_IN_CONTOUR ); - tess->state = T_IN_POLYGON; -} - -void GLAPIENTRY -gluTessEndPolygon( GLUtesselator *tess ) -{ - GLUmesh *mesh; - - if (setjmp(tess->env) != 0) { - /* come back here if out of memory */ - CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); - return; - } - - RequireState( tess, T_IN_POLYGON ); - tess->state = T_DORMANT; - - if( tess->mesh == NULL ) { - if( ! tess->flagBoundary && tess->callMesh == &noMesh ) { - - /* Try some special code to make the easy cases go quickly - * (eg. convex polygons). This code does NOT handle multiple contours, - * intersections, edge flags, and of course it does not generate - * an explicit mesh either. - */ - if( __gl_renderCache( tess )) { - tess->polygonData= NULL; - return; - } - } - if ( !EmptyCache( tess ) ) longjmp(tess->env,1); /* could've used a label*/ - } - - /* Determine the polygon normal and project vertices onto the plane - * of the polygon. - */ - __gl_projectPolygon( tess ); - - /* __gl_computeInterior( tess ) computes the planar arrangement specified - * by the given contours, and further subdivides this arrangement - * into regions. Each region is marked "inside" if it belongs - * to the polygon, according to the rule given by tess->windingRule. - * Each interior region is guaranteed be monotone. - */ - if ( !__gl_computeInterior( tess ) ) { - longjmp(tess->env,1); /* could've used a label */ - } - - mesh = tess->mesh; - if( ! tess->fatalError ) { - int rc = 1; - - /* If the user wants only the boundary contours, we throw away all edges - * except those which separate the interior from the exterior. - * Otherwise we tessellate all the regions marked "inside". - */ - if( tess->boundaryOnly ) { - rc = __gl_meshSetWindingNumber( mesh, 1, TRUE ); - } else { - rc = __gl_meshTessellateInterior( mesh ); - } - if (rc == 0) longjmp(tess->env,1); /* could've used a label */ - - __gl_meshCheckMesh( mesh ); - - if( tess->callBegin != &noBegin || tess->callEnd != &noEnd - || tess->callVertex != &noVertex || tess->callEdgeFlag != &noEdgeFlag - || tess->callBeginData != &__gl_noBeginData - || tess->callEndData != &__gl_noEndData - || tess->callVertexData != &__gl_noVertexData - || tess->callEdgeFlagData != &__gl_noEdgeFlagData ) - { - if( tess->boundaryOnly ) { - __gl_renderBoundary( tess, mesh ); /* output boundary contours */ - } else { - __gl_renderMesh( tess, mesh ); /* output strips and fans */ - } - } - if( tess->callMesh != &noMesh ) { - - /* Throw away the exterior faces, so that all faces are interior. - * This way the user doesn't have to check the "inside" flag, - * and we don't need to even reveal its existence. It also leaves - * the freedom for an implementation to not generate the exterior - * faces in the first place. - */ - __gl_meshDiscardExterior( mesh ); - (*tess->callMesh)( mesh ); /* user wants the mesh itself */ - tess->mesh = NULL; - tess->polygonData= NULL; - return; - } - } - __gl_meshDeleteMesh( mesh ); - tess->polygonData= NULL; - tess->mesh = NULL; -} - - -/*XXXblythe unused function*/ -#if 0 -void GLAPIENTRY -gluDeleteMesh( GLUmesh *mesh ) -{ - __gl_meshDeleteMesh( mesh ); -} -#endif - - - -/*******************************************************/ - -/* Obsolete calls -- for backward compatibility */ - -void GLAPIENTRY -gluBeginPolygon( GLUtesselator *tess ) -{ - gluTessBeginPolygon( tess, NULL ); - gluTessBeginContour( tess ); -} - - -/*ARGSUSED*/ -void GLAPIENTRY -gluNextContour( GLUtesselator *tess, GLenum type ) -{ - gluTessEndContour( tess ); - gluTessBeginContour( tess ); -} - - -void GLAPIENTRY -gluEndPolygon( GLUtesselator *tess ) -{ - gluTessEndContour( tess ); - gluTessEndPolygon( tess ); -} diff --git a/clutter/cogl/cogl/tesselator/tess.h b/clutter/cogl/cogl/tesselator/tess.h deleted file mode 100644 index 1624960..0000000 --- a/clutter/cogl/cogl/tesselator/tess.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __tess_h_ -#define __tess_h_ - -#include -#include -#include "mesh.h" -#include "dict.h" -#include "priorityq.h" - -/* The begin/end calls must be properly nested. We keep track of - * the current state to enforce the ordering. - */ -enum TessState { T_DORMANT, T_IN_POLYGON, T_IN_CONTOUR }; - -/* We cache vertex data for single-contour polygons so that we can - * try a quick-and-dirty decomposition first. - */ -#define TESS_MAX_CACHE 100 - -typedef struct CachedVertex { - GLdouble coords[3]; - void *data; -} CachedVertex; - -struct GLUtesselator { - - /*** state needed for collecting the input data ***/ - - enum TessState state; /* what begin/end calls have we seen? */ - - GLUhalfEdge *lastEdge; /* lastEdge->Org is the most recent vertex */ - GLUmesh *mesh; /* stores the input contours, and eventually - the tessellation itself */ - - void (GLAPIENTRY *callError)( GLenum errnum ); - - /*** state needed for projecting onto the sweep plane ***/ - - GLdouble normal[3]; /* user-specified normal (if provided) */ - GLdouble sUnit[3]; /* unit vector in s-direction (debugging) */ - GLdouble tUnit[3]; /* unit vector in t-direction (debugging) */ - - /*** state needed for the line sweep ***/ - - GLdouble relTolerance; /* tolerance for merging features */ - GLenum windingRule; /* rule for determining polygon interior */ - GLboolean fatalError; /* fatal error: needed combine callback */ - - Dict *dict; /* edge dictionary for sweep line */ - PriorityQ *pq; /* priority queue of vertex events */ - GLUvertex *event; /* current sweep event being processed */ - - void (GLAPIENTRY *callCombine)( GLdouble coords[3], void *data[4], - GLfloat weight[4], void **outData ); - - /*** state needed for rendering callbacks (see render.c) ***/ - - GLboolean flagBoundary; /* mark boundary edges (use EdgeFlag) */ - GLboolean boundaryOnly; /* Extract contours, not triangles */ - GLUface *lonelyTriList; - /* list of triangles which could not be rendered as strips or fans */ - - void (GLAPIENTRY *callBegin)( GLenum type ); - void (GLAPIENTRY *callEdgeFlag)( GLboolean boundaryEdge ); - void (GLAPIENTRY *callVertex)( void *data ); - void (GLAPIENTRY *callEnd)( void ); - void (GLAPIENTRY *callMesh)( GLUmesh *mesh ); - - - /*** state needed to cache single-contour polygons for renderCache() */ - - GLboolean emptyCache; /* empty cache on next vertex() call */ - int cacheCount; /* number of cached vertices */ - CachedVertex cache[TESS_MAX_CACHE]; /* the vertex data */ - - /*** rendering callbacks that also pass polygon data ***/ - void (GLAPIENTRY *callBeginData)( GLenum type, void *polygonData ); - void (GLAPIENTRY *callEdgeFlagData)( GLboolean boundaryEdge, - void *polygonData ); - void (GLAPIENTRY *callVertexData)( void *data, void *polygonData ); - void (GLAPIENTRY *callEndData)( void *polygonData ); - void (GLAPIENTRY *callErrorData)( GLenum errnum, void *polygonData ); - void (GLAPIENTRY *callCombineData)( GLdouble coords[3], void *data[4], - GLfloat weight[4], void **outData, - void *polygonData ); - - jmp_buf env; /* place to jump to when memAllocs fail */ - - void *polygonData; /* client data for current polygon */ -}; - -void GLAPIENTRY __gl_noBeginData( GLenum type, void *polygonData ); -void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, void *polygonData ); -void GLAPIENTRY __gl_noVertexData( void *data, void *polygonData ); -void GLAPIENTRY __gl_noEndData( void *polygonData ); -void GLAPIENTRY __gl_noErrorData( GLenum errnum, void *polygonData ); -void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], void *data[4], - GLfloat weight[4], void **outData, - void *polygonData ); - -#define CALL_BEGIN_OR_BEGIN_DATA(a) \ - if (tess->callBeginData != &__gl_noBeginData) \ - (*tess->callBeginData)((a),tess->polygonData); \ - else (*tess->callBegin)((a)); - -#define CALL_VERTEX_OR_VERTEX_DATA(a) \ - if (tess->callVertexData != &__gl_noVertexData) \ - (*tess->callVertexData)((a),tess->polygonData); \ - else (*tess->callVertex)((a)); - -#define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \ - if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \ - (*tess->callEdgeFlagData)((a),tess->polygonData); \ - else (*tess->callEdgeFlag)((a)); - -#define CALL_END_OR_END_DATA() \ - if (tess->callEndData != &__gl_noEndData) \ - (*tess->callEndData)(tess->polygonData); \ - else (*tess->callEnd)(); - -#define CALL_COMBINE_OR_COMBINE_DATA(a,b,c,d) \ - if (tess->callCombineData != &__gl_noCombineData) \ - (*tess->callCombineData)((a),(b),(c),(d),tess->polygonData); \ - else (*tess->callCombine)((a),(b),(c),(d)); - -#define CALL_ERROR_OR_ERROR_DATA(a) \ - if (tess->callErrorData != &__gl_noErrorData) \ - (*tess->callErrorData)((a),tess->polygonData); \ - else (*tess->callError)((a)); - -#endif diff --git a/clutter/cogl/cogl/tesselator/tesselator.h b/clutter/cogl/cogl/tesselator/tesselator.h deleted file mode 100644 index 69a6ece..0000000 --- a/clutter/cogl/cogl/tesselator/tesselator.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * Copyright (C) 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifndef __TESSELATOR_H__ -#define __TESSELATOR_H__ - -/* This just includes the defines needed by the tesselator code */ - -#include "cogl/cogl-defines.h" - -typedef struct GLUtesselator GLUtesselator; - -#define GLU_TESS_MAX_COORD 1.0e150 - -void gluBeginPolygon (GLUtesselator* tess); -void gluDeleteTess (GLUtesselator* tess); -void gluEndPolygon (GLUtesselator* tess); - -typedef void (_GLUfuncptr)(); - -void gluGetTessProperty (GLUtesselator* tess, GLenum which, double* data); - -GLUtesselator *gluNewTess (void); -void gluNextContour (GLUtesselator* tess, GLenum type); - -void gluTessBeginContour (GLUtesselator* tess); -void gluTessBeginPolygon (GLUtesselator* tess, GLvoid* data); -void gluTessCallback (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc); -void gluTessEndContour (GLUtesselator* tess); -void gluTessEndPolygon (GLUtesselator* tess); -void gluTessNormal (GLUtesselator* tess, double valueX, double valueY, double valueZ); -void gluTessProperty (GLUtesselator* tess, GLenum which, double data); -void gluTessVertex (GLUtesselator* tess, double *location, GLvoid* data); - -/* ErrorCode */ -#define GLU_INVALID_ENUM 100900 -#define GLU_INVALID_VALUE 100901 -#define GLU_OUT_OF_MEMORY 100902 - -/* TessCallback */ -#define GLU_TESS_BEGIN 100100 -#define GLU_BEGIN 100100 -#define GLU_TESS_VERTEX 100101 -#define GLU_VERTEX 100101 -#define GLU_TESS_END 100102 -#define GLU_END 100102 -#define GLU_TESS_ERROR 100103 -#define GLU_TESS_EDGE_FLAG 100104 -#define GLU_EDGE_FLAG 100104 -#define GLU_TESS_COMBINE 100105 -#define GLU_TESS_BEGIN_DATA 100106 -#define GLU_TESS_VERTEX_DATA 100107 -#define GLU_TESS_END_DATA 100108 -#define GLU_TESS_ERROR_DATA 100109 -#define GLU_TESS_EDGE_FLAG_DATA 100110 -#define GLU_TESS_COMBINE_DATA 100111 - -/* TessContour */ -#define GLU_CW 100120 -#define GLU_CCW 100121 -#define GLU_INTERIOR 100122 -#define GLU_EXTERIOR 100123 -#define GLU_UNKNOWN 100124 - -/* TessProperty */ -#define GLU_TESS_WINDING_RULE 100140 -#define GLU_TESS_BOUNDARY_ONLY 100141 -#define GLU_TESS_TOLERANCE 100142 - -/* TessError */ -#define GLU_TESS_ERROR1 100151 -#define GLU_TESS_ERROR2 100152 -#define GLU_TESS_ERROR3 100153 -#define GLU_TESS_ERROR4 100154 -#define GLU_TESS_ERROR5 100155 -#define GLU_TESS_ERROR6 100156 -#define GLU_TESS_ERROR7 100157 -#define GLU_TESS_ERROR8 100158 -#define GLU_TESS_MISSING_BEGIN_POLYGON 100151 -#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152 -#define GLU_TESS_MISSING_END_POLYGON 100153 -#define GLU_TESS_MISSING_END_CONTOUR 100154 -#define GLU_TESS_COORD_TOO_LARGE 100155 -#define GLU_TESS_NEED_COMBINE_CALLBACK 100156 - -/* TessWinding */ -#define GLU_TESS_WINDING_ODD 100130 -#define GLU_TESS_WINDING_NONZERO 100131 -#define GLU_TESS_WINDING_POSITIVE 100132 -#define GLU_TESS_WINDING_NEGATIVE 100133 -#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134 - -#endif /* __TESSELATOR_H__ */ diff --git a/clutter/cogl/cogl/tesselator/tessmono.c b/clutter/cogl/cogl/tesselator/tessmono.c deleted file mode 100644 index 4d08440..0000000 --- a/clutter/cogl/cogl/tesselator/tessmono.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "gluos.h" -#include -#include "geom.h" -#include "mesh.h" -#include "tessmono.h" -#include - -#define AddWinding(eDst,eSrc) (eDst->winding += eSrc->winding, \ - eDst->Sym->winding += eSrc->Sym->winding) - -/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region - * (what else would it do??) The region must consist of a single - * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this - * case means that any vertical line intersects the interior of the - * region in a single interval. - * - * Tessellation consists of adding interior edges (actually pairs of - * half-edges), to split the region into non-overlapping triangles. - * - * The basic idea is explained in Preparata and Shamos (which I don''t - * have handy right now), although their implementation is more - * complicated than this one. The are two edge chains, an upper chain - * and a lower chain. We process all vertices from both chains in order, - * from right to left. - * - * The algorithm ensures that the following invariant holds after each - * vertex is processed: the untessellated region consists of two - * chains, where one chain (say the upper) is a single edge, and - * the other chain is concave. The left vertex of the single edge - * is always to the left of all vertices in the concave chain. - * - * Each step consists of adding the rightmost unprocessed vertex to one - * of the two chains, and forming a fan of triangles from the rightmost - * of two chain endpoints. Determining whether we can add each triangle - * to the fan is a simple orientation test. By making the fan as large - * as possible, we restore the invariant (check it yourself). - */ -int __gl_meshTessellateMonoRegion( GLUface *face ) -{ - GLUhalfEdge *up, *lo; - - /* All edges are oriented CCW around the boundary of the region. - * First, find the half-edge whose origin vertex is rightmost. - * Since the sweep goes from left to right, face->anEdge should - * be close to the edge we want. - */ - up = face->anEdge; - assert( up->Lnext != up && up->Lnext->Lnext != up ); - - for( ; VertLeq( up->Dst, up->Org ); up = up->Lprev ) - ; - for( ; VertLeq( up->Org, up->Dst ); up = up->Lnext ) - ; - lo = up->Lprev; - - while( up->Lnext != lo ) { - if( VertLeq( up->Dst, lo->Org )) { - /* up->Dst is on the left. It is safe to form triangles from lo->Org. - * The EdgeGoesLeft test guarantees progress even when some triangles - * are CW, given that the upper and lower chains are truly monotone. - */ - while( lo->Lnext != up && (EdgeGoesLeft( lo->Lnext ) - || EdgeSign( lo->Org, lo->Dst, lo->Lnext->Dst ) <= 0 )) { - GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo ); - if (tempHalfEdge == NULL) return 0; - lo = tempHalfEdge->Sym; - } - lo = lo->Lprev; - } else { - /* lo->Org is on the left. We can make CCW triangles from up->Dst. */ - while( lo->Lnext != up && (EdgeGoesRight( up->Lprev ) - || EdgeSign( up->Dst, up->Org, up->Lprev->Org ) >= 0 )) { - GLUhalfEdge *tempHalfEdge= __gl_meshConnect( up, up->Lprev ); - if (tempHalfEdge == NULL) return 0; - up = tempHalfEdge->Sym; - } - up = up->Lnext; - } - } - - /* Now lo->Org == up->Dst == the leftmost vertex. The remaining region - * can be tessellated in a fan from this leftmost vertex. - */ - assert( lo->Lnext != up ); - while( lo->Lnext->Lnext != up ) { - GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo ); - if (tempHalfEdge == NULL) return 0; - lo = tempHalfEdge->Sym; - } - - return 1; -} - - -/* __gl_meshTessellateInterior( mesh ) tessellates each region of - * the mesh which is marked "inside" the polygon. Each such region - * must be monotone. - */ -int __gl_meshTessellateInterior( GLUmesh *mesh ) -{ - GLUface *f, *next; - - /*LINTED*/ - for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) { - /* Make sure we don''t try to tessellate the new triangles. */ - next = f->next; - if( f->inside ) { - if ( !__gl_meshTessellateMonoRegion( f ) ) return 0; - } - } - - return 1; -} - - -/* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces - * which are not marked "inside" the polygon. Since further mesh operations - * on NULL faces are not allowed, the main purpose is to clean up the - * mesh so that exterior loops are not represented in the data structure. - */ -void __gl_meshDiscardExterior( GLUmesh *mesh ) -{ - GLUface *f, *next; - - /*LINTED*/ - for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) { - /* Since f will be destroyed, save its next pointer. */ - next = f->next; - if( ! f->inside ) { - __gl_meshZapFace( f ); - } - } -} - -#define MARKED_FOR_DELETION 0x7fffffff - -/* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the - * winding numbers on all edges so that regions marked "inside" the - * polygon have a winding number of "value", and regions outside - * have a winding number of 0. - * - * If keepOnlyBoundary is TRUE, it also deletes all edges which do not - * separate an interior region from an exterior one. - */ -int __gl_meshSetWindingNumber( GLUmesh *mesh, int value, - GLboolean keepOnlyBoundary ) -{ - GLUhalfEdge *e, *eNext; - - for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) { - eNext = e->next; - if( e->Rface->inside != e->Lface->inside ) { - - /* This is a boundary edge (one side is interior, one is exterior). */ - e->winding = (e->Lface->inside) ? value : -value; - } else { - - /* Both regions are interior, or both are exterior. */ - if( ! keepOnlyBoundary ) { - e->winding = 0; - } else { - if ( !__gl_meshDelete( e ) ) return 0; - } - } - } - return 1; -} diff --git a/clutter/cogl/cogl/tesselator/tessmono.h b/clutter/cogl/cogl/tesselator/tessmono.h deleted file mode 100644 index 8ee1b2f..0000000 --- a/clutter/cogl/cogl/tesselator/tessmono.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __tessmono_h_ -#define __tessmono_h_ - -/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region - * (what else would it do??) The region must consist of a single - * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this - * case means that any vertical line intersects the interior of the - * region in a single interval. - * - * Tessellation consists of adding interior edges (actually pairs of - * half-edges), to split the region into non-overlapping triangles. - * - * __gl_meshTessellateInterior( mesh ) tessellates each region of - * the mesh which is marked "inside" the polygon. Each such region - * must be monotone. - * - * __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces - * which are not marked "inside" the polygon. Since further mesh operations - * on NULL faces are not allowed, the main purpose is to clean up the - * mesh so that exterior loops are not represented in the data structure. - * - * __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the - * winding numbers on all edges so that regions marked "inside" the - * polygon have a winding number of "value", and regions outside - * have a winding number of 0. - * - * If keepOnlyBoundary is TRUE, it also deletes all edges which do not - * separate an interior region from an exterior one. - */ - -int __gl_meshTessellateMonoRegion( GLUface *face ); -int __gl_meshTessellateInterior( GLUmesh *mesh ); -void __gl_meshDiscardExterior( GLUmesh *mesh ); -int __gl_meshSetWindingNumber( GLUmesh *mesh, int value, - GLboolean keepOnlyBoundary ); - -#endif diff --git a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h b/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h deleted file mode 100644 index 60c11b9..0000000 --- a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H -#define __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H - -#include -#include -#include - -#include - -#ifdef COGL_HAS_GLX_SUPPORT -#include -#endif - -#include "cogl-handle.h" -#include "cogl-texture-private.h" -#include "cogl-texture-pixmap-x11.h" - -#define COGL_TEXTURE_PIXMAP_X11(tex) ((CoglTexturePixmapX11 *) tex) - -typedef struct _CoglDamageRectangle CoglDamageRectangle; - -struct _CoglDamageRectangle -{ - unsigned int x1; - unsigned int y1; - unsigned int x2; - unsigned int y2; -}; - -typedef struct _CoglTexturePixmapX11 CoglTexturePixmapX11; - -struct _CoglTexturePixmapX11 -{ - CoglTexture _parent; - - Pixmap pixmap; - CoglHandle tex; - - unsigned int depth; - Visual *visual; - unsigned int width; - unsigned int height; - - XImage *image; - - XShmSegmentInfo shm_info; - - Damage damage; - CoglTexturePixmapX11ReportLevel damage_report_level; - gboolean damage_owned; - CoglDamageRectangle damage_rect; - - void *winsys; - - /* During the pre_paint method, this will be set to TRUE if we - should use the winsys texture, otherwise we will use the regular - texture */ - gboolean use_winsys_texture; -}; - -GQuark -_cogl_handle_texture_pixmap_x11_get_type (void); - -#endif /* __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H */ diff --git a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c deleted file mode 100644 index 01657d1..0000000 --- a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.c +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authors: - * Neil Roberts - * Johan Bilien - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-debug.h" -#include "cogl-internal.h" -#include "cogl-util.h" -#include "cogl-texture-pixmap-x11.h" -#include "cogl-texture-pixmap-x11-private.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-driver.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-rectangle-private.h" -#include "cogl-context-private.h" -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-handle.h" -#include "cogl-winsys-private.h" -#include "cogl-pipeline-opengl-private.h" - -#include -#include - -#include -#include -#include - -#include -#include - -static void _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap); - -COGL_TEXTURE_DEFINE (TexturePixmapX11, texture_pixmap_x11); - -static const CoglTextureVtable cogl_texture_pixmap_x11_vtable; - -static void -cogl_damage_rectangle_union (CoglDamageRectangle *damage_rect, - int x, - int y, - int width, - int height) -{ - /* If the damage region is empty then we'll just copy the new - rectangle directly */ - if (damage_rect->x1 == damage_rect->x2 || - damage_rect->y1 == damage_rect->y2) - { - damage_rect->x1 = x; - damage_rect->y1 = y; - damage_rect->x2 = x + width; - damage_rect->y2 = y + height; - } - else - { - if (damage_rect->x1 > x) - damage_rect->x1 = x; - if (damage_rect->y1 > y) - damage_rect->y1 = y; - if (damage_rect->x2 < x + width) - damage_rect->x2 = x + width; - if (damage_rect->y2 < y + height) - damage_rect->y2 = y + height; - } -} - -static gboolean -cogl_damage_rectangle_is_whole (const CoglDamageRectangle *damage_rect, - unsigned int width, - unsigned int height) -{ - return (damage_rect->x1 == 0 && damage_rect->y1 == 0 - && damage_rect->x2 == width && damage_rect->y2 == height); -} - -static const CoglWinsysVtable * -_cogl_texture_pixmap_x11_get_winsys (CoglTexturePixmapX11 *tex_pixmap) -{ - /* FIXME: A CoglContext should be reachable from a CoglTexture - * pointer */ - _COGL_GET_CONTEXT (ctx, NULL); - - return ctx->display->renderer->winsys_vtable; -} - -static void -process_damage_event (CoglTexturePixmapX11 *tex_pixmap, - XDamageNotifyEvent *damage_event) -{ - Display *display; - enum { DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; - const CoglWinsysVtable *winsys; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - display = cogl_xlib_get_display (); - - COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap); - - switch (tex_pixmap->damage_report_level) - { - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES: - /* For raw rectangles we don't need do look at the damage region - at all because the damage area is directly given in the event - struct and the reporting of events is not affected by - clearing the damage region */ - handle_mode = DO_NOTHING; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES: - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY: - /* For delta rectangles and non empty we'll query the damage - region for the bounding box */ - handle_mode = NEED_BOUNDING_BOX; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX: - /* For bounding box we need to clear the damage region but we - don't actually care what it was because the damage event - itself contains the bounding box of the region */ - handle_mode = NEEDS_SUBTRACT; - break; - - default: - g_assert_not_reached (); - } - - /* If the damage already covers the whole rectangle then we don't - need to request the bounding box of the region because we're - going to update the whole texture anyway. */ - if (cogl_damage_rectangle_is_whole (&tex_pixmap->damage_rect, - tex_pixmap->width, - tex_pixmap->height)) - { - if (handle_mode != DO_NOTHING) - XDamageSubtract (display, tex_pixmap->damage, None, None); - } - else if (handle_mode == NEED_BOUNDING_BOX) - { - XserverRegion parts; - int r_count; - XRectangle r_bounds; - XRectangle *r_damage; - - /* We need to extract the damage region so we can get the - bounding box */ - - parts = XFixesCreateRegion (display, 0, 0); - XDamageSubtract (display, tex_pixmap->damage, None, parts); - r_damage = XFixesFetchRegionAndBounds (display, - parts, - &r_count, - &r_bounds); - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - r_bounds.x, - r_bounds.y, - r_bounds.width, - r_bounds.height); - if (r_damage) - XFree (r_damage); - - XFixesDestroyRegion (display, parts); - } - else - { - if (handle_mode == NEEDS_SUBTRACT) - /* We still need to subtract from the damage region but we - don't care what the region actually was */ - XDamageSubtract (display, tex_pixmap->damage, None, None); - - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - damage_event->area.x, - damage_event->area.y, - damage_event->area.width, - damage_event->area.height); - } - - /* If we're using the texture from pixmap extension then there's no - point in getting the region and we can just mark that the texture - needs updating */ - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); -} - -static CoglFilterReturn -_cogl_texture_pixmap_x11_filter (void *native_event, void *data) -{ - XEvent *event = native_event; - CoglTexturePixmapX11 *tex_pixmap = data; - int damage_base; - - _COGL_GET_CONTEXT (ctxt, COGL_FILTER_CONTINUE); - - damage_base = _cogl_xlib_get_damage_base (); - if (event->type == damage_base + XDamageNotify) - { - XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) event; - - if (damage_event->damage == tex_pixmap->damage) - process_damage_event (tex_pixmap, damage_event); - } - - return COGL_FILTER_CONTINUE; -} - -static void -set_damage_object_internal (CoglTexturePixmapX11 *tex_pixmap, - Damage damage, - CoglTexturePixmapX11ReportLevel report_level) -{ - if (tex_pixmap->damage) - { - _cogl_xlib_remove_filter (_cogl_texture_pixmap_x11_filter, tex_pixmap); - - if (tex_pixmap->damage_owned) - { - XDamageDestroy (cogl_xlib_get_display (), tex_pixmap->damage); - tex_pixmap->damage_owned = FALSE; - } - } - - tex_pixmap->damage = damage; - tex_pixmap->damage_report_level = report_level; - - if (damage) - _cogl_xlib_add_filter (_cogl_texture_pixmap_x11_filter, tex_pixmap); -} - -CoglHandle -cogl_texture_pixmap_x11_new (guint32 pixmap, - gboolean automatic_updates) -{ - CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1); - Display *display = cogl_xlib_get_display (); - Window pixmap_root_window; - int pixmap_x, pixmap_y; - unsigned int pixmap_border_width; - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - XWindowAttributes window_attributes; - int damage_base; - const CoglWinsysVtable *winsys; - - _COGL_GET_CONTEXT (ctxt, COGL_INVALID_HANDLE); - - _cogl_texture_init (tex, &cogl_texture_pixmap_x11_vtable); - - tex_pixmap->pixmap = pixmap; - tex_pixmap->image = NULL; - tex_pixmap->shm_info.shmid = -1; - tex_pixmap->tex = COGL_INVALID_HANDLE; - tex_pixmap->damage_owned = FALSE; - tex_pixmap->damage = 0; - - if (!XGetGeometry (display, pixmap, &pixmap_root_window, - &pixmap_x, &pixmap_y, - &tex_pixmap->width, &tex_pixmap->height, - &pixmap_border_width, &tex_pixmap->depth)) - { - g_free (tex_pixmap); - g_warning ("Unable to query pixmap size"); - return COGL_INVALID_HANDLE; - } - - /* We need a visual to use for shared memory images so we'll query - it from the pixmap's root window */ - if (!XGetWindowAttributes (display, pixmap_root_window, &window_attributes)) - { - g_free (tex_pixmap); - g_warning ("Unable to query root window attributes"); - return COGL_INVALID_HANDLE; - } - tex_pixmap->visual = window_attributes.visual; - - /* If automatic updates are requested and the Xlib connection - supports damage events then we'll register a damage object on the - pixmap */ - damage_base = _cogl_xlib_get_damage_base (); - if (automatic_updates && damage_base >= 0) - { - Damage damage = XDamageCreate (display, - pixmap, - XDamageReportBoundingBox); - set_damage_object_internal (tex_pixmap, - damage, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX); - tex_pixmap->damage_owned = TRUE; - } - - /* Assume the entire pixmap is damaged to begin with */ - tex_pixmap->damage_rect.x1 = 0; - tex_pixmap->damage_rect.x2 = tex_pixmap->width; - tex_pixmap->damage_rect.y1 = 0; - tex_pixmap->damage_rect.y2 = tex_pixmap->height; - - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - if (winsys->texture_pixmap_x11_create) - winsys->texture_pixmap_x11_create (tex_pixmap); - - return _cogl_texture_pixmap_x11_handle_new (tex_pixmap); -} - -/* Tries to allocate enough shared mem to handle a full size - * update size of the X Pixmap. */ -static void -try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap) -{ - XImage *dummy_image; - Display *display; - - display = cogl_xlib_get_display (); - - if (!XShmQueryExtension (display)) - return; - - /* We are creating a dummy_image so we can have Xlib calculate - * image->bytes_per_line - including any magic padding it may - * want - for the largest possible ximage we might need to use - * when handling updates to the texture. - * - * Note: we pass a NULL shminfo here, but that has no bearing - * on the setup of the XImage, except that ximage->obdata will - * == NULL. - */ - dummy_image = - XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - NULL, /* shminfo, */ - tex_pixmap->width, - tex_pixmap->height); - if (!dummy_image) - goto failed_image_create; - - tex_pixmap->shm_info.shmid = shmget (IPC_PRIVATE, - dummy_image->bytes_per_line - * dummy_image->height, - IPC_CREAT | 0777); - if (tex_pixmap->shm_info.shmid == -1) - goto failed_shmget; - - tex_pixmap->shm_info.shmaddr = shmat (tex_pixmap->shm_info.shmid, 0, 0); - if (tex_pixmap->shm_info.shmaddr == (void *) -1) - goto failed_shmat; - - tex_pixmap->shm_info.readOnly = False; - - if (XShmAttach (display, &tex_pixmap->shm_info) == 0) - goto failed_xshmattach; - - XDestroyImage (dummy_image); - - return; - - failed_xshmattach: - g_warning ("XShmAttach failed"); - shmdt (tex_pixmap->shm_info.shmaddr); - - failed_shmat: - g_warning ("shmat failed"); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - - failed_shmget: - g_warning ("shmget failed"); - XDestroyImage (dummy_image); - - failed_image_create: - tex_pixmap->shm_info.shmid = -1; -} - -void -cogl_texture_pixmap_x11_update_area (CoglHandle handle, - int x, - int y, - int width, - int height) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle); - const CoglWinsysVtable *winsys; - - if (!cogl_is_texture_pixmap_x11 (handle)) - return; - - /* We'll queue the update for both the GLX texture and the regular - texture because we can't determine which will be needed until we - actually render something */ - - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); - - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - x, y, width, height); -} - -gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglHandle handle) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle); - - if (!cogl_is_texture_pixmap_x11 (tex_pixmap)) - return FALSE; - - return !!tex_pixmap->winsys; -} - -void -cogl_texture_pixmap_x11_set_damage_object (CoglHandle handle, - guint32 damage, - CoglTexturePixmapX11ReportLevel - report_level) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (handle); - int damage_base; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - if (!cogl_is_texture_pixmap_x11 (tex_pixmap)) - return; - - damage_base = _cogl_xlib_get_damage_base (); - if (damage_base >= 0) - set_damage_object_internal (tex_pixmap, damage, report_level); -} - -static void -_cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - Display *display; - CoglPixelFormat image_format; - XImage *image; - int src_x, src_y; - int x, y, width, height; - - display = cogl_xlib_get_display (); - - /* If the damage region is empty then there's nothing to do */ - if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1) - return; - - x = tex_pixmap->damage_rect.x1; - y = tex_pixmap->damage_rect.y1; - width = tex_pixmap->damage_rect.x2 - x; - height = tex_pixmap->damage_rect.y2 - y; - - /* We lazily create the texture the first time it is needed in case - this texture can be entirely handled using the GLX texture - instead */ - if (tex_pixmap->tex == COGL_INVALID_HANDLE) - { - CoglPixelFormat texture_format; - - texture_format = (tex_pixmap->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tex_pixmap->tex = cogl_texture_new_with_size (tex_pixmap->width, - tex_pixmap->height, - COGL_TEXTURE_NONE, - texture_format); - } - - if (tex_pixmap->image == NULL) - { - /* If we also haven't got a shm segment then this must be the - first time we've tried to update, so lets try allocating shm - first */ - if (tex_pixmap->shm_info.shmid == -1) - try_alloc_shm (tex_pixmap); - - if (tex_pixmap->shm_info.shmid == -1) - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap); - - /* We'll fallback to using a regular XImage. We'll download - the entire area instead of a sub region because presumably - if this is the first update then the entire pixmap is - needed anyway and it saves trying to manually allocate an - XImage at the right size */ - tex_pixmap->image = XGetImage (display, - tex_pixmap->pixmap, - 0, 0, - tex_pixmap->width, tex_pixmap->height, - AllPlanes, ZPixmap); - image = tex_pixmap->image; - src_x = x; - src_y = y; - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage", - tex_pixmap); - - /* Create a temporary image using the beginning of the - shared memory segment and the right size for the region - we want to update. We need to reallocate the XImage every - time because there is no XShmGetSubImage. */ - image = XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - &tex_pixmap->shm_info, - width, - height); - image->data = tex_pixmap->shm_info.shmaddr; - src_x = 0; - src_y = 0; - - XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes); - } - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap); - - image = tex_pixmap->image; - src_x = x; - src_y = y; - - XGetSubImage (display, - tex_pixmap->pixmap, - x, y, width, height, - AllPlanes, ZPixmap, - image, - x, y); - } - - /* xlib doesn't appear to fill in image->{red,green,blue}_mask so - this just assumes that the image is stored as ARGB from most - significant byte to to least significant. If the format is little - endian that means the order will be BGRA in memory */ - - switch (image->bits_per_pixel) - { - default: - case 32: - { - /* If the pixmap is actually non-packed-pixel RGB format then - the texture would have been created in RGB_888 format so Cogl - will ignore the alpha channel and effectively pack it for - us */ - image_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - - /* If the format is actually big endian then the alpha - component will come first */ - if (image->byte_order == MSBFirst) - image_format |= COGL_AFIRST_BIT; - } - break; - - case 24: - image_format = COGL_PIXEL_FORMAT_RGB_888; - break; - - case 16: - /* FIXME: this should probably swap the orders around if the - endianness does not match */ - image_format = COGL_PIXEL_FORMAT_RGB_565; - break; - } - - if (image->bits_per_pixel != 16) - { - /* If the image is in little-endian then the order in memory is - reversed */ - if (image->byte_order == LSBFirst) - image_format |= COGL_BGR_BIT; - } - - cogl_texture_set_region (tex_pixmap->tex, - src_x, src_y, - x, y, width, height, - image->width, - image->height, - image_format, - image->bytes_per_line, - (const guint8 *) image->data); - - /* If we have a shared memory segment then the XImage would be a - temporary one with no data allocated so we can just XFree it */ - if (tex_pixmap->shm_info.shmid != -1) - XFree (image); - - memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle)); -} - -static void -_cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixmap, - gboolean new_value) -{ - if (tex_pixmap->use_winsys_texture != new_value) - { - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (tex_pixmap); - - tex_pixmap->use_winsys_texture = new_value; - } -} - -static void -_cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap) -{ - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - - if (winsys->texture_pixmap_x11_update (tex_pixmap, needs_mipmap)) - { - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE); - return; - } - } - - /* If it didn't work then fallback to using XGetImage. This may be - temporary */ - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, FALSE); - - _cogl_texture_pixmap_x11_update_image_texture (tex_pixmap); -} - -static CoglHandle -_cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglHandle tex; - int i; - - /* We try getting the texture twice, once without flushing the - updates and once with. If pre_paint has been called already then - we should have a good idea of which texture to use so we don't - want to mess with that by ensuring the updates. However, if we - couldn't find a texture then we'll just make a best guess by - flushing without expecting mipmap support and try again. This - would happen for example if an application calls - get_gl_texture before the first paint */ - - for (i = 0; i < 2; i++) - { - if (tex_pixmap->use_winsys_texture) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap); - } - else - tex = tex_pixmap->tex; - - if (tex) - return tex; - - _cogl_texture_pixmap_x11_update (tex_pixmap, FALSE); - } - - g_assert_not_reached (); - - return COGL_INVALID_HANDLE; -} - -static gboolean -_cogl_texture_pixmap_x11_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bmp) -{ - /* This doesn't make much sense for texture from pixmap so it's not - supported */ - return FALSE; -} - -static gboolean -_cogl_texture_pixmap_x11_get_data (CoglTexture *tex, - CoglPixelFormat format, - unsigned int rowstride, - guint8 *data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_data (child_tex, format, rowstride, data); -} - -static void -_cogl_texture_pixmap_x11_foreach_sub_texture_in_region - (CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglTextureSliceCallback callback, - void *user_data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_foreach_sub_texture_in_region (child_tex, - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - callback, - user_data); -} - -static int -_cogl_texture_pixmap_x11_get_max_waste (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_get_max_waste (child_tex); -} - -static gboolean -_cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_is_sliced (child_tex); -} - -static gboolean -_cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_get_max_waste (child_tex); -} - -static void -_cogl_texture_pixmap_x11_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_transform_coords_to_gl (child_tex, s, t); -} - -static CoglTransformResult -_cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords); -} - -static gboolean -_cogl_texture_pixmap_x11_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_gl_texture (child_tex, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_texture_pixmap_x11_set_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_set_filters (child_tex, min_filter, mag_filter); -} - -static void -_cogl_texture_pixmap_x11_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - _cogl_texture_pixmap_x11_update (tex_pixmap, - !!(flags & COGL_TEXTURE_NEEDS_MIPMAP)); - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - _cogl_texture_pre_paint (child_tex, flags); -} - -static void -_cogl_texture_pixmap_x11_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_ensure_non_quad_rendering (child_tex); -} - -static void -_cogl_texture_pixmap_x11_set_wrap_mode_parameters (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_set_wrap_mode_parameters (child_tex, - wrap_mode_s, - wrap_mode_t, - wrap_mode_p); -} - -static CoglPixelFormat -_cogl_texture_pixmap_x11_get_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_format (child_tex); -} - -static GLenum -_cogl_texture_pixmap_x11_get_gl_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglHandle child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return _cogl_texture_get_gl_format (child_tex); -} - -static int -_cogl_texture_pixmap_x11_get_width (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - - return tex_pixmap->width; -} - -static int -_cogl_texture_pixmap_x11_get_height (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - - return tex_pixmap->height; -} - -static void -_cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - set_damage_object_internal (tex_pixmap, 0, 0); - - if (tex_pixmap->image) - XDestroyImage (tex_pixmap->image); - - if (tex_pixmap->shm_info.shmid != -1) - { - XShmDetach (cogl_xlib_get_display (), &tex_pixmap->shm_info); - shmdt (tex_pixmap->shm_info.shmaddr); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - } - - if (tex_pixmap->tex) - cogl_handle_unref (tex_pixmap->tex); - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_free (tex_pixmap); - } - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_pixmap)); -} - -static const CoglTextureVtable -cogl_texture_pixmap_x11_vtable = - { - _cogl_texture_pixmap_x11_set_region, - _cogl_texture_pixmap_x11_get_data, - _cogl_texture_pixmap_x11_foreach_sub_texture_in_region, - _cogl_texture_pixmap_x11_get_max_waste, - _cogl_texture_pixmap_x11_is_sliced, - _cogl_texture_pixmap_x11_can_hardware_repeat, - _cogl_texture_pixmap_x11_transform_coords_to_gl, - _cogl_texture_pixmap_x11_transform_quad_coords_to_gl, - _cogl_texture_pixmap_x11_get_gl_texture, - _cogl_texture_pixmap_x11_set_filters, - _cogl_texture_pixmap_x11_pre_paint, - _cogl_texture_pixmap_x11_ensure_non_quad_rendering, - _cogl_texture_pixmap_x11_set_wrap_mode_parameters, - _cogl_texture_pixmap_x11_get_format, - _cogl_texture_pixmap_x11_get_gl_format, - _cogl_texture_pixmap_x11_get_width, - _cogl_texture_pixmap_x11_get_height, - NULL /* is_foreign */ - }; diff --git a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h b/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h deleted file mode 100644 index b2a4ae0..0000000 --- a/clutter/cogl/cogl/winsys/cogl-texture-pixmap-x11.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_TEXTURE_PIXMAP_X11_H -#define __COGL_TEXTURE_PIXMAP_X11_H - -#include - -#ifdef COGL_ENABLE_EXPERIMENTAL_API - -/* All of the cogl-texture-pixmap-x11 API is currently experimental so - * we suffix the actual symbols with _EXP so if somone is monitoring - * for ABI changes it will hopefully be clearer to them what's going - * on if any of the symbols dissapear at a later date. - */ -#define cogl_texture_pixmap_x11_new cogl_texture_pixmap_x11_new_EXP -#define cogl_texture_pixmap_x11_update_area \ - cogl_texture_pixmap_x11_update_area_EXP -#define cogl_texture_pixmap_x11_is_using_tfp_extension \ - cogl_texture_pixmap_x11_is_using_tfp_extension_EXP -#define cogl_texture_pixmap_x11_set_damage_object \ - cogl_texture_pixmap_x11_set_damage_object_EXP -#define cogl_is_texture_pixmap_x11 cogl_is_texture_pixmap_x11_EXP - -typedef enum -{ - COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY -} CoglTexturePixmapX11ReportLevel; - -/** - * cogl_texture_pixmap_x11_new: - * @pixmap: A X11 pixmap ID - * @automatic_updates: Whether to automatically copy the contents of - * the pixmap to the texture. - * - * Creates a texture that contains the contents of @pixmap. If - * @automatic_updates is %TRUE then Cogl will attempt to listen for - * damage events on the pixmap and automatically update the texture - * when it changes. - * - * Return value: a CoglHandle to a texture - * - * Since: 1.4 - * Stability: Unstable - */ -CoglHandle -cogl_texture_pixmap_x11_new (guint32 pixmap, - gboolean automatic_updates); - -/** - * cogl_texture_pixmap_x11_update_area: - * @handle: A CoglHandle to a CoglTexturePixmapX11 instance - * @x: x coordinate of the area to update - * @y: y coordinate of the area to update - * @width: width of the area to update - * @height: height of the area to update - * - * Forces an update of the texture pointed to by @handle so that it is - * refreshed with the contents of the pixmap that was given to - * cogl_texture_pixmap_x11_new(). - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_texture_pixmap_x11_update_area (CoglHandle handle, - int x, - int y, - int width, - int height); - -/** - * cogl_texture_pixmap_x11_is_using_tfp_extension: - * @handle: A CoglHandle to a CoglTexturePixmapX11 instance - * - * Checks whether the texture is using the GLX_EXT_texture_from_pixmap - * or similar extension to copy the contents of the pixmap to the texture. - * This extension is usually implemented as zero-copy operation so it - * implies the updates are working efficiently. - * - * Return value: %TRUE if the texture is using an efficient extension - * and %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglHandle handle); - -/** - * cogl_texture_pixmap_x11_set_damage_object: - * @handle: A CoglHandle - * @damage: A X11 Damage object or 0 - * @report_level: The report level which describes how to interpret - * the damage events. This should match the level that the damage - * object was created with. - * - * Sets the damage object that will be used to track automatic updates - * to the texture. Damage tracking can be disabled by passing 0 for - * @damage. Otherwise this damage will replace the one used if %TRUE - * was passed for automatic_updates to cogl_texture_pixmap_x11_new(). - * - * Note that Cogl will subtract from the damage region as it processes - * damage events. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_texture_pixmap_x11_set_damage_object (CoglHandle handle, - guint32 damage, - CoglTexturePixmapX11ReportLevel - report_level); - -/** - * cogl_is_texture_pixmap_x11: - * @handle: A CoglHandle - * - * Checks whether @handle points to a CoglTexturePixmapX11 instance. - * - * Return value: %TRUE if the handle is a CoglTexturePixmapX11, and - * %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -gboolean -cogl_is_texture_pixmap_x11 (CoglHandle handle); - -#endif /* COGL_ENABLE_EXPERIMENTAL_API */ - -#endif /* __COGL_TEXTURE_PIXMAP_X11_H */ diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h b/clutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h deleted file mode 100644 index 58c0734..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names, - * implied_public_feature_flags, - * implied_private_feature_flags, - * implied_winsys_feature) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics accross - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -COGL_WINSYS_FEATURE_BEGIN (swap_region, - "NOK\0", - "swap_region\0", - 0, - 0, - COGL_WINSYS_FEATURE_SWAP_REGION) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion, - (EGLDisplay dpy, - EGLSurface surface, - EGLint numRects, - const EGLint *rects)) -COGL_WINSYS_FEATURE_END () diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-egl.c b/clutter/cogl/cogl/winsys/cogl-winsys-egl.c deleted file mode 100644 index 22fd611..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys-egl.c +++ /dev/null @@ -1,1282 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" - -#include "cogl-winsys-private.h" -#include "cogl-feature-private.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer.h" -#include "cogl-swap-chain-private.h" -#include "cogl-renderer-private.h" -#include "cogl-onscreen-template-private.h" -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT -#include "cogl-renderer-xlib-private.h" -#include "cogl-display-xlib-private.h" -#endif -#include "cogl-private.h" - -#include -#include -#include -#include - -#include - -#ifdef COGL_HAS_GLES1 - -#include -#include - -#else - -#include -#define NativeDisplayType EGLNativeDisplayType -#define NativeWindowType EGLNativeWindowType - -#endif - - -#include - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT -#include - -#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask -#endif - -typedef struct _CoglRendererEGL -{ -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - CoglRendererXlib _parent; -#endif - - EGLDisplay edpy; - - EGLint egl_version_major; - EGLint egl_version_minor; - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT - gboolean gdl_initialized; -#endif - - /* Function pointers for GLX specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * pf_ ## name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "cogl-winsys-egl-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglRendererEGL; - -typedef struct _CoglDisplayEGL -{ -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - CoglDisplayXlib _parent; -#endif - - EGLContext egl_context; -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - EGLSurface dummy_surface; -#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \ - defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) - EGLSurface egl_surface; - int egl_surface_width; - int egl_surface_height; - gboolean have_onscreen; -#else -#error "Unknown EGL platform" -#endif - - EGLConfig egl_config; - gboolean found_egl_config; -} CoglDisplayEGL; - -typedef struct _CoglContextEGL -{ - EGLSurface current_surface; -} CoglContextEGL; - -typedef struct _CoglOnscreenXlib -{ - Window xwin; - gboolean is_foreign_xwin; -} CoglOnscreenXlib; - -typedef struct _CoglOnscreenEGL -{ - CoglOnscreenXlib _parent; - EGLSurface egl_surface; -} CoglOnscreenEGL; - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - feature_flags, feature_flags_private, \ - winsys_feature) \ - static const CoglFeatureFunction \ - cogl_egl_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglRendererEGL, pf_ ## name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl-winsys-egl-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - feature_flags, feature_flags_private, \ - winsys_feature) \ - { 255, 255, namespaces, extension_names, \ - feature_flags, feature_flags_private, \ - winsys_feature, \ - cogl_egl_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "cogl-winsys-egl-feature-functions.h" - }; - -static CoglFuncPtr -_cogl_winsys_get_proc_address (const char *name) -{ - return (CoglFuncPtr) eglGetProcAddress (name); -} - -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f) -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - egl_renderer->pf_ ## name = NULL; -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static void -initialize_function_table (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - -#include "cogl-winsys-egl-feature-functions.h" -} - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, guint32 xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreenXlib *xlib_onscreen; - - if (!framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - continue; - - xlib_onscreen = COGL_ONSCREEN (framebuffer)->winsys; - if (xlib_onscreen->xwin == (Window)xid) - return COGL_ONSCREEN (framebuffer); - } - - return NULL; -} - -static CoglFilterReturn -event_filter_cb (void *event, void *data) -{ - XEvent *xevent = event; - CoglContext *context = data; - - if (xevent->type == ConfigureNotify) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xconfigure.window); - - if (onscreen) - { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - /* XXX: consider adding an abstraction for this... */ - framebuffer->width = xevent->xconfigure.width; - framebuffer->height = xevent->xconfigure.height; - } - } - - return COGL_FILTER_CONTINUE; -} -#endif /* COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT */ - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT - if (egl_renderer->gdl_initialized) - gdl_close (); -#endif - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - _cogl_renderer_xlib_disconnect (renderer); -#endif - - eglTerminate (egl_renderer->edpy); - - g_slice_free (CoglRendererEGL, egl_renderer); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglRendererEGL *egl_renderer; -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - CoglRendererXlib *xlib_renderer; -#endif - EGLBoolean status; -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT - gdl_ret_t rc = GDL_SUCCESS; - gdl_display_info_t gdl_display_info; -#endif - - renderer->winsys = g_slice_new0 (CoglRendererEGL); - - egl_renderer = renderer->winsys; -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - xlib_renderer = renderer->winsys; - - if (!_cogl_renderer_xlib_connect (renderer, error)) - goto error; - - egl_renderer->edpy = - eglGetDisplay ((NativeDisplayType) xlib_renderer->xdpy); - - status = eglInitialize (egl_renderer->edpy, - &egl_renderer->egl_version_major, - &egl_renderer->egl_version_minor); -#else - egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY); - - status = eglInitialize (egl_renderer->edpy, - &egl_renderer->egl_version_major, - &egl_renderer->egl_version_minor); -#endif - - if (status != EGL_TRUE) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to initialize EGL"); - goto error; - } - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT - /* Check we can talk to the GDL library */ - - rc = gdl_init (NULL); - if (rc != GDL_SUCCESS) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "GDL initialize failed. %s", - gdl_get_error_string (rc)); - goto error; - } - - rc = gdl_get_display_info (GDL_DISPLAY_ID_0, &gdl_display_info); - if (rc != GDL_SUCCESS) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "GDL failed to get display information: %s", - gdl_get_error_string (rc)); - gdl_close (); - goto error; - } - - gdl_close (); -#endif - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static void -update_winsys_features (CoglContext *context) -{ - CoglDisplayEGL *egl_display = context->display->winsys; - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - const char *egl_extensions; - int i; - - g_return_if_fail (egl_display->egl_context); - - _cogl_gl_update_features (context); - - memset (context->winsys_features, 0, sizeof (context->winsys_features)); - - egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS); - - COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions); - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE; - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, - TRUE); -#endif - - initialize_function_table (context->display->renderer); - - for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) - if (_cogl_feature_check ("EGL", winsys_feature_data + i, 0, 0, - egl_extensions, - egl_renderer)) - { - context->feature_flags |= winsys_feature_data[i].feature_flags; - if (winsys_feature_data[i].winsys_feature) - COGL_FLAGS_SET (context->winsys_features, - winsys_feature_data[i].winsys_feature, - TRUE); - } - - /* FIXME: the winsys_feature_data can currently only have one - * winsys feature per extension... */ - if (egl_renderer->pf_eglSwapBuffersRegion) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); - } -} - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT -static XVisualInfo * -get_visual_info (CoglDisplay *display, EGLConfig egl_config) -{ - CoglRendererXlib *xlib_renderer = display->renderer->winsys; - CoglRendererEGL *egl_renderer = display->renderer->winsys; - XVisualInfo visinfo_template; - int template_mask = 0; - XVisualInfo *visinfo = NULL; - int visinfos_count; - EGLint visualid, red_size, green_size, blue_size, alpha_size; - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_NATIVE_VISUAL_ID, &visualid); - - if (visualid != 0) - { - visinfo_template.visualid = visualid; - template_mask |= VisualIDMask; - } - else - { - /* some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID - * attribute, so attempt to find the closest match. */ - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_RED_SIZE, &red_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_GREEN_SIZE, &green_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_BLUE_SIZE, &blue_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_ALPHA_SIZE, &alpha_size); - - visinfo_template.depth = red_size + green_size + blue_size + alpha_size; - template_mask |= VisualDepthMask; - - visinfo_template.screen = DefaultScreen (xlib_renderer->xdpy); - template_mask |= VisualScreenMask; - } - - visinfo = XGetVisualInfo (xlib_renderer->xdpy, - template_mask, - &visinfo_template, - &visinfos_count); - - return visinfo; -} -#endif - -static gboolean -try_create_context (CoglDisplay *display, - int retry_cookie, - gboolean *try_fallback, - GError **error) -{ - CoglDisplayEGL *egl_display = display->winsys; -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - CoglDisplayXlib *xlib_display = display->winsys; - CoglRendererXlib *xlib_renderer = display->renderer->winsys; -#endif - CoglRendererEGL *egl_renderer = display->renderer->winsys; - EGLDisplay edpy; - EGLConfig config; - EGLint config_count = 0; - EGLBoolean status; - EGLint cfg_attribs[] = { - /* NB: This must be the first attribute, since we may - * try and fallback to no stencil buffer */ - EGL_STENCIL_SIZE, 2, - - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_ALPHA_SIZE, EGL_DONT_CARE, - - EGL_DEPTH_SIZE, 1, - - /* XXX: Why does the GDL platform choose these by default? */ -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT - EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE, - EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE, -#endif - - EGL_BUFFER_SIZE, EGL_DONT_CARE, - -#if defined (HAVE_COGL_GL) - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, -#elif defined (HAVE_COGL_GLES2) - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, -#else - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, -#endif - - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - - EGL_NONE - }; -#if defined (HAVE_COGL_GLES2) - EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; -#else - EGLint *attribs = NULL; -#endif - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - XVisualInfo *xvisinfo; - XSetWindowAttributes attrs; -#endif - const char *error_message; - - edpy = egl_renderer->edpy; - -#ifdef HAVE_COGL_GL - eglBindAPI (EGL_OPENGL_API); -#endif - - /* Some GLES hardware can't support a stencil buffer: */ - if (retry_cookie == 1) - { - g_warning ("Trying with stencil buffer disabled..."); - cfg_attribs[1 /* EGL_STENCIL_SIZE */] = 0; - } - /* XXX: at this point we only have one fallback */ - - status = eglChooseConfig (edpy, - cfg_attribs, - &config, 1, - &config_count); - if (status != EGL_TRUE || config_count == 0) - { - error_message = "Unable to find a usable EGL configuration"; - goto fail; - } - - egl_display->egl_config = config; - - egl_display->egl_context = eglCreateContext (edpy, - config, - EGL_NO_CONTEXT, - attribs); - if (egl_display->egl_context == EGL_NO_CONTEXT) - { - error_message = "Unable to create a suitable EGL context"; - goto fail; - } - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - - xvisinfo = get_visual_info (display, config); - if (xvisinfo == NULL) - { - error_message = "Unable to find suitable X visual"; - goto fail; - } - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - xlib_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | - CWColormap | - CWBorderPixel, - &attrs); - - XFree (xvisinfo); - - egl_display->dummy_surface = - eglCreateWindowSurface (edpy, - egl_display->egl_config, - (NativeWindowType) xlib_display->dummy_xwin, - NULL); - - if (egl_display->dummy_surface == EGL_NO_SURFACE) - { - /* FIXME: we shouldn't be calling g_set_error here we should - * just set error_message same goes for below. */ - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create an EGL surface"); - goto fail; - } - - if (!eglMakeCurrent (edpy, - egl_display->dummy_surface, - egl_display->dummy_surface, - egl_display->egl_context)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to eglMakeCurrent with dummy surface"); - goto fail; - } - -#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) - - egl_display->egl_surface = - eglCreateWindowSurface (edpy, - config, - (NativeWindowType) NULL, - NULL); - if (egl_display->egl_surface == EGL_NO_SURFACE) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create EGL window surface"); - goto fail; - } - - if (!eglMakeCurrent (egl_renderer->edpy, - egl_display->egl_surface, - egl_display->egl_surface, - egl_display->egl_context)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to eglMakeCurrent with egl surface"); - goto fail; - } - - eglQuerySurface (egl_renderer->edpy, - egl_display->egl_surface, - EGL_WIDTH, - &egl_display->egl_surface_width); - - eglQuerySurface (egl_renderer->edpy, - egl_display->egl_surface, - EGL_HEIGHT, - &egl_display->egl_surface_height); - -#else -#error "Unknown EGL platform" -#endif - - return TRUE; - -fail: - - /* Currently we only have one fallback path... */ - if (retry_cookie == 0) - { - *try_fallback = TRUE; - return FALSE; - } - else - { - *try_fallback = FALSE; - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "%s", error_message); - return FALSE; - } -} - -static void -cleanup_context (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = display->renderer->winsys; -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - CoglDisplayXlib *xlib_display = display->winsys; - CoglRendererXlib *xlib_renderer = display->renderer->winsys; -#endif - - if (egl_display->egl_context != EGL_NO_CONTEXT) - { - eglMakeCurrent (egl_renderer->edpy, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - eglDestroyContext (egl_renderer->edpy, egl_display->egl_context); - egl_display->egl_context = EGL_NO_CONTEXT; - } - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - if (egl_display->dummy_surface != EGL_NO_SURFACE) - { - eglDestroySurface (egl_renderer->edpy, egl_display->dummy_surface); - egl_display->dummy_surface = EGL_NO_SURFACE; - } - - if (xlib_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, xlib_display->dummy_xwin); - xlib_display->dummy_xwin = None; - } -#endif -} - -static gboolean -create_context (CoglDisplay *display, GError **error) -{ - CoglDisplayEGL *egl_display = display->winsys; - gboolean support_transparent_windows; - int retry_cookie = 0; - gboolean status; - gboolean try_fallback; - GError *try_error = NULL; - - g_return_val_if_fail (egl_display->egl_context == NULL, TRUE); - - if (display->onscreen_template && - display->onscreen_template->swap_chain && - display->onscreen_template->swap_chain->has_alpha) - support_transparent_windows = TRUE; - else - support_transparent_windows = FALSE; - - retry_cookie = 0; - while (!(status = try_create_context (display, - retry_cookie, - &try_fallback, - &try_error)) && - try_fallback) - { - g_error_free (try_error); - cleanup_context (display); - try_error = NULL; - retry_cookie++; - } - if (!status) - g_propagate_error (error, try_error); - - return status; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - - g_return_if_fail (egl_display != NULL); - - cleanup_context (display); - - g_slice_free (CoglDisplayEGL, display->winsys); - display->winsys = NULL; -} - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT -static gboolean -gdl_plane_init (CoglDisplay *display, GError **error) -{ - gboolean ret = TRUE; - gdl_color_space_t colorSpace = GDL_COLOR_SPACE_RGB; - gdl_rectangle_t dstRect; - gdl_display_info_t display_info; - gdl_ret_t rc = GDL_SUCCESS; - - if (!display->gdl_plane) - { - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, - "No GDL plane specified with " - "cogl_gdl_display_set_plane"); - return FALSE; - } - - rc = gdl_init (NULL); - if (rc != GDL_SUCCESS) - { - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, - "GDL initialize failed. %s", gdl_get_error_string (rc)); - return FALSE; - } - - rc = gdl_get_display_info (GDL_DISPLAY_ID_0, &display_info); - if (rc != GDL_SUCCESS) - { - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, - "GDL failed to get display infomation: %s", - gdl_get_error_string (rc)); - gdl_close (); - return FALSE; - } - - dstRect.origin.x = 0; - dstRect.origin.y = 0; - dstRect.width = display_info.tvmode.width; - dstRect.height = display_info.tvmode.height; - - /* Configure the plane attribute. */ - rc = gdl_plane_reset (plane); - if (rc == GDL_SUCCESS) - rc = gdl_plane_config_begin (plane); - - if (rc == GDL_SUCCESS) - rc = gdl_plane_set_attr (GDL_PLANE_SRC_COLOR_SPACE, &colorSpace); - - if (rc == GDL_SUCCESS) - rc = gdl_plane_set_attr (GDL_PLANE_PIXEL_FORMAT, &pixfmt); - - if (rc == GDL_SUCCESS) - rc = gdl_plane_set_attr (GDL_PLANE_DST_RECT, &dstRect); - - if (rc == GDL_SUCCESS) - rc = gdl_plane_set_uint (GDL_PLANE_NUM_GFX_SURFACES, - display->swap_chain->length); - - if (rc == GDL_SUCCESS) - rc = gdl_plane_config_end (GDL_FALSE); - else - gdl_plane_config_end (GDL_TRUE); - - if (rc != GDL_SUCCESS) - { - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, - "GDL configuration failed: %s.", gdl_get_error_string (rc)); - ret = FALSE; - } - - gdl_close (); -} -#endif - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayEGL *egl_display; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - egl_display = g_slice_new0 (CoglDisplayEGL); - display->winsys = egl_display; - -#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT - if (!gdl_plane_init (display, error)) - goto error; -#endif - - if (!create_context (display, error)) - goto error; - - egl_display->found_egl_config = TRUE; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -static gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error) -{ - context->winsys = g_new0 (CoglContextEGL, 1); - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - cogl_renderer_add_native_filter (context->display->renderer, - event_filter_cb, - context); -#endif - update_winsys_features (context); - - return TRUE; -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - cogl_renderer_remove_native_filter (context->display->renderer, - event_filter_cb, - context); -#endif - g_free (context->winsys); -} - -static gboolean -_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, - GError **error) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; - CoglDisplay *display = context->display; - CoglDisplayEGL *egl_display = display->winsys; -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - CoglRendererEGL *egl_renderer = display->renderer->winsys; - CoglRendererXlib *xlib_renderer = display->renderer->winsys; - CoglOnscreenXlib *xlib_onscreen; - Window xwin; -#endif - CoglOnscreenEGL *egl_onscreen; - - g_return_val_if_fail (egl_display->egl_context, FALSE); - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - - /* FIXME: We need to explicitly Select for ConfigureNotify events. - * For foreign windows we need to be careful not to mess up any - * existing event mask. - * We need to document that for windows we create then toolkits - * must be careful not to clear event mask bits that we select. - */ - - /* XXX: Note we ignore the user's original width/height when - * given a foreign X window. */ - if (onscreen->foreign_xid) - { - Status status; - CoglXlibTrapState state; - XWindowAttributes attr; - int xerror; - - xwin = onscreen->foreign_xid; - - _cogl_renderer_xlib_trap_errors (display->renderer, &state); - - status = XGetWindowAttributes (xlib_renderer->xdpy, xwin, &attr); - xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); - if (status == 0 || xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to query geometry of foreign xid 0x%08lX: %s", - xwin, message); - return FALSE; - } - - _cogl_framebuffer_winsys_update_size (framebuffer, - attr.width, attr.height); - - /* Make sure the app selects for the events we require... */ - onscreen->foreign_update_mask_callback (onscreen, - COGL_ONSCREEN_X11_EVENT_MASK, - onscreen->foreign_update_mask_data); - } - else - { - int width; - int height; - CoglXlibTrapState state; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - _cogl_renderer_xlib_trap_errors (display->renderer, &state); - - xvisinfo = get_visual_info (display, egl_display->egl_config); - if (xvisinfo == NULL) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - return FALSE; - } - - /* window attributes */ - xattr.background_pixel = WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return FALSE; - } - } -#endif - - onscreen->winsys = g_slice_new0 (CoglOnscreenEGL); - egl_onscreen = onscreen->winsys; - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - xlib_onscreen = onscreen->winsys; - - xlib_onscreen->xwin = xwin; - xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? TRUE : FALSE; - - egl_onscreen->egl_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_display->egl_config, - (NativeWindowType) xlib_onscreen->xwin, - NULL); -#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) - if (egl_display->have_onscreen) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "EGL platform only supports a single onscreen window"); - return FALSE; - } - - egl_onscreen->egl_surface = egl_display->egl_surface; - - _cogl_framebuffer_winsys_update_size (framebuffer, - egl_display->egl_surface_width, - egl_display->egl_surface_height); - egl_display->have_onscreen = TRUE; -#else -#error "Unknown EGL platform" -#endif - - return TRUE; -} - -static void -_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglXlibTrapState old_state; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; -#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) - CoglDisplayEGL *egl_display = context->display->winsys; -#endif - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - CoglOnscreenEGL *egl_onscreen = onscreen->winsys; - - if (egl_onscreen->egl_surface != EGL_NO_SURFACE) - { - if (eglDestroySurface (egl_renderer->edpy, egl_onscreen->egl_surface) - == EGL_FALSE) - g_warning ("Failed to destroy EGL surface"); - egl_onscreen->egl_surface = EGL_NO_SURFACE; - } - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT - egl_display->have_onscreen = FALSE; -#endif - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - _cogl_xlib_trap_errors (&old_state); - - if (!xlib_onscreen->is_foreign_xwin && xlib_onscreen->xwin != None) - { - XDestroyWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); - xlib_onscreen->xwin = None; - } - else - xlib_onscreen->xwin = None; - - XSync (xlib_renderer->xdpy, False); - - if (_cogl_xlib_untrap_errors (&old_state) != Success) - g_warning ("X Error while destroying X window"); -#endif -} - -static void -_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglContextEGL *egl_context = context->winsys; - CoglDisplayEGL *egl_display = context->display->winsys; - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - CoglOnscreenEGL *egl_onscreen = onscreen->winsys; - - if (egl_context->current_surface == egl_onscreen->egl_surface) - return; - - if (G_UNLIKELY (!onscreen)) - { -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - eglMakeCurrent (egl_renderer->edpy, - egl_display->dummy_surface, - egl_display->dummy_surface, - egl_display->egl_context); - egl_context->current_surface = egl_display->dummy_surface; -#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) - return; -#else -#error "Unknown EGL platform" -#endif - } - else - { - eglMakeCurrent (egl_renderer->edpy, - egl_onscreen->egl_surface, - egl_onscreen->egl_surface, - egl_display->egl_context); - egl_context->current_surface = egl_onscreen->egl_surface; - } - - if (onscreen->swap_throttled) - eglSwapInterval (egl_renderer->edpy, 1); - else - eglSwapInterval (egl_renderer->edpy, 0); -} - -static void -_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, - int *rectangles, - int n_rectangles) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - CoglOnscreenEGL *egl_onscreen = onscreen->winsys; - - if (egl_renderer->pf_eglSwapBuffersRegion (egl_renderer->edpy, - egl_onscreen->egl_surface, - n_rectangles, - rectangles) == EGL_FALSE) - g_warning ("Error reported by eglSwapBuffersRegion"); -} - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT -static void -_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen, - gboolean visibility) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - - if (visibility) - XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); - else - XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); -} -#endif - -static guint32 -_cogl_winsys_get_vsync_counter (void) -{ - /* Unsupported feature */ - return 0; -} - -static void -_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - CoglOnscreenEGL *egl_onscreen = onscreen->winsys; - - eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface); -} - -static guint32 -_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) -{ - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - return xlib_onscreen->xwin; -} - -static unsigned int -_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data) -{ - /* Unsupported feature */ - return 0; -} - -static void -_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, - unsigned int id) -{ - /* Unsupported feature */ -} - -static void -_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglContextEGL *egl_context = context->winsys; - CoglOnscreenEGL *egl_onscreen = onscreen->winsys; - - if (egl_context->current_surface != egl_onscreen->egl_surface) - return; - - egl_context->current_surface = EGL_NO_SURFACE; - _cogl_winsys_onscreen_bind (onscreen); -} - -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT -/* XXX: This is a particularly hacky _cogl_winsys interface... */ -static XVisualInfo * -_cogl_winsys_xlib_get_visual_info (void) -{ - CoglDisplayEGL *egl_display; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (ctx->display->winsys, FALSE); - - egl_display = ctx->display->winsys; - - if (!egl_display->found_egl_config) - return NULL; - - return get_visual_info (ctx->display, egl_display->egl_config); -} -#endif - -static EGLDisplay -_cogl_winsys_context_egl_get_egl_display (CoglContext *context) -{ - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - - return egl_renderer->edpy; -} - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .name = "EGL", - .get_proc_address = _cogl_winsys_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_winsys_renderer_disconnect, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - .context_egl_get_egl_display = - _cogl_winsys_context_egl_get_egl_display, -#ifdef COGL_HAS_XLIB_SUPPORT - .xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info, -#endif - .onscreen_init = _cogl_winsys_onscreen_init, - .onscreen_deinit = _cogl_winsys_onscreen_deinit, - .onscreen_bind = _cogl_winsys_onscreen_bind, - .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers, - .onscreen_swap_region = _cogl_winsys_onscreen_swap_region, -#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT - .onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility, -#endif - .onscreen_update_swap_throttled = - _cogl_winsys_onscreen_update_swap_throttled, - .onscreen_x11_get_window_xid = - _cogl_winsys_onscreen_x11_get_window_xid, - .onscreen_add_swap_buffers_callback = - _cogl_winsys_onscreen_add_swap_buffers_callback, - .onscreen_remove_swap_buffers_callback = - _cogl_winsys_onscreen_remove_swap_buffers_callback, - .get_vsync_counter = _cogl_winsys_get_vsync_counter - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -const CoglWinsysVtable * -_cogl_winsys_egl_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h b/clutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h deleted file mode 100644 index 50df562..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names, - * implied_public_feature_flags, - * implied_private_feature_flags, - * implied_winsys_feature) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics accross - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -COGL_WINSYS_FEATURE_BEGIN (texture_from_pixmap, - "EXT\0", - "texture_from_pixmap\0", - 0, - 0, - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) -COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage, - (Display *display, - GLXDrawable drawable, - int buffer, - int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage, - (Display *display, - GLXDrawable drawable, - int buffer)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (video_sync, - "SGI\0", - "video_sync\0", - 0, - 0, - COGL_WINSYS_FEATURE_VBLANK_COUNTER) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync, - (unsigned int *count)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXWaitVideoSync, - (int divisor, - int remainder, - unsigned int *count)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (swap_control, - "SGI\0", - "swap_control\0", - 0, - 0, - COGL_WINSYS_FEATURE_SWAP_THROTTLE) -COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval, - (int interval)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (copy_sub_buffer, - "MESA\0", - "copy_sub_buffer\0", - 0, - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer, - (Display *dpy, - GLXDrawable drawable, - int x, int y, int width, int height)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (swap_event, - "INTEL\0", - "swap_event\0", - 0, - 0, - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT) -COGL_WINSYS_FEATURE_END () diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-glx.c b/clutter/cogl/cogl/winsys/cogl-winsys-glx.c deleted file mode 100644 index 5948dde..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys-glx.c +++ /dev/null @@ -1,1959 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" - -#include "cogl-winsys-private.h" -#include "cogl-feature-private.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer.h" -#include "cogl-swap-chain-private.h" -#include "cogl-renderer-private.h" -#include "cogl-renderer-glx-private.h" -#include "cogl-onscreen-template-private.h" -#include "cogl-display-xlib-private.h" -#include "cogl-display-glx-private.h" -#include "cogl-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-rectangle-private.h" -#include "cogl-pipeline-opengl-private.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include - -typedef CoglFuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName); - -#ifdef HAVE_DRM -#include -#include -#include -#endif - -#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask - -typedef struct _CoglContextGLX -{ - GLXDrawable current_drawable; -} CoglContextGLX; - -typedef struct _CoglOnscreenXlib -{ - Window xwin; - gboolean is_foreign_xwin; -} CoglOnscreenXlib; - -typedef struct _CoglOnscreenGLX -{ - CoglOnscreenXlib _parent; - GLXDrawable glxwin; - guint32 last_swap_vsync_counter; - GList *swap_callbacks; -} CoglOnscreenGLX; - -typedef struct _CoglSwapBuffersNotifyEntry -{ - CoglSwapBuffersNotify callback; - void *user_data; - unsigned int id; -} CoglSwapBuffersNotifyEntry; - -typedef struct _CoglTexturePixmapGLX -{ - GLXPixmap glx_pixmap; - gboolean has_mipmap_space; - gboolean can_mipmap; - - CoglHandle glx_tex; - - gboolean bind_tex_image_queued; - gboolean pixmap_bound; -} CoglTexturePixmapGLX; - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - feature_flags, feature_flags_private, \ - winsys_feature) \ - static const CoglFeatureFunction \ - cogl_glx_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglRendererGLX, pf_ ## name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "cogl-winsys-glx-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - feature_flags, feature_flags_private, \ - winsys_feature) \ - { 255, 255, namespaces, extension_names, \ - feature_flags, feature_flags_private, \ - winsys_feature, \ - cogl_glx_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "cogl-winsys-glx-feature-functions.h" - }; - -CoglFuncPtr -_cogl_winsys_get_proc_address (const char *name) -{ - static GLXGetProcAddressProc get_proc_func = NULL; - static void *dlhand = NULL; - - if (get_proc_func == NULL && dlhand == NULL) - { - dlhand = dlopen (NULL, RTLD_LAZY); - - if (!dlhand) - { - g_warning ("Failed to dlopen (NULL, RTDL_LAZY): %s", dlerror ()); - return NULL; - } - - dlerror (); - - get_proc_func = - (GLXGetProcAddressProc) dlsym (dlhand, "glXGetProcAddress"); - - if (dlerror () != NULL) - { - get_proc_func = - (GLXGetProcAddressProc) dlsym (dlhand, "glXGetProcAddressARB"); - } - - if (dlerror () != NULL) - { - get_proc_func = NULL; - g_warning ("failed to bind GLXGetProcAddress " - "or GLXGetProcAddressARB"); - } - } - - if (get_proc_func) - return get_proc_func ((GLubyte *) name); - - return NULL; -} - -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f) -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - glx_renderer->pf_ ## name = NULL; -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static void -initialize_function_table (CoglRenderer *renderer) -{ - CoglRendererGLX *glx_renderer = renderer->winsys; - -#include "cogl-winsys-glx-feature-functions.h" -} - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, guint32 xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreenXlib *xlib_onscreen; - - if (framebuffer->type != COGL_FRAMEBUFFER_TYPE_ONSCREEN) - continue; - - /* Does the GLXEvent have the GLXDrawable or the X Window? */ - xlib_onscreen = COGL_ONSCREEN (framebuffer)->winsys; - if (xlib_onscreen->xwin == (Window)xid) - return COGL_ONSCREEN (framebuffer); - } - - return NULL; -} - -static void -notify_swap_buffers (CoglContext *context, GLXDrawable drawable) -{ - CoglOnscreen *onscreen = find_onscreen_for_xid (context, (guint32)drawable); - CoglOnscreenGLX *glx_onscreen; - GList *l; - - if (!onscreen) - return; - - glx_onscreen = onscreen->winsys; - - for (l = glx_onscreen->swap_callbacks; l; l = l->next) - { - CoglSwapBuffersNotifyEntry *entry = l->data; - entry->callback (COGL_FRAMEBUFFER (onscreen), entry->user_data); - } -} - -static CoglFilterReturn -glx_event_filter_cb (void *native_event, void *data) -{ - XEvent *xevent = native_event; - CoglContext *context = data; -#ifdef GLX_INTEL_swap_event - CoglRendererGLX *glx_renderer; -#endif - - if (xevent->type == ConfigureNotify) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xconfigure.window); - - if (onscreen) - { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - _cogl_framebuffer_winsys_update_size (framebuffer, - xevent->xconfigure.width, - xevent->xconfigure.height); - } - - /* we let ConfigureNotify pass through */ - return COGL_FILTER_CONTINUE; - } - -#ifdef GLX_INTEL_swap_event - glx_renderer = context->display->renderer->winsys; - - if (xevent->type == (glx_renderer->glx_event_base + GLX_BufferSwapComplete)) - { - GLXBufferSwapComplete *swap_event = (GLXBufferSwapComplete *) xevent; - - notify_swap_buffers (context, swap_event->drawable); - - /* remove SwapComplete events from the queue */ - return COGL_FILTER_REMOVE; - } -#endif /* GLX_INTEL_swap_event */ - - return COGL_FILTER_CONTINUE; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - _cogl_renderer_xlib_disconnect (renderer); - - g_slice_free (CoglRendererGLX, renderer->winsys); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglRendererGLX *glx_renderer; - CoglRendererXlib *xlib_renderer; - - renderer->winsys = g_slice_new0 (CoglRendererGLX); - - glx_renderer = renderer->winsys; - xlib_renderer = renderer->winsys; - - if (!_cogl_renderer_xlib_connect (renderer, error)) - goto error; - - if (!glXQueryExtension (xlib_renderer->xdpy, - &glx_renderer->glx_error_base, - &glx_renderer->glx_event_base)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX support"); - goto error; - } - - /* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting - * extensions specified to require GLX 1.3, but still reporting 1.2 - * via glXQueryVersion. */ - if (!glXQueryVersion (xlib_renderer->xdpy, - &glx_renderer->glx_major, - &glx_renderer->glx_minor) - || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX 1.2 support"); - goto error; - } - - glx_renderer->dri_fd = -1; - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static void -update_winsys_features (CoglContext *context) -{ - CoglDisplayGLX *glx_display = context->display->winsys; - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglRendererGLX *glx_renderer = context->display->renderer->winsys; - const char *glx_extensions; - int i; - - g_return_if_fail (glx_display->glx_context); - - _cogl_gl_update_features (context); - - memset (context->winsys_features, 0, sizeof (context->winsys_features)); - - glx_extensions = - glXQueryExtensionsString (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - - COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions); - - context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE; - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, - TRUE); - - initialize_function_table (context->display->renderer); - - for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) - if (_cogl_feature_check ("GLX", winsys_feature_data + i, 0, 0, - glx_extensions, - glx_renderer)) - { - context->feature_flags |= winsys_feature_data[i].feature_flags; - if (winsys_feature_data[i].winsys_feature) - COGL_FLAGS_SET (context->winsys_features, - winsys_feature_data[i].winsys_feature, - TRUE); - } - - /* Note: the GLX_SGI_video_sync spec explicitly states this extension - * only works for direct contexts. */ - if (!glx_renderer->is_direct) - { - glx_renderer->pf_glXGetVideoSync = NULL; - glx_renderer->pf_glXWaitVideoSync = NULL; - } - - if (glx_renderer->pf_glXWaitVideoSync) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_VBLANK_WAIT, - TRUE); - -#ifdef HAVE_DRM - /* drm is really an extreme fallback -rumoured to work with Via - * chipsets... */ - if (!glx_renderer->pf_glXWaitVideoSync) - { - if (glx_renderer->dri_fd < 0) - glx_renderer->dri_fd = open("/dev/dri/card0", O_RDWR); - if (glx_renderer->dri_fd >= 0) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_VBLANK_WAIT, - TRUE); - } -#endif - - if (glx_renderer->pf_glXCopySubBuffer || context->drv.pf_glBlitFramebuffer) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - - /* Note: glXCopySubBuffer and glBlitFramebuffer won't be throttled - * by the SwapInterval so we have to throttle swap_region requests - * manually... */ - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) && - _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT)) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); -} - -/* It seems the GLX spec never defined an invalid GLXFBConfig that - * we could overload as an indication of error, so we have to return - * an explicit boolean status. */ -static gboolean -find_fbconfig (CoglDisplay *display, - gboolean with_alpha, - GLXFBConfig *config_ret, - GError **error) -{ - CoglRendererXlib *xlib_renderer = display->renderer->winsys; - GLXFBConfig *configs = NULL; - int n_configs, i; - static const int attributes[] = { - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DOUBLEBUFFER, GL_TRUE, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_ALPHA_SIZE, 1, - GLX_DEPTH_SIZE, 1, - GLX_STENCIL_SIZE, 1, - None - }; - gboolean ret = TRUE; - int xscreen_num = DefaultScreen (xlib_renderer->xdpy); - - configs = glXChooseFBConfig (xlib_renderer->xdpy, - xscreen_num, - attributes, - &n_configs); - if (!configs || n_configs == 0) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to find any compatible fbconfigs"); - ret = FALSE; - goto done; - } - - if (with_alpha) - { - for (i = 0; i < n_configs; i++) - { - XVisualInfo *vinfo; - - vinfo = glXGetVisualFromFBConfig (xlib_renderer->xdpy, configs[i]); - if (vinfo == NULL) - continue; - - if (vinfo->depth == 32 && - (vinfo->red_mask | vinfo->green_mask | vinfo->blue_mask) - != 0xffffffff) - { - COGL_NOTE (WINSYS, "Found an ARGB FBConfig [index:%d]", i); - *config_ret = configs[i]; - goto done; - } - } - - /* If we make it here then we didn't find an RGBA config so - we'll fall back to using an RGB config */ - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find fbconfig with rgba visual"); - ret = FALSE; - goto done; - } - else - { - COGL_NOTE (WINSYS, "Using the first available FBConfig"); - *config_ret = configs[0]; - } - -done: - XFree (configs); - return ret; -} - -static gboolean -create_context (CoglDisplay *display, GError **error) -{ - CoglDisplayGLX *glx_display = display->winsys; - CoglDisplayXlib *xlib_display = display->winsys; - CoglRendererXlib *xlib_renderer = display->renderer->winsys; - CoglRendererGLX *glx_renderer = display->renderer->winsys; - gboolean support_transparent_windows; - GLXFBConfig config; - GError *fbconfig_error = NULL; - XSetWindowAttributes attrs; - XVisualInfo *xvisinfo; - GLXDrawable dummy_drawable; - CoglXlibTrapState old_state; - - g_return_val_if_fail (glx_display->glx_context == NULL, TRUE); - - if (display->onscreen_template && - display->onscreen_template->swap_chain && - display->onscreen_template->swap_chain->has_alpha) - support_transparent_windows = TRUE; - else - support_transparent_windows = FALSE; - - glx_display->found_fbconfig = - find_fbconfig (display, support_transparent_windows, &config, - &fbconfig_error); - if (!glx_display->found_fbconfig) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - glx_display->fbconfig = config; - glx_display->fbconfig_has_rgba_visual = support_transparent_windows; - - COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", - xlib_renderer->xdpy); - - glx_display->glx_context = glXCreateNewContext (xlib_renderer->xdpy, - config, - GLX_RGBA_TYPE, - NULL, - True); - if (glx_display->glx_context == NULL) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create suitable GL context"); - return FALSE; - } - - glx_renderer->is_direct = - glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context); - - COGL_NOTE (WINSYS, "Setting %s context", - glx_renderer->is_direct ? "direct" : "indirect"); - - /* XXX: GLX doesn't let us make a context current without a window - * so we create a dummy window that we can use while no CoglOnscreen - * framebuffer is in use. - */ - - xvisinfo = glXGetVisualFromFBConfig (xlib_renderer->xdpy, config); - if (xvisinfo == NULL) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to retrieve the X11 visual"); - return FALSE; - } - - _cogl_renderer_xlib_trap_errors (display->renderer, &old_state); - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - xlib_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | CWColormap | CWBorderPixel, - &attrs); - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - glx_display->dummy_glxwin = glXCreateWindow (xlib_renderer->xdpy, - config, - xlib_display->dummy_xwin, - NULL); - } - - if (glx_display->dummy_glxwin) - dummy_drawable = glx_display->dummy_glxwin; - else - dummy_drawable = xlib_display->dummy_xwin; - - COGL_NOTE (WINSYS, "Selecting dummy 0x%x for the GLX context", - (unsigned int) dummy_drawable); - - glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - - XFree (xvisinfo); - - if (_cogl_renderer_xlib_untrap_errors (display->renderer, &old_state)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to select the newly created GLX context"); - return FALSE; - } - - return TRUE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglDisplayGLX *glx_display = display->winsys; - CoglDisplayXlib *xlib_display = display->winsys; - CoglRendererXlib *xlib_renderer = display->renderer->winsys; - - g_return_if_fail (glx_display != NULL); - - if (glx_display->glx_context) - { - glXMakeContextCurrent (xlib_renderer->xdpy, None, None, NULL); - glXDestroyContext (xlib_renderer->xdpy, glx_display->glx_context); - glx_display->glx_context = NULL; - } - - if (glx_display->dummy_glxwin) - { - glXDestroyWindow (xlib_renderer->xdpy, glx_display->dummy_glxwin); - glx_display->dummy_glxwin = None; - } - - if (xlib_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, xlib_display->dummy_xwin); - xlib_display->dummy_xwin = None; - } - - g_slice_free (CoglDisplayGLX, display->winsys); - display->winsys = NULL; -} - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayGLX *glx_display; - int i; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - glx_display = g_slice_new0 (CoglDisplayGLX); - display->winsys = glx_display; - - if (!create_context (display, error)) - goto error; - - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - glx_display->glx_cached_configs[i].depth = -1; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -static gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error) -{ - context->winsys = g_new0 (CoglContextGLX, 1); - - cogl_renderer_add_native_filter (context->display->renderer, - glx_event_filter_cb, - context); - update_winsys_features (context); - - return TRUE; -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - cogl_renderer_remove_native_filter (context->display->renderer, - glx_event_filter_cb, - context); - g_free (context->winsys); -} - -static gboolean -_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, - GError **error) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; - CoglDisplay *display = context->display; - CoglDisplayGLX *glx_display = display->winsys; - CoglRendererXlib *xlib_renderer = display->renderer->winsys; - CoglRendererGLX *glx_renderer = display->renderer->winsys; - Window xwin; - CoglOnscreenXlib *xlib_onscreen; - CoglOnscreenGLX *glx_onscreen; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - /* FIXME: We need to explicitly Select for ConfigureNotify events. - * For foreign windows we need to be careful not to mess up any - * existing event mask. - * We need to document that for windows we create then toolkits - * must be careful not to clear event mask bits that we select. - */ - - /* XXX: Note we ignore the user's original width/height when - * given a foreign X window. */ - if (onscreen->foreign_xid) - { - Status status; - CoglXlibTrapState state; - XWindowAttributes attr; - int xerror; - - xwin = onscreen->foreign_xid; - - _cogl_renderer_xlib_trap_errors (display->renderer, &state); - - status = XGetWindowAttributes (xlib_renderer->xdpy, xwin, &attr); - XSync (xlib_renderer->xdpy, False); - xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); - if (status == 0 || xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, message, sizeof(message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to query geometry of foreign xid 0x%08lX: %s", - xwin, message); - return FALSE; - } - - _cogl_framebuffer_winsys_update_size (framebuffer, - attr.width, attr.height); - - /* Make sure the app selects for the events we require... */ - onscreen->foreign_update_mask_callback (onscreen, - COGL_ONSCREEN_X11_EVENT_MASK, - onscreen->foreign_update_mask_data); - } - else - { - int width; - int height; - CoglXlibTrapState state; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - _cogl_renderer_xlib_trap_errors (display->renderer, &state); - - xvisinfo = glXGetVisualFromFBConfig (xlib_renderer->xdpy, - glx_display->fbconfig); - if (xvisinfo == NULL) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - return FALSE; - } - - /* window attributes */ - xattr.background_pixel = WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = _cogl_renderer_xlib_untrap_errors (display->renderer, &state); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return FALSE; - } - } - - onscreen->winsys = g_slice_new0 (CoglOnscreenGLX); - xlib_onscreen = onscreen->winsys; - glx_onscreen = onscreen->winsys; - - xlib_onscreen->xwin = xwin; - xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? TRUE : FALSE; - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - glx_onscreen->glxwin = - glXCreateWindow (xlib_renderer->xdpy, - glx_display->fbconfig, - xlib_onscreen->xwin, - NULL); - } - -#ifdef GLX_INTEL_swap_event - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT)) - { - GLXDrawable drawable = - glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - - /* similarly to above, we unconditionally select this event - * because we rely on it to advance the master clock, and - * drive redraw/relayout, animations and event handling. - */ - glXSelectEvent (xlib_renderer->xdpy, - drawable, - GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); - } -#endif /* GLX_INTEL_swap_event */ - - return TRUE; -} - -static void -_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglXlibTrapState old_state; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - - _cogl_xlib_trap_errors (&old_state); - - if (glx_onscreen->glxwin != None) - { - glXDestroyWindow (xlib_renderer->xdpy, glx_onscreen->glxwin); - glx_onscreen->glxwin = None; - } - - if (!xlib_onscreen->is_foreign_xwin && xlib_onscreen->xwin != None) - { - XDestroyWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); - xlib_onscreen->xwin = None; - } - else - xlib_onscreen->xwin = None; - - XSync (xlib_renderer->xdpy, False); - - _cogl_xlib_untrap_errors (&old_state); -} - -static void -_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglContextGLX *glx_context = context->winsys; - CoglDisplayXlib *xlib_display = context->display->winsys; - CoglDisplayGLX *glx_display = context->display->winsys; - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglRendererGLX *glx_renderer = context->display->renderer->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - CoglXlibTrapState old_state; - GLXDrawable drawable; - - if (G_UNLIKELY (!onscreen)) - { - drawable = - glx_display->dummy_glxwin ? - glx_display->dummy_glxwin : xlib_display->dummy_xwin; - - if (glx_context->current_drawable == drawable) - return; - - _cogl_xlib_trap_errors (&old_state); - - glXMakeContextCurrent (xlib_renderer->xdpy, - drawable, drawable, - glx_display->glx_context); - } - else - { - drawable = - glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - - if (glx_context->current_drawable == drawable) - return; - - _cogl_xlib_trap_errors (&old_state); - - COGL_NOTE (WINSYS, - "MakeContextCurrent dpy: %p, window: 0x%x (%s), context: %p", - xlib_renderer->xdpy, - (unsigned int) drawable, - xlib_onscreen->is_foreign_xwin ? "foreign" : "native", - glx_display->glx_context); - - glXMakeContextCurrent (xlib_renderer->xdpy, - drawable, - drawable, - glx_display->glx_context); - - /* In case we are using GLX_SGI_swap_control for vblank syncing - * we need call glXSwapIntervalSGI here to make sure that it - * affects the current drawable. - * - * Note: we explicitly set to 0 when we aren't using the swap - * interval to synchronize since some drivers have a default - * swap interval of 1. Sadly some drivers even ignore requests - * to disable the swap interval. - * - * NB: glXSwapIntervalSGI applies to the context not the - * drawable which is why we can't just do this once when the - * framebuffer is allocated. - * - * FIXME: We should check for GLX_EXT_swap_control which allows - * per framebuffer swap intervals. GLX_MESA_swap_control also - * allows per-framebuffer swap intervals but the semantics tend - * to be more muddled since Mesa drivers tend to expose both the - * MESA and SGI extensions which should technically be mutually - * exclusive. - */ - if (glx_renderer->pf_glXSwapInterval) - { - if (onscreen->swap_throttled) - glx_renderer->pf_glXSwapInterval (1); - else - glx_renderer->pf_glXSwapInterval (0); - } - } - - XSync (xlib_renderer->xdpy, False); - - /* FIXME: We should be reporting a GError here - */ - if (_cogl_xlib_untrap_errors (&old_state)) - { - g_warning ("X Error received while making drawable 0x%08lX current", - drawable); - return; - } - - glx_context->current_drawable = drawable; -} - -#ifdef HAVE_DRM -static int -drm_wait_vblank (int fd, drm_wait_vblank_t *vbl) -{ - int ret, rc; - - do - { - ret = ioctl (fd, DRM_IOCTL_WAIT_VBLANK, vbl); - vbl->request.type &= ~_DRM_VBLANK_RELATIVE; - rc = errno; - } - while (ret && rc == EINTR); - - return rc; -} -#endif /* HAVE_DRM */ - -static void -_cogl_winsys_wait_for_vblank (void) -{ - CoglRendererGLX *glx_renderer; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - glx_renderer = ctx->display->renderer->winsys; - - if (glx_renderer->pf_glXGetVideoSync) - { - guint32 current_count; - - glx_renderer->pf_glXGetVideoSync (¤t_count); - glx_renderer->pf_glXWaitVideoSync (2, - (current_count + 1) % 2, - ¤t_count); - } -#ifdef HAVE_DRM - else - { - drm_wait_vblank_t blank; - - COGL_NOTE (WINSYS, "Waiting for vblank (drm)"); - blank.request.type = _DRM_VBLANK_RELATIVE; - blank.request.sequence = 1; - blank.request.signal = 0; - drm_wait_vblank (glx_renderer->dri_fd, &blank); - } -#endif /* HAVE_DRM */ -} - -static guint32 -_cogl_winsys_get_vsync_counter (void) -{ - guint32 video_sync_count; - CoglRendererGLX *glx_renderer; - - _COGL_GET_CONTEXT (ctx, 0); - - glx_renderer = ctx->display->renderer->winsys; - - glx_renderer->pf_glXGetVideoSync (&video_sync_count); - - return video_sync_count; -} - -static void -_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, - int *rectangles, - int n_rectangles) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglRendererGLX *glx_renderer = context->display->renderer->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - GLXDrawable drawable = - glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - guint32 end_frame_vsync_counter = 0; - gboolean have_counter; - gboolean can_wait; - - _cogl_framebuffer_flush_state (framebuffer, - framebuffer, - COGL_FRAMEBUFFER_FLUSH_BIND_ONLY); - - if (onscreen->swap_throttled) - { - have_counter = - _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER); - can_wait = _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT); - } - else - { - have_counter = FALSE; - can_wait = FALSE; - } - - /* We need to ensure that all the rendering is done, otherwise - * redraw operations that are slower than the framerate can - * queue up in the pipeline during a heavy animation, causing a - * larger and larger backlog of rendering visible as lag to the - * user. - * - * For an exaggerated example consider rendering at 60fps (so 16ms - * per frame) and you have a really slow frame that takes 160ms to - * render, even though painting the scene and issuing the commands - * to the GPU takes no time at all. If all we did was use the - * video_sync extension to throttle the painting done by the CPU - * then every 16ms we would have another frame queued up even though - * the GPU has only rendered one tenth of the current frame. By the - * time the GPU would get to the 2nd frame there would be 9 frames - * waiting to be rendered. - * - * The problem is that we don't currently have a good way to throttle - * the GPU, only the CPU so we have to resort to synchronizing the - * GPU with the CPU to throttle it. - * - * Note: since calling glFinish() and synchronizing the CPU with - * the GPU is far from ideal, we hope that this is only a short - * term solution. - * - One idea is to using sync objects to track render - * completion so we can throttle the backlog (ideally with an - * additional extension that lets us get notifications in our - * mainloop instead of having to busy wait for the - * completion.) - * - Another option is to support clipped redraws by reusing the - * contents of old back buffers such that we can flip instead - * of using a blit and then we can use GLX_INTEL_swap_events - * to throttle. For this though we would still probably want an - * additional extension so we can report the limited region of - * the window damage to X/compositors. - */ - glFinish (); - - if (have_counter && can_wait) - { - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (); - - /* If we have the GLX_SGI_video_sync extension then we can - * be a bit smarter about how we throttle blits by avoiding - * any waits if we can see that the video sync count has - * already progressed. */ - if (glx_onscreen->last_swap_vsync_counter == end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (); - - if (glx_renderer->pf_glXCopySubBuffer) - { - Display *xdpy = xlib_renderer->xdpy; - int i; - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - glx_renderer->pf_glXCopySubBuffer (xdpy, drawable, - rect[0], rect[1], rect[2], rect[3]); - } - } - else if (context->drv.pf_glBlitFramebuffer) - { - int i; - /* XXX: checkout how this state interacts with the code to use - * glBlitFramebuffer in Neil's texture atlasing branch */ - glDrawBuffer (GL_FRONT); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - int x2 = rect[0] + rect[2]; - int y2 = rect[1] + rect[3]; - context->drv.pf_glBlitFramebuffer (rect[0], rect[1], x2, y2, - rect[0], rect[1], x2, y2, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - glDrawBuffer (GL_BACK); - } - - /* NB: unlike glXSwapBuffers, glXCopySubBuffer and - * glBlitFramebuffer don't issue an implicit glFlush() so we - * have to flush ourselves if we want the request to complete in - * a finite amount of time since otherwise the driver can batch - * the command indefinitely. */ - glFlush (); - - /* NB: It's important we save the counter we read before acting on - * the swap request since if we are mixing and matching different - * swap methods between frames we don't want to read the timer e.g. - * after calling glFinish() some times and not for others. - * - * In other words; this way we consistently save the time at the end - * of the applications frame such that the counter isn't muddled by - * the varying costs of different swap methods. - */ - if (have_counter) - glx_onscreen->last_swap_vsync_counter = end_frame_vsync_counter; -} - -static void -_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglRendererGLX *glx_renderer = context->display->renderer->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - gboolean have_counter; - GLXDrawable drawable; - - /* XXX: theoretically this shouldn't be necessary but at least with - * the Intel drivers we have see that if we don't call - * glXMakeContextCurrent for the drawable we are swapping then - * we get a BadDrawable error from the X server. */ - _cogl_framebuffer_flush_state (framebuffer, - framebuffer, - COGL_FRAMEBUFFER_FLUSH_BIND_ONLY); - - drawable = glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - - if (onscreen->swap_throttled) - { - guint32 end_frame_vsync_counter = 0; - - have_counter = - _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER); - - /* If the swap_region API is also being used then we need to track - * the vsync counter for each swap request so we can manually - * throttle swap_region requests. */ - if (have_counter) - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (); - - if (!glx_renderer->pf_glXSwapInterval) - { - gboolean can_wait = - _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT); - - /* If we are going to wait for VBLANK manually, we not only - * need to flush out pending drawing to the GPU before we - * sleep, we need to wait for it to finish. Otherwise, we - * may end up with the situation: - * - * - We finish drawing - GPU drawing continues - * - We go to sleep - GPU drawing continues - * VBLANK - We call glXSwapBuffers - GPU drawing continues - * - GPU drawing continues - * - Swap buffers happens - * - * Producing a tear. Calling glFinish() first will cause us - * to properly wait for the next VBLANK before we swap. This - * obviously does not happen when we use _GLX_SWAP and let - * the driver do the right thing - */ - glFinish (); - - if (have_counter && can_wait) - { - if (glx_onscreen->last_swap_vsync_counter == - end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (); - } - } - else - have_counter = FALSE; - - glXSwapBuffers (xlib_renderer->xdpy, drawable); - - if (have_counter) - glx_onscreen->last_swap_vsync_counter = _cogl_winsys_get_vsync_counter (); -} - -static guint32 -_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) -{ - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - return xlib_onscreen->xwin; -} - -static unsigned int -_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data) -{ - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - CoglSwapBuffersNotifyEntry *entry = g_slice_new0 (CoglSwapBuffersNotifyEntry); - static int next_swap_buffers_callback_id = 0; - - entry->callback = callback; - entry->user_data = user_data; - entry->id = next_swap_buffers_callback_id++; - - glx_onscreen->swap_callbacks = - g_list_prepend (glx_onscreen->swap_callbacks, entry); - - return entry->id; -} - -static void -_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, - unsigned int id) -{ - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - GList *l; - - for (l = glx_onscreen->swap_callbacks; l; l = l->next) - { - CoglSwapBuffersNotifyEntry *entry = l->data; - if (entry->id == id) - { - g_slice_free (CoglSwapBuffersNotifyEntry, entry); - glx_onscreen->swap_callbacks = - g_list_delete_link (glx_onscreen->swap_callbacks, l); - return; - } - } -} - -static void -_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglContextGLX *glx_context = context->winsys; - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - GLXDrawable drawable = - glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - - if (glx_context->current_drawable != drawable) - return; - - glx_context->current_drawable = 0; - _cogl_winsys_onscreen_bind (onscreen); -} - -static void -_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen, - gboolean visibility) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglRendererXlib *xlib_renderer = context->display->renderer->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - - if (visibility) - XMapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); - else - XUnmapWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); -} - -/* XXX: This is a particularly hacky _cogl_winsys interface... */ -static XVisualInfo * -_cogl_winsys_xlib_get_visual_info (void) -{ - CoglDisplayGLX *glx_display; - CoglRendererXlib *xlib_renderer; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (ctx->display->winsys, FALSE); - - glx_display = ctx->display->winsys; - xlib_renderer = ctx->display->renderer->winsys; - - if (!glx_display->found_fbconfig) - return NULL; - - return glXGetVisualFromFBConfig (xlib_renderer->xdpy, glx_display->fbconfig); -} - -static gboolean -get_fbconfig_for_depth (CoglContext *context, - unsigned int depth, - GLXFBConfig *fbconfig_ret, - gboolean *can_mipmap_ret) -{ - CoglRendererXlib *xlib_renderer; - CoglDisplayGLX *glx_display; - Display *dpy; - GLXFBConfig *fbconfigs; - int n_elements, i; - int db, stencil, alpha, mipmap, rgba, value; - int spare_cache_slot = 0; - gboolean found = FALSE; - - xlib_renderer = context->display->renderer->winsys; - glx_display = context->display->winsys; - - /* Check if we've already got a cached config for this depth */ - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - if (glx_display->glx_cached_configs[i].depth == -1) - spare_cache_slot = i; - else if (glx_display->glx_cached_configs[i].depth == depth) - { - *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config; - *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap; - return glx_display->glx_cached_configs[i].found; - } - - dpy = xlib_renderer->xdpy; - - fbconfigs = glXGetFBConfigs (dpy, DefaultScreen (dpy), &n_elements); - - db = G_MAXSHORT; - stencil = G_MAXSHORT; - mipmap = 0; - rgba = 0; - - for (i = 0; i < n_elements; i++) - { - XVisualInfo *vi; - int visual_depth; - - vi = glXGetVisualFromFBConfig (dpy, fbconfigs[i]); - if (vi == NULL) - continue; - - visual_depth = vi->depth; - - XFree (vi); - - if (visual_depth != depth) - continue; - - glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_ALPHA_SIZE, - &alpha); - glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BUFFER_SIZE, - &value); - if (value != depth && (value - alpha) != depth) - continue; - - value = 0; - if (depth == 32) - { - glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGBA_EXT, - &value); - if (value) - rgba = 1; - } - - if (!value) - { - if (rgba) - continue; - - glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGB_EXT, - &value); - if (!value) - continue; - } - - glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_DOUBLEBUFFER, - &value); - if (value > db) - continue; - - db = value; - - glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STENCIL_SIZE, - &value); - if (value > stencil) - continue; - - stencil = value; - - /* glGenerateMipmap is defined in the offscreen extension */ - if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) - { - glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_MIPMAP_TEXTURE_EXT, - &value); - - if (value < mipmap) - continue; - - mipmap = value; - } - - *fbconfig_ret = fbconfigs[i]; - *can_mipmap_ret = mipmap; - found = TRUE; - } - - if (n_elements) - XFree (fbconfigs); - - glx_display->glx_cached_configs[spare_cache_slot].depth = depth; - glx_display->glx_cached_configs[spare_cache_slot].found = found; - glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret; - glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap; - - return found; -} - -static gboolean -should_use_rectangle (CoglContext *context) -{ - - if (context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN) - { - if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE)) - { - const char *rect_env; - - /* Use the rectangle only if it is available and either: - - the COGL_PIXMAP_TEXTURE_RECTANGLE environment variable is - set to 'force' - - *or* - - the env var is set to 'allow' or not set and NPOTs textures - are not available */ - - context->rectangle_state = - cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) ? - COGL_WINSYS_RECTANGLE_STATE_DISABLE : - COGL_WINSYS_RECTANGLE_STATE_ENABLE; - - if ((rect_env = g_getenv ("COGL_PIXMAP_TEXTURE_RECTANGLE")) || - /* For compatibility, we'll also look at the old Clutter - environment variable */ - (rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE"))) - { - if (g_ascii_strcasecmp (rect_env, "force") == 0) - context->rectangle_state = - COGL_WINSYS_RECTANGLE_STATE_ENABLE; - else if (g_ascii_strcasecmp (rect_env, "disable") == 0) - context->rectangle_state = - COGL_WINSYS_RECTANGLE_STATE_DISABLE; - else if (g_ascii_strcasecmp (rect_env, "allow")) - g_warning ("Unknown value for COGL_PIXMAP_TEXTURE_RECTANGLE, " - "should be 'force' or 'disable'"); - } - } - else - context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_DISABLE; - } - - return context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_ENABLE; -} - -static gboolean -try_create_glx_pixmap (CoglContext *context, - CoglTexturePixmapX11 *tex_pixmap, - gboolean mipmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglRenderer *renderer; - CoglRendererXlib *xlib_renderer; - Display *dpy; - /* We have to initialize this *opaque* variable because gcc tries to - * be too smart for its own good and warns that the variable may be - * used uninitialized otherwise. */ - GLXFBConfig fb_config = (GLXFBConfig)0; - int attribs[7]; - int i = 0; - GLenum target; - CoglXlibTrapState trap_state; - - renderer = context->display->renderer; - xlib_renderer = renderer->winsys; - dpy = xlib_renderer->xdpy; - - if (!get_fbconfig_for_depth (context, - tex_pixmap->depth, &fb_config, - &glx_tex_pixmap->can_mipmap)) - { - COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i", - tex_pixmap->depth); - return FALSE; - } - - if (should_use_rectangle (context)) - { - target = GLX_TEXTURE_RECTANGLE_EXT; - glx_tex_pixmap->can_mipmap = FALSE; - } - else - target = GLX_TEXTURE_2D_EXT; - - if (!glx_tex_pixmap->can_mipmap) - mipmap = FALSE; - - attribs[i++] = GLX_TEXTURE_FORMAT_EXT; - - if (tex_pixmap->depth == 24) - attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; - else if (tex_pixmap->depth == 32) - attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; - else - return FALSE; - - attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; - attribs[i++] = mipmap; - - attribs[i++] = GLX_TEXTURE_TARGET_EXT; - attribs[i++] = target; - - attribs[i++] = None; - - /* We need to trap errors from glXCreatePixmap because it can - * sometimes fail during normal usage. For example on NVidia it gets - * upset if you try to create two GLXPixmaps for the same drawable. - */ - - _cogl_renderer_xlib_trap_errors (renderer, &trap_state); - - glx_tex_pixmap->glx_pixmap = glXCreatePixmap (dpy, - fb_config, - tex_pixmap->pixmap, - attribs); - glx_tex_pixmap->has_mipmap_space = mipmap; - - XSync (dpy, False); - - if (_cogl_renderer_xlib_untrap_errors (renderer, &trap_state)) - { - COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap); - _cogl_renderer_xlib_trap_errors (renderer, &trap_state); - glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap); - XSync (dpy, False); - _cogl_renderer_xlib_untrap_errors (renderer, &trap_state); - - glx_tex_pixmap->glx_pixmap = None; - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - - /* FIXME: It should be possible to get to a CoglContext from any - * CoglTexture pointer. */ - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - glx_tex_pixmap = g_new0 (CoglTexturePixmapGLX, 1); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->can_mipmap = FALSE; - glx_tex_pixmap->has_mipmap_space = FALSE; - - glx_tex_pixmap->glx_tex = COGL_INVALID_HANDLE; - - glx_tex_pixmap->bind_tex_image_queued = TRUE; - glx_tex_pixmap->pixmap_bound = FALSE; - - tex_pixmap->winsys = glx_tex_pixmap; - - if (!try_create_glx_pixmap (ctx, tex_pixmap, FALSE)) - { - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); - return FALSE; - } - - return TRUE; -} - -static void -free_glx_pixmap (CoglContext *context, - CoglTexturePixmapGLX *glx_tex_pixmap) -{ - CoglXlibTrapState trap_state; - CoglRenderer *renderer; - CoglRendererXlib *xlib_renderer; - CoglRendererGLX *glx_renderer; - - renderer = context->display->renderer; - xlib_renderer = renderer->winsys; - glx_renderer = renderer->winsys; - - if (glx_tex_pixmap->pixmap_bound) - glx_renderer->pf_glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_LEFT_EXT); - - /* FIXME - we need to trap errors and synchronize here because - * of ordering issues between the XPixmap destruction and the - * GLXPixmap destruction. - * - * If the X pixmap is destroyed, the GLX pixmap is destroyed as - * well immediately, and thus, when Cogl calls glXDestroyPixmap() - * it'll cause a BadDrawable error. - * - * this is technically a bug in the X server, which should not - * destroy either pixmaps until the call to glXDestroyPixmap(); so - * at some point we should revisit this code and remove the - * trap+sync after verifying that the destruction is indeed safe. - * - * for reference, see: - * http://bugzilla.clutter-project.org/show_bug.cgi?id=2324 - */ - _cogl_renderer_xlib_trap_errors (renderer, &trap_state); - glXDestroyPixmap (xlib_renderer->xdpy, glx_tex_pixmap->glx_pixmap); - XSync (xlib_renderer->xdpy, False); - _cogl_renderer_xlib_untrap_errors (renderer, &trap_state); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->pixmap_bound = FALSE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - - /* FIXME: It should be possible to get to a CoglContext from any - * CoglTexture pointer. */ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!tex_pixmap->winsys) - return; - - glx_tex_pixmap = tex_pixmap->winsys; - - free_glx_pixmap (ctx, glx_tex_pixmap); - - if (glx_tex_pixmap->glx_tex) - cogl_handle_unref (glx_tex_pixmap->glx_tex); - - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglRendererGLX *glx_renderer; - - /* FIXME: It should be possible to get to a CoglContext from any CoglTexture - * pointer. */ - _COGL_GET_CONTEXT (ctx, FALSE); - - /* If we don't have a GLX pixmap then fallback */ - if (glx_tex_pixmap->glx_pixmap == None) - return FALSE; - - glx_renderer = ctx->display->renderer->winsys; - - /* Lazily create a texture to hold the pixmap */ - if (glx_tex_pixmap->glx_tex == COGL_INVALID_HANDLE) - { - CoglPixelFormat texture_format; - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - if (should_use_rectangle (ctx)) - { - glx_tex_pixmap->glx_tex = - _cogl_texture_rectangle_new_with_size (tex_pixmap->width, - tex_pixmap->height, - COGL_TEXTURE_NO_ATLAS, - texture_format); - - if (glx_tex_pixmap->glx_tex) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture rectangle for %p", - tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture rectangle could not be created", - tex_pixmap); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } - } - else - { - glx_tex_pixmap->glx_tex = - _cogl_texture_2d_new_with_size (tex_pixmap->width, - tex_pixmap->height, - COGL_TEXTURE_NO_ATLAS, - texture_format); - - if (glx_tex_pixmap->glx_tex) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p", - tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture 2d could not be created", - tex_pixmap); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } - } - } - - if (needs_mipmap) - { - /* If we can't support mipmapping then temporarily fallback */ - if (!glx_tex_pixmap->can_mipmap) - return FALSE; - - /* Recreate the GLXPixmap if it wasn't previously created with a - * mipmap tree */ - if (!glx_tex_pixmap->has_mipmap_space) - { - free_glx_pixmap (ctx, glx_tex_pixmap); - - COGL_NOTE (TEXTURE_PIXMAP, "Recreating GLXPixmap with mipmap " - "support for %p", tex_pixmap); - if (!try_create_glx_pixmap (ctx, tex_pixmap, TRUE)) - - { - /* If the pixmap failed then we'll permanently fallback - * to using XImage. This shouldn't happen. */ - COGL_NOTE (TEXTURE_PIXMAP, "Falling back to XGetImage " - "updates for %p because creating the GLXPixmap " - "with mipmap support failed", tex_pixmap); - - if (glx_tex_pixmap->glx_tex) - cogl_handle_unref (glx_tex_pixmap->glx_tex); - return FALSE; - } - - glx_tex_pixmap->bind_tex_image_queued = TRUE; - } - } - - if (glx_tex_pixmap->bind_tex_image_queued) - { - GLuint gl_handle, gl_target; - CoglRendererXlib *xlib_renderer = ctx->display->renderer->winsys; - - cogl_texture_get_gl_texture (glx_tex_pixmap->glx_tex, - &gl_handle, &gl_target); - - COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - - GE( _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE) ); - - if (glx_tex_pixmap->pixmap_bound) - glx_renderer->pf_glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_LEFT_EXT); - - glx_renderer->pf_glXBindTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_LEFT_EXT, - NULL); - - /* According to the recommended usage in the spec for - * GLX_EXT_texture_pixmap we should release the texture after - * we've finished drawing with it and it is undefined what - * happens if you render to a pixmap that is bound to a texture. - * However that would require the texture backend to know when - * Cogl has finished painting and it may be more expensive to - * keep unbinding the texture. Leaving it bound appears to work - * on Mesa and NVidia drivers and it is also what Compiz does so - * it is probably ok */ - - glx_tex_pixmap->bind_tex_image_queued = FALSE; - glx_tex_pixmap->pixmap_bound = TRUE; - - _cogl_texture_2d_externally_modified (glx_tex_pixmap->glx_tex); - } - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - glx_tex_pixmap->bind_tex_image_queued = TRUE; -} - -static CoglHandle -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - return glx_tex_pixmap->glx_tex; -} - - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .name = "GLX", - .get_proc_address = _cogl_winsys_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_winsys_renderer_disconnect, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - .xlib_get_visual_info = _cogl_winsys_xlib_get_visual_info, - .onscreen_init = _cogl_winsys_onscreen_init, - .onscreen_deinit = _cogl_winsys_onscreen_deinit, - .onscreen_bind = _cogl_winsys_onscreen_bind, - .onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers, - .onscreen_swap_region = _cogl_winsys_onscreen_swap_region, - .onscreen_update_swap_throttled = - _cogl_winsys_onscreen_update_swap_throttled, - .onscreen_x11_get_window_xid = - _cogl_winsys_onscreen_x11_get_window_xid, - .onscreen_add_swap_buffers_callback = - _cogl_winsys_onscreen_add_swap_buffers_callback, - .onscreen_remove_swap_buffers_callback = - _cogl_winsys_onscreen_remove_swap_buffers_callback, - .onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility, - .get_vsync_counter = _cogl_winsys_get_vsync_counter, - - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - .texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create, - .texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free, - .texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update, - .texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify, - .texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture, - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-private.h b/clutter/cogl/cogl/winsys/cogl-winsys-private.h deleted file mode 100644 index 1e1fec0..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys-private.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __COGL_WINSYS_PRIVATE_H -#define __COGL_WINSYS_PRIVATE_H - -#include "cogl-framebuffer-private.h" -#ifdef COGL_HAS_XLIB_SUPPORT -#include "cogl-texture-pixmap-x11-private.h" -#endif - -#ifdef COGL_HAS_XLIB_SUPPORT -#include -#include "cogl-texture-pixmap-x11-private.h" -#endif - -GQuark -_cogl_winsys_error_quark (void); - -#define COGL_WINSYS_ERROR (_cogl_winsys_error_quark ()) - -typedef enum { /*< prefix=COGL_WINSYS_ERROR >*/ - COGL_WINSYS_ERROR_INIT, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, -} CoglWinsysError; - -typedef enum -{ - COGL_WINSYS_RECTANGLE_STATE_UNKNOWN, - COGL_WINSYS_RECTANGLE_STATE_DISABLE, - COGL_WINSYS_RECTANGLE_STATE_ENABLE -} CoglWinsysRectangleState; - -typedef struct _CoglWinsysVtable -{ - const char *name; - - CoglFuncPtr - (*get_proc_address) (const char *name); - - gboolean - (*renderer_connect) (CoglRenderer *renderer, GError **error); - - void - (*renderer_disconnect) (CoglRenderer *renderer); - - gboolean - (*display_setup) (CoglDisplay *display, GError **error); - - void - (*display_destroy) (CoglDisplay *display); - - gboolean - (*context_init) (CoglContext *context, GError **error); - - void - (*context_deinit) (CoglContext *context); - -#ifdef COGL_HAS_EGL_SUPPORT - EGLDisplay - (*context_egl_get_egl_display) (CoglContext *context); -#endif - - gboolean - (*has_feature) (CoglWinsysFeature feature); - -#ifdef COGL_HAS_XLIB_SUPPORT - XVisualInfo * - (*xlib_get_visual_info) (void); -#endif - - gboolean - (*onscreen_init) (CoglOnscreen *onscreen, GError **error); - - void - (*onscreen_deinit) (CoglOnscreen *onscreen); - - void - (*onscreen_bind) (CoglOnscreen *onscreen); - - void - (*onscreen_swap_buffers) (CoglOnscreen *onscreen); - - void - (*onscreen_swap_region) (CoglOnscreen *onscreen, - int *rectangles, - int n_rectangles); - - void - (*onscreen_update_swap_throttled) (CoglOnscreen *onscreen); - - guint32 - (*onscreen_x11_get_window_xid) (CoglOnscreen *onscreen); - - unsigned int - (*onscreen_add_swap_buffers_callback) (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data); - - void - (*onscreen_remove_swap_buffers_callback) (CoglOnscreen *onscreen, - unsigned int id); - - void - (*onscreen_set_visibility) (CoglOnscreen *onscreen, - gboolean visibility); - - guint32 - (*get_vsync_counter) (void); - -#ifdef COGL_HAS_XLIB_SUPPORT - gboolean - (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap); - void - (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap); - - gboolean - (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap); - - void - (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap); - - CoglHandle - (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap); -#endif - -} CoglWinsysVtable; - -gboolean -_cogl_winsys_has_feature (CoglWinsysFeature feature); - -#endif /* __COGL_WINSYS_PRIVATE_H */ diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-sdl.c b/clutter/cogl/cogl/winsys/cogl-winsys-sdl.c deleted file mode 100644 index 9c937e4..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys-sdl.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" - -CoglFuncPtr -_cogl_winsys_get_proc_address (const char *name) -{ - return NULL; -} - diff --git a/clutter/cogl/cogl/winsys/cogl-winsys-stub.c b/clutter/cogl/cogl/winsys/cogl-winsys-stub.c deleted file mode 100644 index a45cbdf..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys-stub.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl-framebuffer-private.h" - -/* This provides a stub winsys implementation for when Clutter still handles - * creating an OpenGL context. This is useful so we don't have to guard all - * calls into the winsys layer with #ifdef COGL_HAS_FULL_WINSYS - */ - -CoglFuncPtr -_cogl_winsys_get_proc_address (const char *name) -{ - return NULL; -} - -void -_cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen) -{ - -} - -void -_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, - int *rectangles, - int n_rectangles) -{ - -} - -void -_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) -{ - -} - -unsigned int -_cogl_winsys_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data) -{ - g_assert (0); - return 0; -} - -void -_cogl_winsys_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, - unsigned int id) -{ - g_assert (0); -} - -#ifdef COGL_HAS_XLIB_SUPPORT -XVisualInfo * -_cogl_winsys_xlib_get_visual_info (void) -{ - g_assert (0); - return NULL; -} -#endif - -#ifdef COGL_HAS_X11_SUPPORT -guint32 -_cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) -{ - g_assert (0); - return 0; -} -#endif - -gboolean -_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, - GError **error) -{ - return TRUE; -} - -void -_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) -{ - -} - -void -_cogl_winsys_context_deinit (CoglContext *context) -{ - -} diff --git a/clutter/cogl/cogl/winsys/cogl-winsys.c b/clutter/cogl/cogl/winsys/cogl-winsys.c deleted file mode 100644 index 547ea5a..0000000 --- a/clutter/cogl/cogl/winsys/cogl-winsys.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "cogl.h" -#include "cogl-context-private.h" - -GQuark -_cogl_winsys_error_quark (void) -{ - return g_quark_from_static_string ("cogl-winsys-error-quark"); -} - -/* FIXME: we should distinguish renderer and context features */ -gboolean -_cogl_winsys_has_feature (CoglWinsysFeature feature) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - return COGL_FLAGS_GET (ctx->winsys_features, feature); -} diff --git a/clutter/cogl/configure.ac b/clutter/cogl/configure.ac deleted file mode 100644 index c982156..0000000 --- a/clutter/cogl/configure.ac +++ /dev/null @@ -1,769 +0,0 @@ -AC_PREREQ(2.59) - -dnl ================================================================ -dnl XXX: If you are making a release then you need to check these -dnl sections: -dnl » API versions -dnl (the pretty numbers that the users see) -dnl -dnl » Interface version details for libtool -dnl (the shared library versioning information) -dnl -dnl » Source code release status -dnl (mark the source code as being part of a "release" or from "git") -dnl ================================================================ - -dnl ================================================================ -dnl API versions (i.e. the pretty numbers that users see) -dnl ================================================================ -m4_define([cogl_major_version], [2]) -m4_define([cogl_minor_version], [0]) -m4_define([cogl_micro_version], [0]) -m4_define([cogl_version], - [cogl_major_version.cogl_minor_version.cogl_micro_version]) - -dnl Since the core Cogl library has to also maintain support for the -dnl Cogl 1.x API for Clutter then we track the 1.x version separately. -m4_define([cogl_1_minor_version], [6]) -m4_define([cogl_1_micro_version], [0]) -m4_define([cogl_1_version], [1.cogl_1_minor_version.cogl_1_micro_version]) - -dnl ================================================================ -dnl Interface version details for libtool -dnl ================================================================ -# Note: we don't automatically deduce the libtool version info from -# the pretty version number that users sees. This is because we want -# to update the pretty version number before making a release since it -# can affect the name of our pkg-config file and the naming or -# location of other installed files which we want to be able to verify -# as correct well before making a release. -# -# For reference on how the various numbers should be updated at -# release time these rules are adapted from the libtool info pages: -# -# 1. Update the version information only immediately before a public -# release. -# -# 2. If the library source code has changed at all since the last -# update, then increment REVISION (`C:R:A' becomes `C:r+1:A'). -# -# 3. If any interfaces have been added, removed, or changed since the -# last update, increment CURRENT, and set REVISION to 0. -# -# 4. If any interfaces have been added since the last public release, -# then increment AGE. -# -# 5. If any interfaces have been removed since the last public release, -# then set AGE to 0. -m4_define([cogl_lt_current], 0) -m4_define([cogl_lt_revision], 0) -m4_define([cogl_lt_age], 0) -# We do also tell libtool the pretty version: -m4_define([cogl_lt_release], [cogl_version]) - - -dnl ================================================================ -dnl Source code release status -dnl ================================================================ -# Finally we explicitly track when we are building development source -# from Git vs building source corresponding to a release. As with the -# libtool version info we don't automatically derive this from the -# pretty version number because we want to test the results of -# updating the version number in advance of a release. -m4_define([cogl_release_status], [git]) - - -dnl ================================================================ -dnl Required versions for dependencies -dnl ================================================================ -m4_define([glib_req_version], [2.26.0]) -m4_define([pangocairo_req_version], [1.20]) -m4_define([gi_req_version], [0.9.5]) -m4_define([gdk_pixbuf_req_version], [2.0]) -m4_define([uprof_req_version], [0.3]) -m4_define([gtk_doc_req_version], [1.13]) -m4_define([xfixes_req_version], [3]) -m4_define([xcomposite_req_version], [0.4]) - - -AC_INIT(cogl, [cogl_version]) -AC_CONFIG_SRCDIR(cogl/cogl.h) -AC_CONFIG_AUX_DIR([build]) -AC_CONFIG_MACRO_DIR([build/autotools]) -AC_CONFIG_HEADERS(config.h) - -# Save this value here, since automake will set cflags later and we -# want to know if the user specified custom cflags or not. -cflags_set=${CFLAGS+set} - -AM_INIT_AUTOMAKE([1.11 foreign -Wno-portability no-define no-dist-gzip - dist-bzip2]) -AM_SILENT_RULES([yes]) - - -dnl ================================================================ -dnl Export the API versioning -dnl ================================================================ -AC_SUBST([COGL_MAJOR_VERSION],[cogl_major_version]) -AC_SUBST([COGL_MINOR_VERSION],[cogl_minor_version]) -AC_SUBST([COGL_MICRO_VERSION],[cogl_micro_version]) -AC_SUBST([COGL_VERSION],[cogl_version]) -AC_SUBST([COGL_API_VERSION],[cogl_major_version.0]) -AC_SUBST([COGL_API_VERSION_AM],[$COGL_MAJOR_VERSION\_0]) - -AC_SUBST([COGL_1_MINOR_VERSION],[cogl_1_minor_version]) -AC_SUBST([COGL_1_MICRO_VERSION],[cogl_1_micro_version]) -AC_SUBST([COGL_1_VERSION],[cogl_1_version]) - - -dnl ================================================================ -dnl Export the libtool versioning -dnl ================================================================ -AC_SUBST([COGL_LT_CURRENT], [cogl_lt_current]) -AC_SUBST([COGL_LT_REVISION], [cogl_lt_revision]) -AC_SUBST([COGL_LT_AGE], [cogl_lt_age]) -AC_SUBST([COGL_LT_RELEASE], [cogl_lt_release]) - - -dnl ================================================================ -dnl Export the source code release status -dnl ================================================================ -AC_SUBST([COGL_RELEASE_STATUS], [cogl_release_status]) - - -dnl ================================================================ -dnl See what platform we are building for -dnl ================================================================ -AC_CANONICAL_HOST -AC_MSG_CHECKING([if building for some Win32 platform]) -AS_CASE([$host], - [*-*-mingw*|*-*-cygwin*], - [ - COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -no-undefined" - platform_win32=yes - ], - - [platform_win32=no] -) -AC_MSG_RESULT([$platform_win32]) -AM_CONDITIONAL(OS_WIN32, [test "$platform_win32" = "yes"]) - - -dnl ================================================================ -dnl Handle extra configure options -dnl ================================================================ - -dnl ============================================================ -dnl Enable debugging -dnl ============================================================ -m4_define([default], [m4_if(cogl_release_status, [git], [yes], [no])]) -AC_ARG_ENABLE( - [debug], - [AC_HELP_STRING([--enable-debug=@<:@no/yes@:>@], [Control Cogl debugging level @<:@default=]default[@:>@])], - [], - enable_debug=default -) - -AS_CASE( - [$enable_debug], - [yes], - [ - test "$cflags_set" = set || CFLAGS="$CFLAGS -g -O0" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -DCOGL_GL_DEBUG -DCOGL_OBJECT_DEBUG -DCOGL_HANDLE_DEBUG -DCOGL_ENABLE_DEBUG" - ], - [no], - [ - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -DCOGL_ENABLE_DEBUG -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS" - ], - [AC_MSG_ERROR([Unknown argument for --enable-debug])] -) - -AC_SUBST(COGL_DEBUG_CFLAGS) - - -dnl ============================================================ -dnl Enable strict compiler flags -dnl ============================================================ - -# use strict compiler flags only when building from git; the rules for -# distcheck will take care of turning this on when making a release -m4_define([default], [m4_if(cogl_release_status, [git], [yes], [no])]) -AC_ARG_ENABLE( - [maintainer-flags], - [AC_HELP_STRING([--enable-maintainer-flags=@<:@no/yes/error@:>@], [Use strict compiler flags @<:@default=]default[@:>@])], - [], - enable_maintainer_flags=default -) - -MAINTAINER_COMPILER_FLAGS="-Wall -Wshadow -Wcast-align -Wuninitialized - -Wno-strict-aliasing -Wempty-body -Wformat - -Wformat-security -Winit-self - -Wdeclaration-after-statement -Wvla - -Wpointer-arith" - -AS_CASE( - [$enable_maintainer_flags], - [yes], - [ - AS_COMPILER_FLAGS([MAINTAINER_CFLAGS], [$MAINTAINER_COMPILER_FLAGS]) - ], - [no], - [ - ], - [error], - [ - MAINTAINER_COMPILER_FLAGS="$MAINTAINER_COMPILER_FLAGS -Werror" - AS_COMPILER_FLAGS([MAINTAINER_CFLAGS], [$MAINTAINER_COMPILER_FLAGS]) - ], - [*], - [AC_MSG_ERROR([Invalid option for --enable-maintainer-flags])] -) - -# strip leading spaces -COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS ${MAINTAINER_CFLAGS/# }" - - -dnl ============================================================ -dnl Choose image loading backend -dnl ============================================================ -AC_ARG_ENABLE( - [gdk-pixbuf], - [AC_HELP_STRING([--enable-gdk-pixbuf=@<:@no/yes@:>@], [Enable image loading via gdk-pixbuf @<:@default=yes@:>@])], - [], - enable_gdk_pixbuf=yes -) -if test "x$enable_gdk_pixbuf" = "xyes"; then - PKG_CHECK_EXISTS([gdk-pixbuf-2.0], [have_gdk_pixbuf=yes], [have_gdk_pixbuf=no]) -else - have_gdk_pixbuf=no -fi - -AC_ARG_ENABLE( - [quartz-image], - [AC_HELP_STRING([--enable-quartz-image=@<:@no/yes@:>@], [Enable image loading via quartz @<:@default=no@:>@])], - [], - enable_quartz_image=no -) - -AS_IF( - [test "x$have_gdk_pixbuf" = "xyes"], - [ - AC_DEFINE([USE_GDKPIXBUF], 1, [Use GdkPixbuf for loading image data]) - COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gdk-pixbuf-2.0 >= gdk_pixbuf_req_version" - COGL_IMAGE_BACKEND="gdk-pixbuf" - ], - [test "x$enable_quartz_image" = "xyes"], - [ - EXPERIMENTAL_CONFIG=yes - EXPERIMENTAL_OPTIONS="$EXPERIMENTAL_OPTIONS Quartz Core Graphics," - AC_DEFINE([USE_QUARTZ], 1, - [Use Core Graphics (Quartz) for loading image data]) - COGL_IMAGE_BACKEND="quartz" - ], - [ - EXPERIMENTAL_CONFIG=yes - EXPERIMENTAL_OPTIONS="$EXPERIMENTAL_OPTIONS fallback image decoding (stb_image)," - AC_DEFINE([USE_INTERNAL], 1, - [Use internal image decoding for loading image data]) - COGL_IMAGE_BACKEND="stb_image" - ] -) - - - -dnl ============================================================ -dnl Determine which drivers and window systems we can support -dnl ============================================================ - -dnl ======================================================== -dnl Drivers first... -dnl ======================================================== -DRIVER_COUNT=0 -EGL_CHECKED=no - -AC_ARG_ENABLE( - [gles1], - [AC_HELP_STRING([--enable-gles1=@<:@no/yes@:>@], [Enable support for OpenGL-ES 1.1 @<:@default=no@:>@])], - [], - enable_gles1=no -) -AS_IF([test "x$enable_gles1" = "xyes"], - [ - AS_IF([test "x$platform_win32" != "xyes"], - [AC_MSG_ERROR([GLES 1 not available for win32])]) - - DRIVER_COUNT=$((DRIVER_COUNT + 1)) - COGL_DRIVER=gles - glesversion=1.1 - - cogl_gl_headers="GLES/gl.h GLES/glext.h" - - AC_DEFINE([HAVE_COGL_GLES], 1, [Have GLES 1.1 for rendering]) - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES CLUTTER_COGL_HAS_GLES" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES1" - - PKG_CHECK_EXISTS([glesv1_cm], - [COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES glesv1_cm" - NEED_EGL=yes - ], - [ - AC_CHECK_HEADERS([$cogl_gl_headers], - [], - [AC_MSG_ERROR([Unable to locate required GLES headers])]) - - # Check for a GLES 1.x Common Profile library with/without EGL. - # - # Note: historically GLES 1 libraries shipped with the - # EGL and GLES symbols all bundled in one library. Now - # the Khronos Implementers Guide defines two naming - # schemes: -lGLES_CM should be used for a library that - # bundles the GLES and EGL API together and -lGLESv1_CM - # would be used for a standalone GLES API. - AC_CHECK_LIB(GLES_CM, [eglInitialize], - [COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGLES_CM"], - [ - AC_CHECK_LIB(GLESv1_CM, [glFlush], - [COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGLESv1_CM" - NEED_SEPARATE_EGL=yes - ], - [AC_MSG_ERROR([Unable to locate required GLES 1.x Common Profile library])]) - ]) - - EGL_CHECKED=yes - ]) - ]) - -AC_ARG_ENABLE( - [gles2], - [AC_HELP_STRING([--enable-gles2=@<:@no/yes@:>@], [Enable support for OpenGL-ES 2.0 @<:@default=no@:>@])], - [], - enable_gles2=no -) -AS_IF([test "x$enable_gles2" = "xyes"], - [ - AS_IF([test "x$platform_win32" != "xyes"], - [AC_MSG_ERROR([GLES 1 not available for win32])]) - - DRIVER_COUNT=$((DRIVER_COUNT + 1)) - COGL_DRIVER=gles - glesversion=2.0 - - cogl_gl_headers="GLES2/gl2.h GLES2/gl2ext.h" - AC_DEFINE([HAVE_COGL_GLES2], 1, [Have GLES 2.0 for rendering]) - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES CLUTTER_COGL_HAS_GLES" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES2" - - PKG_CHECK_EXISTS([glesv2], - [COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES glesv2"], - [ - AC_CHECK_HEADERS([$cogl_gl_headers], - [], - [AC_MSG_ERROR([Unable to locate required GLES headers])], - [[#include - ]]) - - COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGLESv2" - ]) - - NEED_EGL=yes - ]) - -AC_ARG_ENABLE( - [gl], - [AC_HELP_STRING([--enable-gl=@<:@no/yes@:>@], [Enable support for OpenGL @<:@default=yes@:>@])], - [], - [AS_IF([test $DRIVER_COUNT -gt 0], [enable_gl=no], [enable_gl=yes])] -) -AS_IF([test "x$enable_gl" = "xyes"], - [ - DRIVER_COUNT=$((DRIVER_COUNT + 1)) - COGL_DRIVER=gl - ALLOW_GLX=yes - - cogl_gl_headers="GL/gl.h" - - AS_IF([test "x$platform_win32" = "xyes"], - [ - COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lopengl32 -lgdi32 -lwinmm" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -D_WIN32_WINNT=0x0500" - ], - [ - PKG_CHECK_EXISTS( - [gl], [COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gl"], - [AC_CHECK_LIB(GL, [glGetString], - [COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lGL"], - [AC_MSG_ERROR([Unable to locate required GL library])]) - ]) - ]) - - AC_DEFINE([HAVE_COGL_GL], [1], [Have GL for rendering]) - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GL" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS CLUTTER_COGL_HAS_GL" - ]) - -AS_IF([test $DRIVER_COUNT -gt 1], - [AC_MSG_ERROR(['The --enable-gl{es1,es2} options are currently mutually exclusive'])]) - -AC_SUBST([COGL_DRIVER]) - -AM_CONDITIONAL([COGL_DRIVER_GL], [test "x$COGL_DRIVER" = "xgl"]) -AM_CONDITIONAL([COGL_DRIVER_GLES], [test "x$COGL_DRIVER" = "xgles"]) - -dnl ======================================================== -dnl Check window system integration libraries... -dnl ======================================================== - -dnl The "stub" winsys is a fallback option we use when Cogl doesn't -dnl yet have support for a window system. It enables a toolkit like -dnl Clutter to provide external support instead. Currently this is -dnl not compatible with other window system backends. -AC_ARG_ENABLE( - [stub-winsys], - [AC_HELP_STRING([--enable-stub-winsys=@<:@no/yes@:>@], [Enable support stub winsys @<:@default=no@:>@])], - [], - enable_stub_winsys=no -) -AS_IF([test "x$enable_stub_winsys" = "xyes"], - [ - GL_WINSYS_APIS="$GL_WINSYS_APIS stub" - ALLOW_GLX=no - ]) -AM_CONDITIONAL(SUPPORT_STUB, [test "x$enable_stub_winsys" = "xyes"]) - -AC_ARG_ENABLE( - [glx], - [AC_HELP_STRING([--enable-glx=@<:@no/yes@:>@], [Enable support GLX @<:@default=auto@:>@])], - [], - [AS_IF([test "x$ALLOW_GLX" = "xyes"], [enable_glx=yes], [enable_glx=no])] -) -AS_IF([test "x$enable_glx" = "xyes"], - [ - AS_IF([test "x$enable_stub_winsys" = "xyes"], - [AC_MSG_ERROR([Stub winsys not currently compatible with others])]) - - AS_IF([test "x$ALLOW_GLX" != "xyes"], - [AC_MSG_ERROR([GLX not supported with $COGL_DRIVER driver])]) - - NEED_XLIB=yes - SUPPORT_GLX=yes - GL_WINSYS_APIS="$GL_WINSYS_APIS glx" - - AC_DEFINE([COGL_HAS_GLX_SUPPORT], [1], [Cogl supports OpenGL using the GLX API]) - AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], - [Cogl can create its own OpenGL context]) - - # We might fall back to DRM for sync-to-vblank on GLX - PKG_CHECK_EXISTS([libdrm], - [ - AC_DEFINE([HAVE_DRM], [1], [Have libdrm support]) - COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES libdrm" - ], - []) - ]) -AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "xyes"]) - - -EGL_PLATFORM_COUNT=0 - -AC_ARG_ENABLE( - [null-egl-platform], - [AC_HELP_STRING([--enable-null-egl-platform=@<:@no/yes@:>@], [Enable support for the NULL egl platform @<:@default=no@:>@])], - [], - enable_null_egl_platform=no -) -AS_IF([test "x$enable_null_egl_platform" = "xyes"], - [ - AS_IF([test "x$enable_stub_winsys" = "xyes"], - [AC_MSG_ERROR([Stub winsys not currently compatible with others])]) - - EGL_PLATFORM_COUNT=$((EGL_PLATFORM_COUNT+1)) - NEED_EGL=yes - EGL_PLATFORMS="$EGL_PLATFORMS null" - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT" - ]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_POWERVR_NULL, - [test "x$enable_null_egl_platform" = "xyes"]) - -AC_ARG_ENABLE( - [gdl-egl-platform], - [AC_HELP_STRING([--enable-gdl-egl-platform=@<:@no/yes@:>@], [Enable support for the GDL egl platform @<:@default=no@:>@])], - [], - enable_gdl_egl_platform=no -) -AS_IF([test "x$enable_gdl_egl_platform" == "xyes"], - [ - AS_IF([test "x$enable_stub_winsys" = "xyes"], - [AC_MSG_ERROR([Stub winsys not currently compatible with others])]) - - EGL_PLATFORM_COUNT=$((EGL_PLATFORM_COUNT+1)) - NEED_EGL=yes - EGL_PLATFORMS="$EGL_PLATFORMS gdl" - - AC_CHECK_HEADERS( - [libgdl.h], - [], - [ - AC_CHECK_HEADERS( - [CE4100/libgdl.h], - [COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I/usr/include/CE4100"], - [AC_MSG_ERROR([libgdl.h not found])]) - ]) - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_GDL_SUPPORT" - ]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_GDL, - [test "x$enable_gdl_egl_platform" = "xyes"]) - -dnl This should go last, since it's the default fallback and we need -dnl to check the value of $EGL_PLATFORM_COUNT here. -AC_ARG_ENABLE( - [xlib-egl-platform], - [AC_HELP_STRING([--enable-xlib-egl-platform=@<:@no/yes@:>@], [Enable support for the Xlib egl platform @<:@default=auto@:>@])], - [], - AS_IF([test "x$COGL_DRIVER" = "xgles" && test $EGL_PLATFORM_COUNT -eq 0], - [enable_xlib_egl_platform=yes], [enable_xlib_egl_platform=no]) -) -AS_IF([test "x$enable_xlib_egl_platform" = "xyes"], - [ - AS_IF([test "x$enable_stub_winsys" = "xyes"], - [AC_MSG_ERROR([Stub winsys not currently compatible with others])]) - - EGL_PLATFORM_COUNT=$((EGL_PLATFORM_COUNT+1)) - NEED_EGL=yes - NEED_XLIB=yes - EGL_PLATFORMS="$EGL_PLATFORMS xlib" - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT" - ]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_POWERVR_X11, - [test "x$enable_xlib_egl_platform" = "xyes"]) - - - -AS_IF([test $EGL_PLATFORM_COUNT -gt 1], - [AC_MSG_ERROR(['The --enable-*-egl-platform options are currently mutually exclusive'])]) - -AS_IF([test "x$NEED_EGL" = "xyes" && test "x$EGL_CHECKED" != "xyes"], - [ - PKG_CHECK_EXISTS([egl], - [COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES egl"], - [ - AC_CHECK_HEADERS( - [EGL/egl.h], - [], - [AC_MSG_ERROR([Unable to locate required EGL headers])]) - - AC_CHECK_LIB(EGL, [eglInitialize], - [COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lEGL"], - [AC_MSG_ERROR([Unable to locate required EGL library])]) - - COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lEGL" - ] - ) - SUPPORT_EGL=yes - GL_WINSYS_APIS="$GL_WINSYS_APIS egl" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_SUPPORT" - AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], - [Cogl can create its own OpenGL context]) - ]) -AM_CONDITIONAL(SUPPORT_EGL, [test "x$SUPPORT_EGL" = "xyes"]) - - -dnl ======================================================== -dnl Check X11 dependencies if required -dnl ======================================================== -AS_IF([test "x$NEED_XLIB" = "xyes"], - [ - X11_MODULES="x11 xext xfixes >= xfixes_req_version xdamage xcomposite >= xcomposite_req_version" - PKG_CHECK_MODULES(DUMMY, [$X11_MODULES], - [COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES $X11_MODULES"]) - SUPPORT_X11=yes - SUPPORT_XLIB=yes - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_X11" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_X11_SUPPORT" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_XLIB" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_XLIB_SUPPORT" - ]) - -AM_CONDITIONAL(X11_TESTS, [test "x$SUPPORT_X11" = "xyes"]) -AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "xyes"]) -AM_CONDITIONAL(SUPPORT_XLIB, [test "x$SUPPORT_XLIB" = "xyes"]) - - -AM_CONDITIONAL(COGL_STANDALONE_BUILD, [true]) - -dnl ================================================================ -dnl Compiler stuff. -dnl ================================================================ -AC_PROG_CC -AC_PROG_CPP -AM_PROG_CC_C_O -AC_ISC_POSIX -AC_C_CONST - - -dnl ================================================================ -dnl Libtool stuff. -dnl ================================================================ -dnl AC_PROG_LIBTOOL -dnl LIBTOOL="$LIBTOOL --preserve-dup-deps" -LT_PREREQ([2.2.6]) -LT_INIT([disable-static]) - -dnl ================================================================ -dnl I18n stuff. -dnl ================================================================ -AM_GNU_GETTEXT_VERSION([0.17]) -AM_GNU_GETTEXT([external]) - -GETTEXT_PACKAGE="cogl" -AC_SUBST(GETTEXT_PACKAGE) -AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, - "$GETTEXT_PACKAGE", - [The prefix for our gettext translation domains.]) -AS_ALL_LINGUAS - - -dnl ================================================================ -dnl Documentation stuff. -dnl ================================================================ -GTK_DOC_CHECK([gtk_doc_req_version], [--flavour no-tmpl]) - - -dnl ================================================================ -dnl Check for dependency packages. -dnl ================================================================ - -dnl ============================================================ -dnl Check glib dependencies -dnl ============================================================ -AM_PATH_GLIB_2_0([glib_req_version], - [have_glib=yes], [have_glib=no], - [gobject gthread gmodule-no-export]) -AS_IF([test "x$have_glib" = "xno"], AC_MSG_ERROR([glib-2.0 is required])) - -COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES glib-2.0 pangocairo >= pangocairo_req_version" -AC_SUBST(COGL_PKG_REQUIRES) -PKG_CHECK_MODULES(COGL_DEP, [$COGL_PKG_REQUIRES]) - - -dnl ================================================================ -dnl Misc program dependencies. -dnl ================================================================ -AC_PROG_INSTALL - -dnl ================================================================ -dnl GObject-Introspection check -dnl ================================================================ -GOBJECT_INTROSPECTION_CHECK([gi_req_version]) - -dnl ================================================================ -dnl Checks for header files. -dnl ================================================================ -AC_PATH_X -AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h limits.h unistd.h) - - -dnl ================================================================ -dnl Checks for library functions. -dnl ================================================================ - - -dnl ================================================================ -dnl What needs to be substituted in other files -dnl ================================================================ -COGL_DEFINES="" -for x in $COGL_DEFINES_SYMBOLS; do - COGL_DEFINES="$COGL_DEFINES -#define $x 1" -done; -AC_SUBST(COGL_DEFINES) - - -AS_IF([test "x$cogl_gl_headers" = "x"], - [AC_MSG_ERROR([Internal error: no GL header set])]) -dnl cogl_gl_headers is a space separate list of headers to -dnl include. We'll now convert them to a single variable with a -dnl #include line for each header -COGL_GL_HEADER_INCLUDES="" -for x in $cogl_gl_headers; do - COGL_GL_HEADER_INCLUDES="$COGL_GL_HEADER_INCLUDES -#include <$x>" -done; -AC_SUBST(COGL_GL_HEADER_INCLUDES) - -AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_2_0_API], [1], - [Can use Cogl 2.0 API internally]) - -AC_SUBST(COGL_DEP_CFLAGS) -AC_SUBST(COGL_DEP_LIBS) -AC_SUBST(COGL_EXTRA_CFLAGS) -AC_SUBST(COGL_EXTRA_LDFLAGS) - -# just for compatability with the clutter build... -MAINTAINER_CFLAGS= -AC_SUBST(MAINTAINER_CFLAGS) - -AC_OUTPUT( -Makefile -cogl/Makefile -cogl/cogl-1.0.pc -cogl/cogl-$COGL_MAJOR_VERSION.0.pc:cogl/cogl.pc.in -cogl/cogl-defines.h -pango/Makefile -examples/Makefile -po/Makefile.in -) - -dnl ================================================================ -dnl Dah Da! -dnl ================================================================ -echo "" -echo "Cogl - $COGL_1_VERSION/$COGL_VERSION (${COGL_RELEASE_STATUS})" - -# Global flags -echo "" -echo " • Global:" -echo " Prefix: ${prefix}" - -echo "" -# Features -echo " • Features:" -echo " Driver: ${COGL_DRIVER} ${glesversion}" -echo " GL Window System APIs:${GL_WINSYS_APIS}" -if test "x$SUPPORT_EGL" = "xyes"; then -echo " EGL Platforms:${EGL_PLATFORMS}" -fi -echo " Image backend: ${COGL_IMAGE_BACKEND}" - -# Compiler/Debug related flags -echo "" -echo " • Compiler options:" -echo " Cogl debug: ${enable_debug}" -echo " Compiler flags: ${CFLAGS} ${COGL_EXTRA_CFLAGS}" -echo " Linker flags: ${LDFLAGS} ${COGL_EXTRA_LDFLAGS}" - -# Miscellaneous -echo "" -echo " • Extra:" -echo " Build introspection data: ${enable_introspection}" - -echo "" - -# General warning about experimental features -if test "x$EXPERIMENTAL_CONFIG" = "xyes"; then -echo "" -echo "☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠" -echo " *WARNING*" -echo "" -echo " The stability of your build might be affected by one or more" -echo " experimental configuration options." -echo -echo " experimental options: $EXPERIMENTAL_OPTIONS" -echo "☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠☠" -echo "" -fi diff --git a/clutter/cogl/doc/CODING_STYLE b/clutter/cogl/doc/CODING_STYLE deleted file mode 100644 index 748b915..0000000 --- a/clutter/cogl/doc/CODING_STYLE +++ /dev/null @@ -1,49 +0,0 @@ -Cogl Coding Style --------------------- - -This document is intended to be a short description of the preferred -coding style to be used for the Cogl source code. - -Coding style is a matter of consistency, readability and maintainance; -coding style is also completely arbitrary and a matter of taste. This -document will use examples at the very least to provide authoritative -and consistent answers to common questions regarding the coding style, -and will also try to identify the allowed exceptions. - -The Cogl coding style is currently defined relative to the Clutter -coding style, so please first read clutter/docs/CODING_STYLE. - -Differences to the Clutter coding style: - -+ Headers - -Cogl headers are not exempt from the 80 characters limit as they are in -Clutter. Function prototypes should not be arranged into vertical -columns but should instead follow the "+ Functions" section of the -Clutter CODING_STYLE like: - -void -my_function (CoglType type, - CoglType *a_pointer, - CoglType another_type); - -+ Types - -Avoid the use of redundant glib typedefs and wherever possible simply -use ANSI C types. - -The following types should not be used: - gint, guint, gfloat, gdouble, glong, gulong, gchar and guchar -Instead use: - int, unsigned int, float, double, long, unsigned long, char, and - guint8/unsigned char - -The glib types that we continue to use for portability are gboolean, -gint{8,16,32,64}, guint{8,16,32,64} and gsize. When ever you need a -byte size type for dealing with pixel data then guint8 should be used. - -The general intention is that Cogl should look palatable to the widest -range of C programmers including those outside the Gnome community so -- especially for the public API - we want to minimize the number of -foreign looking typedefs. - diff --git a/clutter/cogl/examples/Makefile.am b/clutter/cogl/examples/Makefile.am deleted file mode 100644 index a36befe..0000000 --- a/clutter/cogl/examples/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -include $(top_srcdir)/build/autotools/Makefile.am.silent - -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/clutter/cogl \ - -I$(top_builddir)/clutter/cogl - -AM_CFLAGS = \ - $(COGL_DEP_CFLAGS) \ - $(COGL_EXTRA_CFLAGS) \ - -DCOGL_ENABLE_EXPERIMENTAL_2_0_API - -AM_CPPFLAGS = \ - -DG_DISABLE_SINGLE_INCLUDES \ - -DCOGL_DISABLE_DEPRECATED - - -common_ldadd = \ - $(top_builddir)/cogl/libcogl.la \ - $(top_builddir)/pango/libcoglpango.la - -noinst_PROGRAMS = hello - -hello_SOURCES = hello.c -hello_LDADD = $(common_ldadd) - -if X11_TESTS -noinst_PROGRAMS += x11-foreign -x11_foreign_SOURCES = x11-foreign.c -x11_foreign_LDADD = $(common_ldadd) -endif diff --git a/clutter/cogl/examples/hello.c b/clutter/cogl/examples/hello.c deleted file mode 100644 index 62076ad..0000000 --- a/clutter/cogl/examples/hello.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include - -int -main (int argc, char **argv) -{ - CoglContext *ctx; - CoglOnscreen *onscreen; - CoglFramebuffer *fb; - GError *error = NULL; - CoglVertexP2C4 triangle_vertices[] = { - {0, 0.7, 0xff, 0x00, 0x00, 0x80}, - {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, - {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} - }; - CoglPrimitive *triangle; - - ctx = cogl_context_new (NULL, &error); - if (!ctx) { - fprintf (stderr, "Failed to create context: %s\n", error->message); - return 1; - } - /* Eventually we want to get rid of any "default context" but for now it's - * needed... */ - cogl_set_default_context (ctx); - - onscreen = cogl_onscreen_new (ctx, 640, 480); - /* Eventually there will be an implicit allocate on first use so this - * will become optional... */ - fb = COGL_FRAMEBUFFER (onscreen); - if (!cogl_framebuffer_allocate (fb, &error)) { - fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message); - return 1; - } - - cogl_onscreen_show (onscreen); - - cogl_push_framebuffer (fb); - - triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES, - 3, triangle_vertices); - for (;;) { - cogl_primitive_draw (triangle); - cogl_framebuffer_swap_buffers (fb); - } - - return 0; -} diff --git a/clutter/cogl/examples/x11-foreign.c b/clutter/cogl/examples/x11-foreign.c deleted file mode 100644 index 7012562..0000000 --- a/clutter/cogl/examples/x11-foreign.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include - -#include -#include - -static void -update_cogl_x11_event_mask (CoglOnscreen *onscreen, - guint32 event_mask, - void *user_data) -{ - XDisplay *xdpy = user_data; - XSetWindowAttributes attrs; - guint32 xwin; - - attrs.event_mask = event_mask; - xwin = cogl_onscreen_x11_get_window_xid (onscreen); - - XChangeWindowAttributes (xdpy, - (Window)xwin, - CWEventMask, - &attrs); -} - -int -main (int argc, char **argv) -{ - Display *xdpy; - CoglRenderer *renderer; - CoglSwapChain *chain; - CoglOnscreenTemplate *onscreen_template; - CoglDisplay *display; - CoglContext *ctx; - CoglOnscreen *onscreen; - CoglFramebuffer *fb; - GError *error = NULL; - guint32 visual; - XVisualInfo template, *xvisinfo; - int visinfos_count; - XSetWindowAttributes xattr; - unsigned long mask; - Window xwin; - - /* Since we want to test external ownership of the X display, - * connect to X manually... */ - xdpy = XOpenDisplay (NULL); - if (!xdpy) - { - fprintf (stderr, "Failed to open X Display\n"); - return 1; - } - - /* Conceptually choose a GPU... */ - renderer = cogl_renderer_new (); - /* FIXME: This should conceptually be part of the configuration of - * a renderer. */ - cogl_renderer_xlib_set_foreign_display (renderer, xdpy); - if (!cogl_renderer_connect (renderer, &error)) - { - fprintf (stderr, "Failed to connect to a renderer: %s\n", - error->message); - } - - chain = cogl_swap_chain_new (); - cogl_swap_chain_set_has_alpha (chain, TRUE); - - /* Conceptually declare upfront the kinds of windows we anticipate - * creating so that when we configure the display pipeline we can avoid - * having an impedance miss-match between the format of windows and the - * format the display pipeline expects. */ - onscreen_template = cogl_onscreen_template_new (chain); - cogl_object_unref (chain); - - /* Conceptually setup a display pipeline */ - display = cogl_display_new (renderer, onscreen_template); - cogl_object_unref (renderer); - if (!cogl_display_setup (display, &error)) - { - fprintf (stderr, "Failed to setup a display pipeline: %s\n", - error->message); - return 1; - } - - ctx = cogl_context_new (display, &error); - if (!ctx) - { - fprintf (stderr, "Failed to create context: %s\n", error->message); - return 1; - } - /* Eventually we want to get rid of any "default context" but for now it's - * needed... */ - cogl_set_default_context (ctx); - - onscreen = cogl_onscreen_new (ctx, 640, 480); - - /* We want to test that Cogl can handle foreign X windows... */ - - visual = cogl_onscreen_x11_get_visual_xid (onscreen); - if (!visual) - { - fprintf (stderr, "Failed to query an X visual suitable for the " - "configured CoglOnscreen framebuffer\n"); - return 1; - } - - template.visualid = visual; - xvisinfo = XGetVisualInfo (xdpy, VisualIDMask, &template, &visinfos_count); - - /* window attributes */ - xattr.background_pixel = WhitePixel (xdpy, DefaultScreen (xdpy)); - xattr.border_pixel = 0; - xattr.colormap = XCreateColormap (xdpy, - DefaultRootWindow (xdpy), - xvisinfo->visual, - AllocNone); - mask = CWBorderPixel | CWColormap; - - xwin = XCreateWindow (xdpy, - DefaultRootWindow (xdpy), - 0, 0, - 800, 600, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - cogl_onscreen_x11_set_foreign_window_xid (onscreen, xwin, - update_cogl_x11_event_mask, - xdpy); - - fb = COGL_FRAMEBUFFER (onscreen); - /* Eventually there will be an implicit allocate on first use so this - * will become optional... */ - if (!cogl_framebuffer_allocate (fb, &error)) - { - fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message); - return 1; - } - - XMapWindow (xdpy, xwin); - - cogl_push_framebuffer (fb); - - cogl_set_source_color4f (1, 0, 0, 1); - for (;;) - { - cogl_rectangle (-1, 1, 1, -1); - cogl_framebuffer_swap_buffers (fb); - } - - return 0; -} diff --git a/clutter/cogl/pango/Makefile.am b/clutter/cogl/pango/Makefile.am deleted file mode 100644 index 89d2faf..0000000 --- a/clutter/cogl/pango/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -include $(top_srcdir)/build/autotools/Makefile.am.silent - -source_c = \ - cogl-pango-display-list.c \ - cogl-pango-fontmap.c \ - cogl-pango-render.c \ - cogl-pango-glyph-cache.c \ - cogl-pango-pipeline-cache.c - -source_h = cogl-pango.h - -source_h_priv = \ - cogl-pango-display-list.h \ - cogl-pango-private.h \ - cogl-pango-glyph-cache.h \ - cogl-pango-pipeline-cache.h - -if COGL_STANDALONE_BUILD -lib_LTLIBRARIES = libcoglpango.la -else -noinst_LTLIBRARIES = libcoglpango.la -endif - -libcoglpango_la_SOURCES = $(source_c) $(source_h) $(source_h_priv) -libcoglpango_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) -libcoglpango_la_LIBADD = $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) -if COGL_STANDALONE_BUILD -libcoglpango_la_LIBADD += $(top_builddir)/cogl/libcogl.la -libcoglpango_la_LDFLAGS = \ - -export-dynamic \ - -export-symbols-regex "^cogl.*" - -no-undefined \ - -version-info @COGL_LT_CURRENT@:@COGL_LT_REVISION@:@COGL_LT_AGE@ -endif - -INCLUDES = \ - -DG_DISABLE_SINGLE_INCLUDES \ - -DCLUTTER_COMPILATION \ - -DG_LOG_DOMAIN=\"CoglPango\" \ - -I$(top_srcdir) -if !COGL_STANDALONE_BUILD -INCLUDES += \ - -I$(top_srcdir)/clutter \ - -I$(top_srcdir)/clutter/cogl \ - -I$(top_builddir)/clutter \ - -I$(top_builddir)/clutter/cogl -endif - -if COGL_STANDALONE_BUILD -coglpangoheadersdir = $(includedir)/cogl/cogl -coglpangoheaders_HEADERS = $(source_h) -else -coglpangoheadersdir = $(includedir)/clutter-@CLUTTER_API_VERSION@/cogl -coglpangoheaders_HEADERS = $(source_h) -endif - diff --git a/clutter/cogl/pango/cogl-pango-display-list.c b/clutter/cogl/pango/cogl-pango-display-list.c deleted file mode 100644 index a79cf0f..0000000 --- a/clutter/cogl/pango/cogl-pango-display-list.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Neil Roberts - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "cogl-pango-display-list.h" - -typedef enum -{ - COGL_PANGO_DISPLAY_LIST_TEXTURE, - COGL_PANGO_DISPLAY_LIST_RECTANGLE, - COGL_PANGO_DISPLAY_LIST_TRAPEZOID -} CoglPangoDisplayListNodeType; - -typedef struct _CoglPangoDisplayListNode CoglPangoDisplayListNode; -typedef struct _CoglPangoDisplayListVertex CoglPangoDisplayListVertex; - -struct _CoglPangoDisplayList -{ - gboolean color_override; - CoglColor color; - GSList *nodes; - GSList *last_node; - CoglPangoPipelineCache *pipeline_cache; -}; - -struct _CoglPangoDisplayListNode -{ - CoglPangoDisplayListNodeType type; - - gboolean color_override; - CoglColor color; - - CoglPipeline *pipeline; - - union - { - struct - { - /* The texture to render these coords from */ - CoglHandle texture; - /* Array of vertex data to render out of this texture */ - GArray *verts; - /* A VBO representing those vertices */ - CoglHandle vertex_buffer; - } texture; - - struct - { - float x_1, y_1; - float x_2, y_2; - } rectangle; - - struct - { - float y_1; - float x_11; - float x_21; - float y_2; - float x_12; - float x_22; - } trapezoid; - } d; -}; - -struct _CoglPangoDisplayListVertex -{ - float x, y, t_x, t_y; -}; - -CoglPangoDisplayList * -_cogl_pango_display_list_new (CoglPangoPipelineCache *pipeline_cache) -{ - CoglPangoDisplayList *dl = g_slice_new0 (CoglPangoDisplayList); - - dl->pipeline_cache = pipeline_cache; - - return dl; -} - -static void -_cogl_pango_display_list_append_node (CoglPangoDisplayList *dl, - CoglPangoDisplayListNode *node) -{ - if (dl->last_node) - dl->last_node = dl->last_node->next = g_slist_prepend (NULL, node); - else - dl->last_node = dl->nodes = g_slist_prepend (NULL, node); -} - -void -_cogl_pango_display_list_set_color_override (CoglPangoDisplayList *dl, - const CoglColor *color) -{ - dl->color_override = TRUE; - dl->color = *color; -} - -void -_cogl_pango_display_list_remove_color_override (CoglPangoDisplayList *dl) -{ - dl->color_override = FALSE; -} - -void -_cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl, - CoglHandle texture, - float x_1, float y_1, - float x_2, float y_2, - float tx_1, float ty_1, - float tx_2, float ty_2) -{ - CoglPangoDisplayListNode *node; - CoglPangoDisplayListVertex *verts; - - /* Add to the last node if it is a texture node with the same - target texture */ - if (dl->last_node - && (node = dl->last_node->data)->type == COGL_PANGO_DISPLAY_LIST_TEXTURE - && node->d.texture.texture == texture - && (dl->color_override - ? (node->color_override && cogl_color_equal (&dl->color, &node->color)) - : !node->color_override)) - { - /* Get rid of the vertex buffer so that it will be recreated */ - if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE) - { - cogl_handle_unref (node->d.texture.vertex_buffer); - node->d.texture.vertex_buffer = COGL_INVALID_HANDLE; - } - } - else - { - /* Otherwise create a new node */ - node = g_slice_new (CoglPangoDisplayListNode); - - node->type = COGL_PANGO_DISPLAY_LIST_TEXTURE; - node->color_override = dl->color_override; - node->color = dl->color; - node->pipeline = NULL; - node->d.texture.texture = cogl_handle_ref (texture); - node->d.texture.verts - = g_array_new (FALSE, FALSE, sizeof (CoglPangoDisplayListVertex)); - node->d.texture.vertex_buffer = COGL_INVALID_HANDLE; - - _cogl_pango_display_list_append_node (dl, node); - } - - g_array_set_size (node->d.texture.verts, - node->d.texture.verts->len + 4); - verts = &g_array_index (node->d.texture.verts, - CoglPangoDisplayListVertex, - node->d.texture.verts->len - 4); - - verts->x = x_1; - verts->y = y_1; - verts->t_x = tx_1; - verts->t_y = ty_1; - verts++; - verts->x = x_1; - verts->y = y_2; - verts->t_x = tx_1; - verts->t_y = ty_2; - verts++; - verts->x = x_2; - verts->y = y_2; - verts->t_x = tx_2; - verts->t_y = ty_2; - verts++; - verts->x = x_2; - verts->y = y_1; - verts->t_x = tx_2; - verts->t_y = ty_1; -} - -void -_cogl_pango_display_list_add_rectangle (CoglPangoDisplayList *dl, - float x_1, float y_1, - float x_2, float y_2) -{ - CoglPangoDisplayListNode *node = g_slice_new (CoglPangoDisplayListNode); - - node->type = COGL_PANGO_DISPLAY_LIST_RECTANGLE; - node->color_override = dl->color_override; - node->color = dl->color; - node->d.rectangle.x_1 = x_1; - node->d.rectangle.y_1 = y_1; - node->d.rectangle.x_2 = x_2; - node->d.rectangle.y_2 = y_2; - node->pipeline = NULL; - - _cogl_pango_display_list_append_node (dl, node); -} - -void -_cogl_pango_display_list_add_trapezoid (CoglPangoDisplayList *dl, - float y_1, - float x_11, - float x_21, - float y_2, - float x_12, - float x_22) -{ - CoglPangoDisplayListNode *node = g_slice_new (CoglPangoDisplayListNode); - - node->type = COGL_PANGO_DISPLAY_LIST_TRAPEZOID; - node->color_override = dl->color_override; - node->color = dl->color; - node->d.trapezoid.y_1 = y_1; - node->d.trapezoid.x_11 = x_11; - node->d.trapezoid.x_21 = x_21; - node->d.trapezoid.y_2 = y_2; - node->d.trapezoid.x_12 = x_12; - node->d.trapezoid.x_22 = x_22; - node->pipeline = NULL; - - _cogl_pango_display_list_append_node (dl, node); -} - -static void -emit_rectangles_through_journal (CoglPangoDisplayListNode *node) -{ - int i; - - for (i = 0; i < node->d.texture.verts->len; i += 4) - { - CoglPangoDisplayListVertex *v0 = - &g_array_index (node->d.texture.verts, - CoglPangoDisplayListVertex, i); - CoglPangoDisplayListVertex *v1 = - &g_array_index (node->d.texture.verts, - CoglPangoDisplayListVertex, i + 2); - cogl_rectangle_with_texture_coords (v0->x, v0->y, v1->x, v1->y, - v0->t_x, v0->t_y, - v1->t_x, v1->t_y); - } -} - -static void -emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node) -{ - /* It's expensive to go through the Cogl journal for large runs - * of text in part because the journal transforms the quads in software - * to avoid changing the modelview matrix. So for larger runs of text - * we load the vertices into a VBO, and this has the added advantage - * that if the text doesn't change from frame to frame the VBO can - * be re-used avoiding the repeated cost of validating the data and - * mapping it into the GPU... */ - - if (node->d.texture.vertex_buffer == COGL_INVALID_HANDLE) - { - CoglHandle vb = cogl_vertex_buffer_new (node->d.texture.verts->len); - - cogl_vertex_buffer_add (vb, "gl_Vertex", 2, - COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, - sizeof (CoglPangoDisplayListVertex), - &g_array_index (node->d.texture.verts, - CoglPangoDisplayListVertex, 0).x); - cogl_vertex_buffer_add (vb, "gl_MultiTexCoord0", 2, - COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, - sizeof (CoglPangoDisplayListVertex), - &g_array_index (node->d.texture.verts, - CoglPangoDisplayListVertex, - 0).t_x); - cogl_vertex_buffer_submit (vb); - - node->d.texture.vertex_buffer = vb; - } - - -#ifdef CLUTTER_COGL_HAS_GL - - cogl_vertex_buffer_draw (node->d.texture.vertex_buffer, - GL_QUADS, - 0, node->d.texture.verts->len); - -#else /* CLUTTER_COGL_HAS_GL */ - { - /* GLES doesn't support GL_QUADS so instead we use a VBO with - indexed vertices to generate GL_TRIANGLES from the quads */ - - int n_indices = node->d.texture.verts->len / 4 * 6; - CoglHandle indices_vbo - = cogl_vertex_buffer_indices_get_for_quads (n_indices); - - cogl_vertex_buffer_draw_elements (node->d.texture.vertex_buffer, - COGL_VERTICES_MODE_TRIANGLES, - indices_vbo, - 0, node->d.texture.verts->len - 1, - 0, n_indices); - } -#endif /* CLUTTER_COGL_HAS_GL */ -} - -static void -_cogl_pango_display_list_render_texture (CoglPangoDisplayListNode *node) -{ - /* For small runs of text like icon labels, we can get better performance - * going through the Cogl journal since text may then be batched together - * with other geometry. */ - /* FIXME: 100 is a number I plucked out of thin air; it would be good - * to determine this empirically! */ - if (node->d.texture.verts->len < 100) - emit_rectangles_through_journal (node); - else - emit_vertex_buffer_geometry (node); -} - -void -_cogl_pango_display_list_render (CoglPangoDisplayList *dl, - const CoglColor *color) -{ - GSList *l; - - for (l = dl->nodes; l; l = l->next) - { - CoglPangoDisplayListNode *node = l->data; - CoglColor draw_color; - - if (node->pipeline == NULL) - { - if (node->type == COGL_PANGO_DISPLAY_LIST_TEXTURE) - node->pipeline = - _cogl_pango_pipeline_cache_get (dl->pipeline_cache, - node->d.texture.texture); - else - node->pipeline = - _cogl_pango_pipeline_cache_get (dl->pipeline_cache, - NULL); - } - - if (node->color_override) - /* Use the override color but preserve the alpha from the - draw color */ - cogl_color_init_from_4ub (&draw_color, - cogl_color_get_red_byte (&node->color), - cogl_color_get_green_byte (&node->color), - cogl_color_get_blue_byte (&node->color), - cogl_color_get_alpha_byte (color)); - else - draw_color = *color; - cogl_color_premultiply (&draw_color); - - cogl_pipeline_set_color (node->pipeline, &draw_color); - cogl_push_source (node->pipeline); - - switch (node->type) - { - case COGL_PANGO_DISPLAY_LIST_TEXTURE: - _cogl_pango_display_list_render_texture (node); - break; - - case COGL_PANGO_DISPLAY_LIST_RECTANGLE: - cogl_rectangle (node->d.rectangle.x_1, - node->d.rectangle.y_1, - node->d.rectangle.x_2, - node->d.rectangle.y_2); - break; - - case COGL_PANGO_DISPLAY_LIST_TRAPEZOID: - { - float points[8]; - CoglPath *path; - - points[0] = node->d.trapezoid.x_11; - points[1] = node->d.trapezoid.y_1; - points[2] = node->d.trapezoid.x_12; - points[3] = node->d.trapezoid.y_2; - points[4] = node->d.trapezoid.x_22; - points[5] = node->d.trapezoid.y_2; - points[6] = node->d.trapezoid.x_21; - points[7] = node->d.trapezoid.y_1; - - path = cogl_path_new (); - cogl_path_polygon (path, points, 4); - cogl_path_fill (path); - cogl_object_unref (path); - } - break; - } - - cogl_pop_source (); - } -} - -static void -_cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node) -{ - if (node->type == COGL_PANGO_DISPLAY_LIST_TEXTURE) - { - g_array_free (node->d.texture.verts, TRUE); - if (node->d.texture.texture != COGL_INVALID_HANDLE) - cogl_handle_unref (node->d.texture.texture); - if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE) - cogl_handle_unref (node->d.texture.vertex_buffer); - } - - if (node->pipeline) - cogl_object_unref (node->pipeline); - - g_slice_free (CoglPangoDisplayListNode, node); -} - -void -_cogl_pango_display_list_clear (CoglPangoDisplayList *dl) -{ - g_slist_foreach (dl->nodes, (GFunc) _cogl_pango_display_list_node_free, NULL); - g_slist_free (dl->nodes); - dl->nodes = NULL; - dl->last_node = NULL; -} - -void -_cogl_pango_display_list_free (CoglPangoDisplayList *dl) -{ - _cogl_pango_display_list_clear (dl); - g_slice_free (CoglPangoDisplayList, dl); -} diff --git a/clutter/cogl/pango/cogl-pango-display-list.h b/clutter/cogl/pango/cogl-pango-display-list.h deleted file mode 100644 index dd14edd..0000000 --- a/clutter/cogl/pango/cogl-pango-display-list.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Neil Roberts - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef __COGL_PANGO_DISPLAY_LIST_H__ -#define __COGL_PANGO_DISPLAY_LIST_H__ - -#include -#include -#include "cogl-pango-pipeline-cache.h" - -G_BEGIN_DECLS - -typedef struct _CoglPangoDisplayList CoglPangoDisplayList; - -CoglPangoDisplayList *_cogl_pango_display_list_new (CoglPangoPipelineCache *); - -void _cogl_pango_display_list_set_color_override (CoglPangoDisplayList *dl, - const CoglColor *color); -void _cogl_pango_display_list_remove_color_override (CoglPangoDisplayList *dl); - -void _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl, - CoglHandle texture, - float x_1, float y_1, - float x_2, float y_2, - float tx_1, float ty_1, - float tx_2, float ty_2); - -void _cogl_pango_display_list_add_rectangle (CoglPangoDisplayList *dl, - float x_1, float y_1, - float x_2, float y_2); - -void _cogl_pango_display_list_add_trapezoid (CoglPangoDisplayList *dl, - float y_1, - float x_11, - float x_21, - float y_2, - float x_12, - float x_22); - -void _cogl_pango_display_list_render (CoglPangoDisplayList *dl, - const CoglColor *color); - -void _cogl_pango_display_list_clear (CoglPangoDisplayList *dl); - -void _cogl_pango_display_list_free (CoglPangoDisplayList *dl); - -G_END_DECLS - -#endif /* __COGL_PANGO_DISPLAY_LIST_H__ */ diff --git a/clutter/cogl/pango/cogl-pango-fontmap.c b/clutter/cogl/pango/cogl-pango-fontmap.c deleted file mode 100644 index 1bee8f0..0000000 --- a/clutter/cogl/pango/cogl-pango-fontmap.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:cogl-pango - * @short_description: COGL-based text rendering using Pango - * - * FIXME - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* This is needed to get the Pango headers to export stuff needed to - subclass */ -#ifndef PANGO_ENABLE_BACKEND -#define PANGO_ENABLE_BACKEND 1 -#endif - -#include -#include -#include - -#include "cogl-pango.h" -#include "cogl-pango-private.h" - -static GQuark cogl_pango_font_map_get_renderer_key (void) G_GNUC_CONST; - -/** - * cogl_pango_font_map_new: - * - * Creates a new font map. - * - * Return value: the newly created #PangoFontMap - * - * Since: 1.0 - */ -PangoFontMap * -cogl_pango_font_map_new (void) -{ - return pango_cairo_font_map_new (); -} - -/** - * cogl_pango_font_map_create_context: - * @fm: a #CoglPangoFontMap - * - * Creates a new #PangoContext from the passed font map. - * - * Return value: the newly created #PangoContext - * - * Since: 1.0 - */ -PangoContext * -cogl_pango_font_map_create_context (CoglPangoFontMap *fm) -{ - g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (fm), NULL); - - /* We can just directly use the pango context from the Cairo font - map */ - return pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fm)); -} - -/** - * cogl_pango_font_map_get_renderer: - * @fm: a #CoglPangoFontMap - * - * Retrieves the #CoglPangoRenderer for the passed font map. - * - * Return value: a #PangoRenderer - * - * Since: 1.0 - */ -PangoRenderer * -cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm) -{ - PangoRenderer *renderer; - - g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (fm), NULL); - - /* We want to keep a cached pointer to the renderer from the font - map instance but as we don't have a proper subclass we have to - store it in the object data instead */ - - renderer = g_object_get_qdata (G_OBJECT (fm), - cogl_pango_font_map_get_renderer_key ()); - - if (G_UNLIKELY (renderer == NULL)) - { - renderer = g_object_new (COGL_PANGO_TYPE_RENDERER, NULL); - g_object_set_qdata_full (G_OBJECT (fm), - cogl_pango_font_map_get_renderer_key (), - renderer, - g_object_unref); - } - - return renderer; -} - -/** - * cogl_pango_font_map_set_resolution: - * @font_map: a #CoglPangoFontMap - * @dpi: DPI to set - * - * Sets the resolution to be used by @font_map at @dpi. - * - * Since: 1.0 - */ -void -cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, - double dpi) -{ - g_return_if_fail (COGL_PANGO_IS_FONT_MAP (font_map)); - - pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (font_map), dpi); -} - -/** - * cogl_pango_font_map_clear_glyph_cache: - * @fm: a #CoglPangoFontMap - * - * Clears the glyph cache for @fm. - * - * Since: 1.0 - */ -void -cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *fm) -{ - PangoRenderer *renderer; - - renderer = cogl_pango_font_map_get_renderer (fm); - - _cogl_pango_renderer_clear_glyph_cache (COGL_PANGO_RENDERER (renderer)); -} - -/** - * cogl_pango_font_map_set_use_mipmapping: - * @fm: a #CoglPangoFontMap - * @value: %TRUE to enable the use of mipmapping - * - * Sets whether the renderer for the passed font map should use - * mipmapping when rendering a #PangoLayout. - * - * Since: 1.0 - */ -void -cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *fm, - gboolean value) -{ - CoglPangoRenderer *renderer; - - renderer = COGL_PANGO_RENDERER (cogl_pango_font_map_get_renderer (fm)); - - _cogl_pango_renderer_set_use_mipmapping (renderer, value); -} - -/** - * cogl_pango_font_map_get_use_mipmapping: - * @fm: a #CoglPangoFontMap - * - * Retrieves whether the #CoglPangoRenderer used by @fm will - * use mipmapping when rendering the glyphs. - * - * Return value: %TRUE if mipmapping is used, %FALSE otherwise. - * - * Since: 1.0 - */ -gboolean -cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *fm) -{ - CoglPangoRenderer *renderer; - - renderer = COGL_PANGO_RENDERER (cogl_pango_font_map_get_renderer (fm)); - - return _cogl_pango_renderer_get_use_mipmapping (renderer); -} - -static GQuark -cogl_pango_font_map_get_renderer_key (void) -{ - static GQuark renderer_key = 0; - - if (G_UNLIKELY (renderer_key == 0)) - renderer_key = g_quark_from_static_string ("CoglPangoFontMap"); - - return renderer_key; -} diff --git a/clutter/cogl/pango/cogl-pango-glyph-cache.c b/clutter/cogl/pango/cogl-pango-glyph-cache.c deleted file mode 100644 index bbcfe8f..0000000 --- a/clutter/cogl/pango/cogl-pango-glyph-cache.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "cogl-pango-glyph-cache.h" -#include "cogl-pango-private.h" -#include "cogl/cogl-atlas.h" -#include "cogl/cogl-atlas-texture-private.h" - -typedef struct _CoglPangoGlyphCacheKey CoglPangoGlyphCacheKey; - -struct _CoglPangoGlyphCache -{ - /* Hash table to quickly check whether a particular glyph in a - particular font is already cached */ - GHashTable *hash_table; - - /* List of CoglAtlases */ - GSList *atlases; - - /* List of callbacks to invoke when an atlas is reorganized */ - GHookList reorganize_callbacks; - - /* TRUE if we've ever stored a texture in the global atlas. This is - used to make sure we only register one callback to listen for - global atlas reorganizations */ - gboolean using_global_atlas; - - /* True if some of the glyphs are dirty. This is used as an - optimization in _cogl_pango_glyph_cache_set_dirty_glyphs to avoid - iterating the hash table if we know none of them are dirty */ - gboolean has_dirty_glyphs; - - /* Whether mipmapping is being used for this cache. This only - affects whether we decide to put the glyph in the global atlas */ - gboolean use_mipmapping; -}; - -struct _CoglPangoGlyphCacheKey -{ - PangoFont *font; - PangoGlyph glyph; -}; - -static void -cogl_pango_glyph_cache_value_free (CoglPangoGlyphCacheValue *value) -{ - if (value->texture) - cogl_handle_unref (value->texture); - g_slice_free (CoglPangoGlyphCacheValue, value); -} - -static void -cogl_pango_glyph_cache_key_free (CoglPangoGlyphCacheKey *key) -{ - g_object_unref (key->font); - g_slice_free (CoglPangoGlyphCacheKey, key); -} - -static guint -cogl_pango_glyph_cache_hash_func (gconstpointer key) -{ - const CoglPangoGlyphCacheKey *cache_key - = (const CoglPangoGlyphCacheKey *) key; - - /* Generate a number affected by both the font and the glyph - number. We can safely directly compare the pointers because the - key holds a reference to the font so it is not possible that a - different font will have the same memory address */ - return GPOINTER_TO_UINT (cache_key->font) ^ cache_key->glyph; -} - -static gboolean -cogl_pango_glyph_cache_equal_func (gconstpointer a, - gconstpointer b) -{ - const CoglPangoGlyphCacheKey *key_a - = (const CoglPangoGlyphCacheKey *) a; - const CoglPangoGlyphCacheKey *key_b - = (const CoglPangoGlyphCacheKey *) b; - - /* We can safely directly compare the pointers for the fonts because - the key holds a reference to the font so it is not possible that - a different font will have the same memory address */ - return key_a->font == key_b->font - && key_a->glyph == key_b->glyph; -} - -CoglPangoGlyphCache * -cogl_pango_glyph_cache_new (gboolean use_mipmapping) -{ - CoglPangoGlyphCache *cache; - - cache = g_malloc (sizeof (CoglPangoGlyphCache)); - - cache->hash_table = g_hash_table_new_full - (cogl_pango_glyph_cache_hash_func, - cogl_pango_glyph_cache_equal_func, - (GDestroyNotify) cogl_pango_glyph_cache_key_free, - (GDestroyNotify) cogl_pango_glyph_cache_value_free); - - cache->atlases = NULL; - g_hook_list_init (&cache->reorganize_callbacks, sizeof (GHook)); - - cache->has_dirty_glyphs = FALSE; - - cache->use_mipmapping = use_mipmapping; - - return cache; -} - -static void -cogl_pango_glyph_cache_reorganize_cb (void *user_data) -{ - CoglPangoGlyphCache *cache = user_data; - - g_hook_list_invoke (&cache->reorganize_callbacks, FALSE); -} - -void -cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache) -{ - g_slist_foreach (cache->atlases, (GFunc) cogl_object_unref, NULL); - g_slist_free (cache->atlases); - cache->atlases = NULL; - cache->has_dirty_glyphs = FALSE; - - g_hash_table_remove_all (cache->hash_table); -} - -void -cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache) -{ - if (cache->using_global_atlas) - _cogl_atlas_texture_remove_reorganize_callback - (cogl_pango_glyph_cache_reorganize_cb, cache); - - cogl_pango_glyph_cache_clear (cache); - - g_hash_table_unref (cache->hash_table); - - g_hook_list_clear (&cache->reorganize_callbacks); - - g_free (cache); -} - -static void -cogl_pango_glyph_cache_update_position_cb (void *user_data, - CoglHandle new_texture, - const CoglRectangleMapEntry *rect) -{ - CoglPangoGlyphCacheValue *value = user_data; - float tex_width, tex_height; - - if (value->texture) - cogl_handle_unref (value->texture); - value->texture = cogl_handle_ref (new_texture); - - tex_width = cogl_texture_get_width (new_texture); - tex_height = cogl_texture_get_height (new_texture); - - value->tx1 = rect->x / tex_width; - value->ty1 = rect->y / tex_height; - value->tx2 = (rect->x + value->draw_width) / tex_width; - value->ty2 = (rect->y + value->draw_height) / tex_height; - - value->tx_pixel = rect->x; - value->ty_pixel = rect->y; - - /* The glyph has changed position so it will need to be redrawn */ - value->dirty = TRUE; -} - -static gboolean -cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache, - PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value) -{ - CoglHandle texture; - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SHARED_ATLAS)) - return FALSE; - - /* If the cache is using mipmapping then we can't use the global - atlas because it would just get migrated back out */ - if (cache->use_mipmapping) - return FALSE; - - texture = _cogl_atlas_texture_new_with_size (value->draw_width, - value->draw_height, - COGL_TEXTURE_NONE, - COGL_PIXEL_FORMAT_RGBA_8888_PRE); - - if (texture == COGL_INVALID_HANDLE) - return FALSE; - - value->texture = texture; - value->tx1 = 0; - value->ty1 = 0; - value->tx2 = 1; - value->ty2 = 1; - value->tx_pixel = 0; - value->ty_pixel = 0; - - /* The first time we store a texture in the global atlas we'll - register for notifications when the global atlas is reorganized - so we can forward the notification on as a glyph - reorganization */ - if (!cache->using_global_atlas) - { - _cogl_atlas_texture_add_reorganize_callback - (cogl_pango_glyph_cache_reorganize_cb, cache); - cache->using_global_atlas = TRUE; - } - - return TRUE; -} - -static gboolean -cogl_pango_glyph_cache_add_to_local_atlas (CoglPangoGlyphCache *cache, - PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value) -{ - CoglAtlas *atlas = NULL; - GSList *l; - - /* Look for an atlas that can reserve the space */ - for (l = cache->atlases; l; l = l->next) - if (_cogl_atlas_reserve_space (l->data, - value->draw_width + 1, - value->draw_height + 1, - value)) - { - atlas = l->data; - break; - } - - /* If we couldn't find one then start a new atlas */ - if (atlas == NULL) - { - atlas = _cogl_atlas_new (COGL_PIXEL_FORMAT_A_8, - COGL_ATLAS_CLEAR_TEXTURE | - COGL_ATLAS_DISABLE_MIGRATION, - cogl_pango_glyph_cache_update_position_cb); - COGL_NOTE (ATLAS, "Created new atlas for glyphs: %p", atlas); - /* If we still can't reserve space then something has gone - seriously wrong so we'll just give up */ - if (!_cogl_atlas_reserve_space (atlas, - value->draw_width + 1, - value->draw_height + 1, - value)) - { - cogl_object_unref (atlas); - return FALSE; - } - - _cogl_atlas_add_reorganize_callback - (atlas, cogl_pango_glyph_cache_reorganize_cb, NULL, cache); - - cache->atlases = g_slist_prepend (cache->atlases, atlas); - } - - return TRUE; -} - -CoglPangoGlyphCacheValue * -cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, - gboolean create, - PangoFont *font, - PangoGlyph glyph) -{ - CoglPangoGlyphCacheKey lookup_key; - CoglPangoGlyphCacheValue *value; - - lookup_key.font = font; - lookup_key.glyph = glyph; - - value = g_hash_table_lookup (cache->hash_table, &lookup_key); - - if (create && value == NULL) - { - CoglPangoGlyphCacheKey *key; - PangoRectangle ink_rect; - - value = g_slice_new (CoglPangoGlyphCacheValue); - value->texture = COGL_INVALID_HANDLE; - - pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL); - pango_extents_to_pixels (&ink_rect, NULL); - - value->draw_x = ink_rect.x; - value->draw_y = ink_rect.y; - value->draw_width = ink_rect.width; - value->draw_height = ink_rect.height; - - /* If the glyph is zero-sized then we don't need to reserve any - space for it and we can just avoid painting anything */ - if (ink_rect.width < 1 || ink_rect.height < 1) - value->dirty = FALSE; - else - { - /* Try adding the glyph to the global atlas... */ - if (!cogl_pango_glyph_cache_add_to_global_atlas (cache, - font, - glyph, - value) && - /* If it fails try the local atlas */ - !cogl_pango_glyph_cache_add_to_local_atlas (cache, - font, - glyph, - value)) - { - cogl_pango_glyph_cache_value_free (value); - return NULL; - } - - value->dirty = TRUE; - cache->has_dirty_glyphs = TRUE; - } - - key = g_slice_new (CoglPangoGlyphCacheKey); - key->font = g_object_ref (font); - key->glyph = glyph; - - g_hash_table_insert (cache->hash_table, key, value); - } - - return value; -} - -static void -_cogl_pango_glyph_cache_set_dirty_glyphs_cb (gpointer key_ptr, - gpointer value_ptr, - gpointer user_data) -{ - CoglPangoGlyphCacheKey *key = key_ptr; - CoglPangoGlyphCacheValue *value = value_ptr; - CoglPangoGlyphCacheDirtyFunc func = user_data; - - if (value->dirty) - { - func (key->font, key->glyph, value); - - value->dirty = FALSE; - } -} - -void -_cogl_pango_glyph_cache_set_dirty_glyphs (CoglPangoGlyphCache *cache, - CoglPangoGlyphCacheDirtyFunc func) -{ - /* If we know that there are no dirty glyphs then we can shortcut - out early */ - if (!cache->has_dirty_glyphs) - return; - - g_hash_table_foreach (cache->hash_table, - _cogl_pango_glyph_cache_set_dirty_glyphs_cb, - func); - - cache->has_dirty_glyphs = FALSE; -} - -void -_cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data) -{ - GHook *hook = g_hook_alloc (&cache->reorganize_callbacks); - hook->func = func; - hook->data = user_data; - g_hook_prepend (&cache->reorganize_callbacks, hook); -} - -void -_cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data) -{ - GHook *hook = g_hook_find_func_data (&cache->reorganize_callbacks, - FALSE, - func, - user_data); - - if (hook) - g_hook_destroy_link (&cache->reorganize_callbacks, hook); -} diff --git a/clutter/cogl/pango/cogl-pango-glyph-cache.h b/clutter/cogl/pango/cogl-pango-glyph-cache.h deleted file mode 100644 index 2020447..0000000 --- a/clutter/cogl/pango/cogl-pango-glyph-cache.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef __COGL_PANGO_GLYPH_CACHE_H__ -#define __COGL_PANGO_GLYPH_CACHE_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -typedef struct _CoglPangoGlyphCache CoglPangoGlyphCache; -typedef struct _CoglPangoGlyphCacheValue CoglPangoGlyphCacheValue; - -struct _CoglPangoGlyphCacheValue -{ - CoglHandle texture; - - float tx1; - float ty1; - float tx2; - float ty2; - - int tx_pixel; - int ty_pixel; - - int draw_x; - int draw_y; - int draw_width; - int draw_height; - - /* This will be set to TRUE when the glyph atlas is reorganized - which means the glyph will need to be redrawn */ - gboolean dirty; -}; - -typedef void (* CoglPangoGlyphCacheDirtyFunc) (PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value); - -CoglPangoGlyphCache * -cogl_pango_glyph_cache_new (gboolean use_mipmapping); - -void -cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache); - -CoglPangoGlyphCacheValue * -cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, - gboolean create, - PangoFont *font, - PangoGlyph glyph); - -void -cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache); - -void -_cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data); - -void -_cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache, - GHookFunc func, - void *user_data); - -void -_cogl_pango_glyph_cache_set_dirty_glyphs (CoglPangoGlyphCache *cache, - CoglPangoGlyphCacheDirtyFunc func); - -G_END_DECLS - -#endif /* __COGL_PANGO_GLYPH_CACHE_H__ */ diff --git a/clutter/cogl/pango/cogl-pango-pipeline-cache.c b/clutter/cogl/pango/cogl-pango-pipeline-cache.c deleted file mode 100644 index 5f6a5a0..0000000 --- a/clutter/cogl/pango/cogl-pango-pipeline-cache.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "cogl-pango-pipeline-cache.h" - -typedef struct _CoglPangoPipelineCacheEntry CoglPangoPipelineCacheEntry; - -struct _CoglPangoPipelineCache -{ - GHashTable *hash_table; - - CoglPipeline *base_texture_alpha_pipeline; - CoglPipeline *base_texture_rgba_pipeline; - - gboolean use_mipmapping; -}; - -struct _CoglPangoPipelineCacheEntry -{ - /* This will take a reference or it can be NULL to represent the - pipeline used to render colors */ - CoglHandle texture; - - /* This will only take a weak reference */ - CoglHandle pipeline; -}; - -static void -_cogl_pango_pipeline_cache_key_destroy (gpointer data) -{ - if (data) - cogl_object_unref (data); -} - -static void -_cogl_pango_pipeline_cache_value_destroy (gpointer data) -{ - CoglPangoPipelineCacheEntry *cache_entry = data; - - if (cache_entry->texture) - cogl_object_unref (cache_entry->texture); - - /* We don't need to unref the pipeline because it only takes a weak - reference */ - - g_slice_free (CoglPangoPipelineCacheEntry, cache_entry); -} - -CoglPangoPipelineCache * -_cogl_pango_pipeline_cache_new (gboolean use_mipmapping) -{ - CoglPangoPipelineCache *cache = g_new (CoglPangoPipelineCache, 1); - - /* The key is the pipeline pointer. A reference is taken when the - pipeline is used as a key so we should unref it again in the - destroy function */ - cache->hash_table = - g_hash_table_new_full (g_direct_hash, - g_direct_equal, - _cogl_pango_pipeline_cache_key_destroy, - _cogl_pango_pipeline_cache_value_destroy); - - cache->base_texture_rgba_pipeline = NULL; - cache->base_texture_alpha_pipeline = NULL; - - cache->use_mipmapping = use_mipmapping; - - return cache; -} - -static CoglPipeline * -get_base_texture_rgba_pipeline (CoglPangoPipelineCache *cache) -{ - if (cache->base_texture_rgba_pipeline == NULL) - { - CoglPipeline *pipeline; - - pipeline = cache->base_texture_rgba_pipeline = cogl_pipeline_new (); - - cogl_pipeline_set_layer_wrap_mode (pipeline, 0, - COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); - - if (cache->use_mipmapping) - cogl_pipeline_set_layer_filters - (pipeline, 0, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, - COGL_PIPELINE_FILTER_LINEAR); - } - - return cache->base_texture_rgba_pipeline; -} - -static CoglPipeline * -get_base_texture_alpha_pipeline (CoglPangoPipelineCache *cache) -{ - if (cache->base_texture_alpha_pipeline == NULL) - { - CoglPipeline *pipeline; - - pipeline = cogl_pipeline_copy (get_base_texture_rgba_pipeline (cache)); - cache->base_texture_alpha_pipeline = pipeline; - - /* The default combine mode of materials is to modulate (A x B) - * the texture RGBA channels with the RGBA channels of the - * previous layer (which in our case is just the font color) - * - * Since the RGB for an alpha texture is defined as 0, this gives us: - * - * result.rgb = color.rgb * 0 - * result.a = color.a * texture.a - * - * What we want is premultiplied rgba values: - * - * result.rgba = color.rgb * texture.a - * result.a = color.a * texture.a - */ - cogl_pipeline_set_layer_combine (pipeline, 0, /* layer */ - "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", - NULL); - } - - return cache->base_texture_alpha_pipeline; -} - -typedef struct -{ - CoglPangoPipelineCache *cache; - CoglHandle texture; -} PipelineDestroyNotifyData; - -static void -pipeline_destroy_notify_cb (void *user_data) -{ - PipelineDestroyNotifyData *data = user_data; - - g_hash_table_remove (data->cache->hash_table, data->texture); - g_slice_free (PipelineDestroyNotifyData, data); -} - -CoglPipeline * -_cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, - CoglHandle texture) -{ - CoglPangoPipelineCacheEntry *entry; - PipelineDestroyNotifyData *destroy_data; - static CoglUserDataKey pipeline_destroy_notify_key; - - /* Look for an existing entry */ - entry = g_hash_table_lookup (cache->hash_table, texture); - - if (entry) - return cogl_object_ref (entry->pipeline); - - /* No existing pipeline was found so let's create another */ - entry = g_slice_new (CoglPangoPipelineCacheEntry); - - if (texture) - { - CoglPipeline *base; - - entry->texture = cogl_handle_ref (texture); - - if (cogl_texture_get_format (entry->texture) == COGL_PIXEL_FORMAT_A_8) - base = get_base_texture_alpha_pipeline (cache); - else - base = get_base_texture_rgba_pipeline (cache); - - entry->pipeline = cogl_pipeline_copy (base); - - cogl_pipeline_set_layer_texture (entry->pipeline, 0 /* layer */, texture); - } - else - { - entry->texture = NULL; - entry->pipeline = cogl_pipeline_new (); - } - - /* Add a weak reference to the pipeline so we can remove it from the - hash table when it is destroyed */ - destroy_data = g_slice_new (PipelineDestroyNotifyData); - destroy_data->cache = cache; - destroy_data->texture = texture; - cogl_object_set_user_data (entry->pipeline, - &pipeline_destroy_notify_key, - destroy_data, - pipeline_destroy_notify_cb); - - g_hash_table_insert (cache->hash_table, - texture ? cogl_handle_ref (texture) : NULL, - entry); - - /* This doesn't take a reference on the pipeline so that it will use - the newly created reference */ - return entry->pipeline; -} - -void -_cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache) -{ - if (cache->base_texture_rgba_pipeline) - cogl_object_unref (cache->base_texture_rgba_pipeline); - if (cache->base_texture_alpha_pipeline) - cogl_object_unref (cache->base_texture_alpha_pipeline); - - g_hash_table_destroy (cache->hash_table); - - g_free (cache); -} diff --git a/clutter/cogl/pango/cogl-pango-pipeline-cache.h b/clutter/cogl/pango/cogl-pango-pipeline-cache.h deleted file mode 100644 index d095c58..0000000 --- a/clutter/cogl/pango/cogl-pango-pipeline-cache.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * An object oriented GL/GLES Abstraction/Utility Layer - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_PANGO_PIPELINE_CACHE_H__ -#define __COGL_PANGO_PIPELINE_CACHE_H__ - -#include -#include - -G_BEGIN_DECLS - -typedef struct _CoglPangoPipelineCache CoglPangoPipelineCache; - -CoglPangoPipelineCache * -_cogl_pango_pipeline_cache_new (gboolean use_mipmapping); - -/* Returns a pipeline that can be used to render glyphs in the given - texture. The pipeline has a new reference so it is up to the caller - to unref it */ -CoglPipeline * -_cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, - CoglHandle texture); - -void -_cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache); - -G_END_DECLS - -#endif /* __COGL_PANGO_PIPELINE_CACHE_H__ */ diff --git a/clutter/cogl/pango/cogl-pango-private.h b/clutter/cogl/pango/cogl-pango-private.h deleted file mode 100644 index 447e853..0000000 --- a/clutter/cogl/pango/cogl-pango-private.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef __COGL_PANGO_PRIVATE_H__ -#define __COGL_PANGO_PRIVATE_H__ - -#include "cogl-pango.h" - -G_BEGIN_DECLS - -void _cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer); -void _cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, - gboolean value); -gboolean _cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer); - -G_END_DECLS - -#endif /* __COGL_PANGO_PRIVATE_H__ */ diff --git a/clutter/cogl/pango/cogl-pango-render.c b/clutter/cogl/pango/cogl-pango-render.c deleted file mode 100644 index 72cfbcb..0000000 --- a/clutter/cogl/pango/cogl-pango-render.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef PANGO_ENABLE_BACKEND -#define PANGO_ENABLE_BACKEND 1 -#endif - -#include -#include -#include -#include - -#include "cogl/cogl-debug.h" -#include "cogl/cogl-texture-private.h" -#include "cogl-pango-private.h" -#include "cogl-pango-glyph-cache.h" -#include "cogl-pango-display-list.h" - -struct _CoglPangoRenderer -{ - PangoRenderer parent_instance; - - /* Two caches of glyphs as textures, one with mipmapped textures and - one without */ - CoglPangoGlyphCache *glyph_cache; - CoglPangoGlyphCache *mipmapped_glyph_cache; - - CoglPangoPipelineCache *pipeline_cache; - CoglPangoPipelineCache *mipmapped_pipeline_cache; - - gboolean use_mipmapping; - - /* The current display list that is being built */ - CoglPangoDisplayList *display_list; -}; - -struct _CoglPangoRendererClass -{ - PangoRendererClass class_instance; -}; - -typedef struct _CoglPangoRendererQdata CoglPangoRendererQdata; - -/* An instance of this struct gets attached to each PangoLayout to - cache the VBO and to detect changes to the layout */ -struct _CoglPangoRendererQdata -{ - CoglPangoRenderer *renderer; - /* The cache of the geometry for the layout */ - CoglPangoDisplayList *display_list; - /* A reference to the first line of the layout. This is just used to - detect changes */ - PangoLayoutLine *first_line; - /* Whether mipmapping was previously used to render this layout. We - need to regenerate the display list if the mipmapping value is - changed because it will be using a different set of textures */ - gboolean mipmapping_used; -}; - -static void -_cogl_pango_ensure_glyph_cache_for_layout_line (PangoLayoutLine *line); - -typedef struct -{ - CoglPangoDisplayList *display_list; - float x1, y1, x2, y2; -} CoglPangoRendererSliceCbData; - -void -cogl_pango_renderer_slice_cb (CoglHandle handle, - const float *slice_coords, - const float *virtual_coords, - void *user_data) -{ - CoglPangoRendererSliceCbData *data = user_data; - - /* Note: this assumes that there is only one slice containing the - whole texture and it doesn't attempt to split up the vertex - coordinates based on the virtual_coords */ - - _cogl_pango_display_list_add_texture (data->display_list, - handle, - data->x1, - data->y1, - data->x2, - data->y2, - slice_coords[0], - slice_coords[1], - slice_coords[2], - slice_coords[3]); -} - -static void -cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, - CoglPangoGlyphCacheValue *cache_value, - float x1, - float y1) -{ - CoglPangoRendererSliceCbData data; - - g_return_if_fail (priv->display_list != NULL); - - data.display_list = priv->display_list; - data.x1 = x1; - data.y1 = y1; - data.x2 = x1 + (float) cache_value->draw_width; - data.y2 = y1 + (float) cache_value->draw_height; - - /* We iterate the internal sub textures of the texture so that we - can get a pointer to the base texture even if the texture is in - the global atlas. That way the display list can recognise that - the neighbouring glyphs are coming from the same atlas and bundle - them together into a single VBO */ - - _cogl_texture_foreach_sub_texture_in_region (cache_value->texture, - cache_value->tx1, - cache_value->ty1, - cache_value->tx2, - cache_value->ty2, - cogl_pango_renderer_slice_cb, - &data); -} - -static void cogl_pango_renderer_finalize (GObject *object); -static void cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, - PangoFont *font, - PangoGlyphString *glyphs, - int x, - int y); -static void cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, - PangoRenderPart part, - int x, - int y, - int width, - int height); -static void cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, - PangoRenderPart part, - double y1, - double x11, - double x21, - double y2, - double x12, - double x22); - -G_DEFINE_TYPE (CoglPangoRenderer, cogl_pango_renderer, PANGO_TYPE_RENDERER); - -static void -cogl_pango_renderer_init (CoglPangoRenderer *priv) -{ - priv->pipeline_cache = _cogl_pango_pipeline_cache_new (FALSE); - priv->mipmapped_pipeline_cache = _cogl_pango_pipeline_cache_new (TRUE); - priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE); - priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE); - priv->use_mipmapping = TRUE; - _cogl_pango_renderer_set_use_mipmapping (priv, FALSE); -} - -static void -cogl_pango_renderer_class_init (CoglPangoRendererClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass); - - object_class->finalize = cogl_pango_renderer_finalize; - - renderer_class->draw_glyphs = cogl_pango_renderer_draw_glyphs; - renderer_class->draw_rectangle = cogl_pango_renderer_draw_rectangle; - renderer_class->draw_trapezoid = cogl_pango_renderer_draw_trapezoid; -} - -static void -cogl_pango_renderer_finalize (GObject *object) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (object); - - cogl_pango_glyph_cache_free (priv->mipmapped_glyph_cache); - cogl_pango_glyph_cache_free (priv->glyph_cache); - - _cogl_pango_pipeline_cache_free (priv->pipeline_cache); - _cogl_pango_pipeline_cache_free (priv->mipmapped_pipeline_cache); - - G_OBJECT_CLASS (cogl_pango_renderer_parent_class)->finalize (object); -} - -static CoglPangoRenderer * -cogl_pango_get_renderer_from_context (PangoContext *context) -{ - PangoFontMap *font_map; - PangoRenderer *renderer; - CoglPangoFontMap *font_map_priv; - - font_map = pango_context_get_font_map (context); - g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (font_map), NULL); - - font_map_priv = COGL_PANGO_FONT_MAP (font_map); - renderer = cogl_pango_font_map_get_renderer (font_map_priv); - g_return_val_if_fail (COGL_PANGO_IS_RENDERER (renderer), NULL); - - return COGL_PANGO_RENDERER (renderer); -} - -static GQuark -cogl_pango_render_get_qdata_key (void) -{ - static GQuark key = 0; - - if (G_UNLIKELY (key == 0)) - key = g_quark_from_static_string ("CoglPangoDisplayList"); - - return key; -} - -static void -cogl_pango_render_qdata_forget_display_list (CoglPangoRendererQdata *qdata) -{ - if (qdata->display_list) - { - _cogl_pango_glyph_cache_remove_reorganize_callback - (qdata->renderer->glyph_cache, - (GHookFunc) cogl_pango_render_qdata_forget_display_list, - qdata); - - _cogl_pango_display_list_free (qdata->display_list); - - qdata->display_list = NULL; - } -} - -static void -cogl_pango_render_qdata_destroy (CoglPangoRendererQdata *qdata) -{ - cogl_pango_render_qdata_forget_display_list (qdata); - if (qdata->first_line) - pango_layout_line_unref (qdata->first_line); - g_slice_free (CoglPangoRendererQdata, qdata); -} - -/** - * cogl_pango_render_layout_subpixel: - * @layout: a #PangoLayout - * @x: FIXME - * @y: FIXME - * @color: color to use when rendering the layout - * @flags: flags to pass to the renderer - * - * FIXME - * - * Since: 1.0 - */ -void -cogl_pango_render_layout_subpixel (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags) -{ - PangoContext *context; - CoglPangoRenderer *priv; - CoglPangoRendererQdata *qdata; - - context = pango_layout_get_context (layout); - priv = cogl_pango_get_renderer_from_context (context); - if (G_UNLIKELY (!priv)) - return; - - qdata = g_object_get_qdata (G_OBJECT (layout), - cogl_pango_render_get_qdata_key ()); - - if (qdata == NULL) - { - qdata = g_slice_new0 (CoglPangoRendererQdata); - qdata->renderer = priv; - g_object_set_qdata_full (G_OBJECT (layout), - cogl_pango_render_get_qdata_key (), - qdata, - (GDestroyNotify) - cogl_pango_render_qdata_destroy); - } - - /* Check if the layout has changed since the last build of the - display list. This trick was suggested by Behdad Esfahbod here: - http://mail.gnome.org/archives/gtk-i18n-list/2009-May/msg00019.html */ - if (qdata->display_list && - ((qdata->first_line && - qdata->first_line->layout != layout) || - qdata->mipmapping_used != priv->use_mipmapping)) - cogl_pango_render_qdata_forget_display_list (qdata); - - if (qdata->display_list == NULL) - { - CoglPangoPipelineCache *pipeline_cache = - (priv->use_mipmapping ? - priv->mipmapped_pipeline_cache : priv->pipeline_cache); - - cogl_pango_ensure_glyph_cache_for_layout (layout); - - qdata->display_list = _cogl_pango_display_list_new (pipeline_cache); - - /* Register for notification of when the glyph cache changes so - we can rebuild the display list */ - _cogl_pango_glyph_cache_add_reorganize_callback - (priv->glyph_cache, - (GHookFunc) cogl_pango_render_qdata_forget_display_list, - qdata); - - priv->display_list = qdata->display_list; - pango_renderer_draw_layout (PANGO_RENDERER (priv), layout, 0, 0); - priv->display_list = NULL; - - qdata->mipmapping_used = priv->use_mipmapping; - } - - cogl_push_matrix (); - cogl_translate (x / (gfloat) PANGO_SCALE, y / (gfloat) PANGO_SCALE, 0); - _cogl_pango_display_list_render (qdata->display_list, - color); - cogl_pop_matrix (); - - /* Keep a reference to the first line of the layout so we can detect - changes */ - if (qdata->first_line) - { - pango_layout_line_unref (qdata->first_line); - qdata->first_line = NULL; - } - if (pango_layout_get_line_count (layout) > 0) - { - qdata->first_line = pango_layout_get_line (layout, 0); - pango_layout_line_ref (qdata->first_line); - } -} - -/** - * cogl_pango_render_layout: - * @layout: a #PangoLayout - * @x: X coordinate to render the layout at - * @y: Y coordinate to render the layout at - * @color: color to use when rendering the layout - * @flags: flags to pass to the renderer - * - * Renders @layout. - * - * Since: 1.0 - */ -void -cogl_pango_render_layout (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags) -{ - cogl_pango_render_layout_subpixel (layout, - x * PANGO_SCALE, - y * PANGO_SCALE, - color, - flags); -} - -/** - * cogl_pango_render_layout_line: - * @line: a #PangoLayoutLine - * @x: X coordinate to render the line at - * @y: Y coordinate to render the line at - * @color: color to use when rendering the line - * - * Renders @line at the given coordinates using the given color. - * - * Since: 1.0 - */ -void -cogl_pango_render_layout_line (PangoLayoutLine *line, - int x, - int y, - const CoglColor *color) -{ - PangoContext *context; - CoglPangoRenderer *priv; - CoglPangoPipelineCache *pipeline_cache; - - context = pango_layout_get_context (line->layout); - priv = cogl_pango_get_renderer_from_context (context); - if (G_UNLIKELY (!priv)) - return; - - pipeline_cache = (priv->use_mipmapping ? - priv->mipmapped_pipeline_cache : priv->pipeline_cache); - - priv->display_list = _cogl_pango_display_list_new (pipeline_cache); - - _cogl_pango_ensure_glyph_cache_for_layout_line (line); - - pango_renderer_draw_layout_line (PANGO_RENDERER (priv), line, x, y); - - _cogl_pango_display_list_render (priv->display_list, - color); - - _cogl_pango_display_list_free (priv->display_list); - priv->display_list = NULL; -} - -void -_cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer) -{ - cogl_pango_glyph_cache_clear (renderer->glyph_cache); - cogl_pango_glyph_cache_clear (renderer->mipmapped_glyph_cache); -} - -void -_cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, - gboolean value) -{ - renderer->use_mipmapping = value; -} - -gboolean -_cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer) -{ - return renderer->use_mipmapping; -} - -static CoglPangoGlyphCacheValue * -cogl_pango_renderer_get_cached_glyph (PangoRenderer *renderer, - gboolean create, - PangoFont *font, - PangoGlyph glyph) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - CoglPangoGlyphCache *glyph_cache; - - glyph_cache = (priv->use_mipmapping ? - priv->mipmapped_glyph_cache : - priv->glyph_cache); - - return cogl_pango_glyph_cache_lookup (glyph_cache, create, font, glyph); -} - -static void -cogl_pango_renderer_set_dirty_glyph (PangoFont *font, - PangoGlyph glyph, - CoglPangoGlyphCacheValue *value) -{ - cairo_surface_t *surface; - cairo_t *cr; - cairo_scaled_font_t *scaled_font; - cairo_glyph_t cairo_glyph; - cairo_format_t format_cairo; - CoglPixelFormat format_cogl; - - COGL_NOTE (PANGO, "redrawing glyph %i", glyph); - - /* Glyphs that don't take up any space will end up without a - texture. These should never become dirty so they shouldn't end up - here */ - g_return_if_fail (value->texture != COGL_INVALID_HANDLE); - - if (cogl_texture_get_format (value->texture) == COGL_PIXEL_FORMAT_A_8) - { - format_cairo = CAIRO_FORMAT_A8; - format_cogl = COGL_PIXEL_FORMAT_A_8; - } - else - { - format_cairo = CAIRO_FORMAT_ARGB32; - - /* Cairo stores the data in native byte order as ARGB but Cogl's - pixel formats specify the actual byte order. Therefore we - need to use a different format depending on the - architecture */ -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - format_cogl = COGL_PIXEL_FORMAT_BGRA_8888_PRE; -#else - format_cogl = COGL_PIXEL_FORMAT_ARGB_8888_PRE; -#endif - } - - surface = cairo_image_surface_create (format_cairo, - value->draw_width, - value->draw_height); - cr = cairo_create (surface); - - scaled_font = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font)); - cairo_set_scaled_font (cr, scaled_font); - - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); - - cairo_glyph.x = -value->draw_x; - cairo_glyph.y = -value->draw_y; - /* The PangoCairo glyph numbers directly map to Cairo glyph - numbers */ - cairo_glyph.index = glyph; - cairo_show_glyphs (cr, &cairo_glyph, 1); - - cairo_destroy (cr); - cairo_surface_flush (surface); - - /* Copy the glyph to the texture */ - cogl_texture_set_region (value->texture, - 0, /* src_x */ - 0, /* src_y */ - value->tx_pixel, /* dst_x */ - value->ty_pixel, /* dst_y */ - value->draw_width, /* dst_width */ - value->draw_height, /* dst_height */ - value->draw_width, /* width */ - value->draw_height, /* height */ - format_cogl, - cairo_image_surface_get_stride (surface), - cairo_image_surface_get_data (surface)); - - cairo_surface_destroy (surface); -} - -static void -_cogl_pango_ensure_glyph_cache_for_layout_line_internal (PangoLayoutLine *line) -{ - PangoContext *context; - PangoRenderer *renderer; - GSList *l; - - context = pango_layout_get_context (line->layout); - renderer = - PANGO_RENDERER (cogl_pango_get_renderer_from_context (context)); - - for (l = line->runs; l; l = l->next) - { - PangoLayoutRun *run = l->data; - PangoGlyphString *glyphs = run->glyphs; - int i; - - for (i = 0; i < glyphs->num_glyphs; i++) - { - PangoGlyphInfo *gi = &glyphs->glyphs[i]; - - /* If the glyph isn't cached then this will reserve - space for it now. We won't actually draw the glyph - yet because reserving space could cause all of the - other glyphs to be moved so we might as well redraw - them all later once we know that the position is - settled */ - cogl_pango_renderer_get_cached_glyph (renderer, TRUE, - run->item->analysis.font, - gi->glyph); - } - } -} - -static void -_cogl_pango_set_dirty_glyphs (CoglPangoRenderer *priv) -{ - _cogl_pango_glyph_cache_set_dirty_glyphs - (priv->glyph_cache, cogl_pango_renderer_set_dirty_glyph); - _cogl_pango_glyph_cache_set_dirty_glyphs - (priv->mipmapped_glyph_cache, cogl_pango_renderer_set_dirty_glyph); -} - -static void -_cogl_pango_ensure_glyph_cache_for_layout_line (PangoLayoutLine *line) -{ - PangoContext *context; - CoglPangoRenderer *priv; - - context = pango_layout_get_context (line->layout); - priv = cogl_pango_get_renderer_from_context (context); - - _cogl_pango_ensure_glyph_cache_for_layout_line_internal (line); - - /* Now that we know all of the positions are settled we'll fill in - any dirty glyphs */ - _cogl_pango_set_dirty_glyphs (priv); -} - -void -cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout) -{ - PangoContext *context; - CoglPangoRenderer *priv; - PangoLayoutIter *iter; - - context = pango_layout_get_context (layout); - priv = cogl_pango_get_renderer_from_context (context); - - g_return_if_fail (PANGO_IS_LAYOUT (layout)); - - if ((iter = pango_layout_get_iter (layout)) == NULL) - return; - - do - { - PangoLayoutLine *line; - - line = pango_layout_iter_get_line_readonly (iter); - - _cogl_pango_ensure_glyph_cache_for_layout_line_internal (line); - } - while (pango_layout_iter_next_line (iter)); - - pango_layout_iter_free (iter); - - /* Now that we know all of the positions are settled we'll fill in - any dirty glyphs */ - _cogl_pango_set_dirty_glyphs (priv); -} - -static void -cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer, - PangoRenderPart part) -{ - PangoColor *pango_color = pango_renderer_get_color (renderer, part); - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - - if (pango_color) - { - CoglColor color; - - cogl_color_init_from_4ub (&color, - pango_color->red >> 8, - pango_color->green >> 8, - pango_color->blue >> 8, - 0xff); - - _cogl_pango_display_list_set_color_override (priv->display_list, &color); - } - else - _cogl_pango_display_list_remove_color_override (priv->display_list); -} - -static void -cogl_pango_renderer_draw_box (PangoRenderer *renderer, - int x, - int y, - int width, - int height) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - - g_return_if_fail (priv->display_list != NULL); - - _cogl_pango_display_list_add_rectangle (priv->display_list, - x, - y - height, - x + width, - y); -} - -static void -cogl_pango_renderer_get_device_units (PangoRenderer *renderer, - int xin, - int yin, - float *xout, - float *yout) -{ - const PangoMatrix *matrix; - - if ((matrix = pango_renderer_get_matrix (renderer))) - { - /* Convert user-space coords to device coords */ - *xout = ((xin * matrix->xx + yin * matrix->xy) - / PANGO_SCALE + matrix->x0); - *yout = ((yin * matrix->yy + xin * matrix->yx) - / PANGO_SCALE + matrix->y0); - } - else - { - *xout = PANGO_PIXELS (xin); - *yout = PANGO_PIXELS (yin); - } -} - -static void -cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, - PangoRenderPart part, - int x, - int y, - int width, - int height) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - float x1, x2, y1, y2; - - g_return_if_fail (priv->display_list != NULL); - - cogl_pango_renderer_set_color_for_part (renderer, part); - - cogl_pango_renderer_get_device_units (renderer, - x, y, - &x1, &y1); - cogl_pango_renderer_get_device_units (renderer, - x + width, y + height, - &x2, &y2); - - _cogl_pango_display_list_add_rectangle (priv->display_list, - x1, y1, x2, y2); -} - -static void -cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, - PangoRenderPart part, - double y1, - double x11, - double x21, - double y2, - double x12, - double x22) -{ - CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - float points[8]; - - g_return_if_fail (priv->display_list != NULL); - - points[0] = (x11); - points[1] = (y1); - points[2] = (x12); - points[3] = (y2); - points[4] = (x22); - points[5] = points[3]; - points[6] = (x21); - points[7] = points[1]; - - cogl_pango_renderer_set_color_for_part (renderer, part); - - _cogl_pango_display_list_add_trapezoid (priv->display_list, - y1, - x11, - x21, - y2, - x12, - x22); -} - -static void -cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, - PangoFont *font, - PangoGlyphString *glyphs, - int xi, - int yi) -{ - CoglPangoRenderer *priv = (CoglPangoRenderer *) renderer; - CoglPangoGlyphCacheValue *cache_value; - int i; - - cogl_pango_renderer_set_color_for_part (renderer, - PANGO_RENDER_PART_FOREGROUND); - - for (i = 0; i < glyphs->num_glyphs; i++) - { - PangoGlyphInfo *gi = glyphs->glyphs + i; - float x, y; - - cogl_pango_renderer_get_device_units (renderer, - xi + gi->geometry.x_offset, - yi + gi->geometry.y_offset, - &x, &y); - - if ((gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)) - { - PangoFontMetrics *metrics; - - if (font == NULL || - (metrics = pango_font_get_metrics (font, NULL)) == NULL) - { - cogl_pango_renderer_draw_box (renderer, - x, - y, - PANGO_UNKNOWN_GLYPH_WIDTH, - PANGO_UNKNOWN_GLYPH_HEIGHT); - } - else - { - cogl_pango_renderer_draw_box (renderer, - x, - y, - metrics->approximate_char_width - / PANGO_SCALE, - metrics->ascent / PANGO_SCALE); - - pango_font_metrics_unref (metrics); - } - } - else - { - /* Get the texture containing the glyph */ - cache_value = - cogl_pango_renderer_get_cached_glyph (renderer, - FALSE, - font, - gi->glyph); - - /* cogl_pango_ensure_glyph_cache_for_layout should always be - called before rendering a layout so we should never have - a dirty glyph here */ - g_assert (cache_value == NULL || !cache_value->dirty); - - if (cache_value == NULL) - { - cogl_pango_renderer_draw_box (renderer, - x, - y, - PANGO_UNKNOWN_GLYPH_WIDTH, - PANGO_UNKNOWN_GLYPH_HEIGHT); - } - else if (cache_value->texture) - { - x += (float)(cache_value->draw_x); - y += (float)(cache_value->draw_y); - - cogl_pango_renderer_draw_glyph (priv, cache_value, x, y); - } - } - - xi += gi->geometry.width; - } -} diff --git a/clutter/cogl/pango/cogl-pango.h b/clutter/cogl/pango/cogl-pango.h deleted file mode 100644 index 8e7165d..0000000 --- a/clutter/cogl/pango/cogl-pango.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef __PANGO_CLUTTER_H__ -#define __PANGO_CLUTTER_H__ - -#include -#include -#include -#include - -G_BEGIN_DECLS - -/* It's too difficult to actually subclass the pango cairo font - * map. Instead we just make a fake set of macros that actually just - * directly use the original type - */ -#define COGL_PANGO_TYPE_FONT_MAP PANGO_TYPE_CAIRO_FONT_MAP -#define COGL_PANGO_FONT_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_PANGO_TYPE_FONT_MAP, CoglPangoFontMap)) -#define COGL_PANGO_IS_FONT_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_PANGO_TYPE_FONT_MAP)) - -typedef PangoCairoFontMap CoglPangoFontMap; - -PangoFontMap * cogl_pango_font_map_new (void); -PangoContext * cogl_pango_font_map_create_context (CoglPangoFontMap *fm); -void cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, - double dpi); -void cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *fm); -void cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout); -void cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *fm, - gboolean value); -gboolean cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *fm); -PangoRenderer *cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm); - -#define COGL_PANGO_TYPE_RENDERER (cogl_pango_renderer_get_type ()) -#define COGL_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COGL_PANGO_TYPE_RENDERER, CoglPangoRenderer)) -#define COGL_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COGL_PANGO_TYPE_RENDERER, CoglPangoRendererClass)) -#define COGL_PANGO_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COGL_PANGO_TYPE_RENDERER)) -#define COGL_PANGO_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COGL_PANGO_TYPE_RENDERER)) -#define COGL_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COGL_PANGO_TYPE_RENDERER, CoglPangoRendererClass)) - -/* opaque types */ -typedef struct _CoglPangoRenderer CoglPangoRenderer; -typedef struct _CoglPangoRendererClass CoglPangoRendererClass; - -GType cogl_pango_renderer_get_type (void) G_GNUC_CONST; - -void cogl_pango_render_layout_subpixel (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags); -void cogl_pango_render_layout (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags); -void cogl_pango_render_layout_line (PangoLayoutLine *line, - int x, - int y, - const CoglColor *color); - -G_END_DECLS - -#endif /* __PANGO_CLUTTER_H__ */ diff --git a/clutter/cogl/po/ChangeLog b/clutter/cogl/po/ChangeLog deleted file mode 100644 index 45744d4..0000000 --- a/clutter/cogl/po/ChangeLog +++ /dev/null @@ -1,12 +0,0 @@ -2011-02-10 gettextize - - * Makefile.in.in: New file, from gettext-0.17. - * boldquot.sed: New file, from gettext-0.17. - * en@boldquot.header: New file, from gettext-0.17. - * en@quot.header: New file, from gettext-0.17. - * insert-header.sin: New file, from gettext-0.17. - * quot.sed: New file, from gettext-0.17. - * remove-potcdate.sin: New file, from gettext-0.17. - * Rules-quot: New file, from gettext-0.17. - * POTFILES.in: New file. - diff --git a/clutter/cogl/po/Makevars b/clutter/cogl/po/Makevars deleted file mode 100644 index 32692ab..0000000 --- a/clutter/cogl/po/Makevars +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile variables for PO directory in any package using GNU gettext. - -# Usually the message domain is the same as the package name. -DOMAIN = $(PACKAGE) - -# These two variables depend on the location of this directory. -subdir = po -top_builddir = .. - -# These options get passed to xgettext. -XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ - -# This is the copyright holder that gets inserted into the header of the -# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding -# package. (Note that the msgstr strings, extracted from the package's -# sources, belong to the copyright holder of the package.) Translators are -# expected to transfer the copyright for their translations to this person -# or entity, or to disclaim their copyright. The empty string stands for -# the public domain; in this case the translators are expected to disclaim -# their copyright. -COPYRIGHT_HOLDER = Free Software Foundation, Inc. - -# This is the email address or URL to which the translators shall report -# bugs in the untranslated strings: -# - Strings which are not entire sentences, see the maintainer guidelines -# in the GNU gettext documentation, section 'Preparing Strings'. -# - Strings which use unclear terms or require additional context to be -# understood. -# - Strings which make invalid assumptions about notation of date, time or -# money. -# - Pluralisation problems. -# - Incorrect English spelling. -# - Incorrect formatting. -# It can be your email address, or a mailing list address where translators -# can write to without being subscribed, or the URL of a web page through -# which the translators can contact you. -MSGID_BUGS_ADDRESS = - -# This is the list of locale categories, beyond LC_MESSAGES, for which the -# message catalogs shall be used. It is usually empty. -EXTRA_LOCALE_CATEGORIES = diff --git a/clutter/cogl/po/POTFILES.in b/clutter/cogl/po/POTFILES.in deleted file mode 100644 index 667e27c..0000000 --- a/clutter/cogl/po/POTFILES.in +++ /dev/null @@ -1 +0,0 @@ -# List of source files which contain translatable strings. diff --git a/clutter/cogl/po/Rules-quot b/clutter/cogl/po/Rules-quot deleted file mode 100644 index 9c2a995..0000000 --- a/clutter/cogl/po/Rules-quot +++ /dev/null @@ -1,47 +0,0 @@ -# Special Makefile rules for English message catalogs with quotation marks. - -DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot - -.SUFFIXES: .insert-header .po-update-en - -en@quot.po-create: - $(MAKE) en@quot.po-update -en@boldquot.po-create: - $(MAKE) en@boldquot.po-update - -en@quot.po-update: en@quot.po-update-en -en@boldquot.po-update: en@boldquot.po-update-en - -.insert-header.po-update-en: - @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ - if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ - tmpdir=`pwd`; \ - echo "$$lang:"; \ - ll=`echo $$lang | sed -e 's/@.*//'`; \ - LC_ALL=C; export LC_ALL; \ - cd $(srcdir); \ - if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ - if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "creation of $$lang.po failed!" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi - -en@quot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header - -en@boldquot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header - -mostlyclean: mostlyclean-quot -mostlyclean-quot: - rm -f *.insert-header diff --git a/clutter/cogl/po/boldquot.sed b/clutter/cogl/po/boldquot.sed deleted file mode 100644 index 4b937aa..0000000 --- a/clutter/cogl/po/boldquot.sed +++ /dev/null @@ -1,10 +0,0 @@ -s/"\([^"]*\)"/“\1”/g -s/`\([^`']*\)'/‘\1’/g -s/ '\([^`']*\)' / ‘\1’ /g -s/ '\([^`']*\)'$/ ‘\1’/g -s/^'\([^`']*\)' /‘\1’ /g -s/“”/""/g -s/“/“/g -s/”/”/g -s/‘/‘/g -s/’/’/g diff --git a/clutter/cogl/po/en@boldquot.header b/clutter/cogl/po/en@boldquot.header deleted file mode 100644 index fedb6a0..0000000 --- a/clutter/cogl/po/en@boldquot.header +++ /dev/null @@ -1,25 +0,0 @@ -# All this catalog "translates" are quotation characters. -# The msgids must be ASCII and therefore cannot contain real quotation -# characters, only substitutes like grave accent (0x60), apostrophe (0x27) -# and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html -# -# This catalog translates grave accent (0x60) and apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019). -# It also translates pairs of apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019) -# and pairs of quotation mark (0x22) to -# left double quotation mark (U+201C) and right double quotation mark (U+201D). -# -# When output to an UTF-8 terminal, the quotation characters appear perfectly. -# When output to an ISO-8859-1 terminal, the single quotation marks are -# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to -# grave/acute accent (by libiconv), and the double quotation marks are -# transliterated to 0x22. -# When output to an ASCII terminal, the single quotation marks are -# transliterated to apostrophes, and the double quotation marks are -# transliterated to 0x22. -# -# This catalog furthermore displays the text between the quotation marks in -# bold face, assuming the VT100/XTerm escape sequences. -# diff --git a/clutter/cogl/po/en@quot.header b/clutter/cogl/po/en@quot.header deleted file mode 100644 index a9647fc..0000000 --- a/clutter/cogl/po/en@quot.header +++ /dev/null @@ -1,22 +0,0 @@ -# All this catalog "translates" are quotation characters. -# The msgids must be ASCII and therefore cannot contain real quotation -# characters, only substitutes like grave accent (0x60), apostrophe (0x27) -# and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html -# -# This catalog translates grave accent (0x60) and apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019). -# It also translates pairs of apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019) -# and pairs of quotation mark (0x22) to -# left double quotation mark (U+201C) and right double quotation mark (U+201D). -# -# When output to an UTF-8 terminal, the quotation characters appear perfectly. -# When output to an ISO-8859-1 terminal, the single quotation marks are -# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to -# grave/acute accent (by libiconv), and the double quotation marks are -# transliterated to 0x22. -# When output to an ASCII terminal, the single quotation marks are -# transliterated to apostrophes, and the double quotation marks are -# transliterated to 0x22. -# diff --git a/clutter/cogl/po/insert-header.sin b/clutter/cogl/po/insert-header.sin deleted file mode 100644 index b26de01..0000000 --- a/clutter/cogl/po/insert-header.sin +++ /dev/null @@ -1,23 +0,0 @@ -# Sed script that inserts the file called HEADER before the header entry. -# -# At each occurrence of a line starting with "msgid ", we execute the following -# commands. At the first occurrence, insert the file. At the following -# occurrences, do nothing. The distinction between the first and the following -# occurrences is achieved by looking at the hold space. -/^msgid /{ -x -# Test if the hold space is empty. -s/m/m/ -ta -# Yes it was empty. First occurrence. Read the file. -r HEADER -# Output the file's contents by reading the next line. But don't lose the -# current line while doing this. -g -N -bb -:a -# The hold space was nonempty. Following occurrences. Do nothing. -x -:b -} diff --git a/clutter/cogl/po/quot.sed b/clutter/cogl/po/quot.sed deleted file mode 100644 index 0122c46..0000000 --- a/clutter/cogl/po/quot.sed +++ /dev/null @@ -1,6 +0,0 @@ -s/"\([^"]*\)"/“\1”/g -s/`\([^`']*\)'/‘\1’/g -s/ '\([^`']*\)' / ‘\1’ /g -s/ '\([^`']*\)'$/ ‘\1’/g -s/^'\([^`']*\)' /‘\1’ /g -s/“”/""/g diff --git a/clutter/cogl/po/remove-potcdate.sin b/clutter/cogl/po/remove-potcdate.sin deleted file mode 100644 index 2436c49..0000000 --- a/clutter/cogl/po/remove-potcdate.sin +++ /dev/null @@ -1,19 +0,0 @@ -# Sed script that remove the POT-Creation-Date line in the header entry -# from a POT file. -# -# The distinction between the first and the following occurrences of the -# pattern is achieved by looking at the hold space. -/^"POT-Creation-Date: .*"$/{ -x -# Test if the hold space is empty. -s/P/P/ -ta -# Yes it was empty. First occurrence. Remove the line. -g -d -bb -:a -# The hold space was nonempty. Following occurrences. Do nothing. -x -:b -} diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index df29156..8d0084c 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -53,11 +53,7 @@ #include "x11/clutter-x11-texture-pixmap.h" -#ifdef CLUTTER_USING_SYSTEM_COGL #include -#else -#include "cogl/winsys/cogl-texture-pixmap-x11.h" -#endif G_DEFINE_TYPE (ClutterGLXTexturePixmap, \ clutter_glx_texture_pixmap, \ diff --git a/clutter/wayland/clutter-backend-wayland.c b/clutter/wayland/clutter-backend-wayland.c index 0f791cd..c21b81a 100644 --- a/clutter/wayland/clutter-backend-wayland.c +++ b/clutter/wayland/clutter-backend-wayland.c @@ -336,12 +336,12 @@ clutter_backend_wayland_post_parse (ClutterBackend *backend, return TRUE; } -#if defined(HAVE_COGL_GL) +#if defined(COGL_HAS_GL) #define _COGL_RENDERABLE_BIT EGL_OPENGL_BIT -#elif defined(HAVE_COGL_GLES2) +#elif defined(COGL_HAS_GLES2) #define _COGL_GLES_VERSION 2 #define _COGL_RENDERABLE_BIT EGL_OPENGL_ES2_BIT -#elif defined(HAVE_COGL_GLES) +#elif defined(COGL_HAS_GLES1) #define _COGL_GLES_VERSION 1 #define _COGL_RENDERABLE_BIT EGL_OPENGL_ES_BIT #endif @@ -383,7 +383,7 @@ try_create_context (ClutterBackend *backend, if (backend_wayland->egl_context == EGL_NO_CONTEXT) { -#if defined(HAVE_COGL_GL) +#if defined(COGL_HAS_GL) static const EGLint *attribs = NULL; #else static const EGLint attribs[] = @@ -427,11 +427,11 @@ fail: } } -#if defined(HAVE_COGL_GL) +#if defined(COGL_HAS_GL) #define _COGL_SURFACELESS_EXTENSION "EGL_KHR_surfaceless_opengl" -#elif defined(HAVE_COGL_GLES) +#elif defined(COGL_HAS_GLES1) #define _COGL_SURFACELESS_EXTENSION "EGL_KHR_surfaceless_gles1" -#elif defined(HAVE_COGL_GLES2) +#elif defined(COGL_HAS_GLES2) #define _COGL_SURFACELESS_EXTENSION "EGL_KHR_surfaceless_gles2" #endif @@ -449,7 +449,7 @@ clutter_backend_wayland_create_context (ClutterBackend *backend, if (backend_wayland->egl_context != EGL_NO_CONTEXT) return TRUE; -#if defined(HAVE_COGL_GL) +#if defined(COGL_HAS_GL) eglBindAPI (EGL_OPENGL_API); #else eglBindAPI (EGL_OPENGL_ES_API); diff --git a/clutter/x11/clutter-x11-texture-pixmap.c b/clutter/x11/clutter-x11-texture-pixmap.c index 9965fb0..0b459fc 100644 --- a/clutter/x11/clutter-x11-texture-pixmap.c +++ b/clutter/x11/clutter-x11-texture-pixmap.c @@ -51,13 +51,9 @@ #include "clutter-paint-volume-private.h" #include "clutter-private.h" -#include "cogl/cogl.h" +#include -#ifdef CLUTTER_USING_SYSTEM_COGL #include -#else -#include "cogl/winsys/cogl-texture-pixmap-x11.h" -#endif #include diff --git a/configure.ac b/configure.ac index 23d5d04..3753971 100644 --- a/configure.ac +++ b/configure.ac @@ -70,18 +70,6 @@ AC_SUBST([CLUTTER_API_VERSION], [clutter_api_version]) AC_SUBST([CLUTTER_API_VERSION_AM], [$CLUTTER_MAJOR_VERSION\_0]) AC_SUBST([CLUTTER_RELEASE_STATUS], [clutter_release_status]) -dnl For Makefile.am compatibility with the standalone build of Cogl: -AC_SUBST([COGL_1_MINOR_VERSION],[clutter_minor_version]) -AC_SUBST([COGL_1_MICRO_VERSION],[clutter_micro_version]) -AC_SUBST([COGL_1_VERSION],[clutter_version]) - -AC_SUBST([COGL_MAJOR_VERSION],[2]) -AC_SUBST([COGL_MINOR_VERSION],[0]) -AC_SUBST([COGL_MICRO_VERSION],[0]) -AC_SUBST([COGL_VERSION],[2.0.0]) -AC_SUBST([COGL_API_VERSION],[2.0]) -AC_SUBST([COGL_API_VERSION_AM],[2_0]) - m4_define([lt_current], [m4_eval(100 * clutter_minor_version + clutter_micro_version - clutter_interface_age)]) m4_define([lt_revision], [clutter_interface_age]) m4_define([lt_age], [m4_eval(clutter_binary_age - clutter_interface_age)]) @@ -128,6 +116,7 @@ AC_HEADER_STDC # required versions for dependencies m4_define([glib_req_version], [2.26.0]) +m4_define([cogl_req_version], [1.6.0]) m4_define([json_glib_req_version], [0.12.0]) m4_define([atk_req_version], [1.17]) m4_define([cairo_req_version], [1.10]) @@ -140,6 +129,7 @@ m4_define([xfixes_req_version], [3]) m4_define([xcomposite_req_version], [0.4]) AC_SUBST([GLIB_REQ_VERSION], [glib_req_version]) +AC_SUBST([COGL_REQ_VERSION], [cogl_req_version]) AC_SUBST([JSON_GLIB_REQ_VERSION], [json_glib_req_version]) AC_SUBST([ATK_REQ_VERSION], [atk_req_version]) AC_SUBST([CAIRO_REQ_VERSION], [cairo_req_version]) @@ -190,7 +180,6 @@ FLAVOUR_CFLAGS="" CLUTTER_WINSYS_BASE= CLUTTER_WINSYS_BASE_LIB= CLUTTER_WINSYS= -cogl_gl_headers="" glesversion=1.1 use_gles2_wrapper=no experimental_backend=no @@ -206,23 +195,8 @@ AC_ARG_WITH([gles], [Select Clutter GLES version (for EGL backends)])], [glesversion=$with_gles]) -COGL_REQ="" -AC_ARG_WITH([system-cogl], - [AS_HELP_STRING([--with-system-cogl=@<:@yes/no@:>@], - [Use a system installed Cogl library])], - [ - if test "x$with_system_cogl" = "xyes"; then - COGL_REQ="cogl-1.0" - fi - ], - [with_system_cogl=no]) - -AM_CONDITIONAL(USE_SYSTEM_COGL, [test "x$with_system_cogl" = "xyes"]) -AS_IF([test "x$with_system_cogl" = "xyes"], - [ AC_DEFINE([CLUTTER_USING_SYSTEM_COGL], [1], [Built against the system Cogl library])]) - # base dependencies for core -CLUTTER_BASE_PC_FILES="cairo-gobject >= $CAIRO_REQ_VERSION atk >= $ATK_REQ_VERSION pangocairo >= $PANGO_REQ_VERSION json-glib-1.0 >= $JSON_GLIB_REQ_VERSION $COGL_REQ" +CLUTTER_BASE_PC_FILES="cogl-1.0 cairo-gobject >= $CAIRO_REQ_VERSION atk >= $ATK_REQ_VERSION pangocairo >= $PANGO_REQ_VERSION json-glib-1.0 >= $JSON_GLIB_REQ_VERSION" # backend specific pkg-config files BACKEND_PC_FILES="" @@ -233,15 +207,12 @@ AS_CASE([$CLUTTER_FLAVOUR], [glx], [ - cogl_gl_headers="GL/gl.h" CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_GLX" SUPPORT_X11=1 SUPPORT_XLIB=1 SUPPORT_GLX=1 - COGL_DRIVER="gl" - CLUTTER_WINSYS=glx CLUTTER_WINSYS_BASE=x11 CLUTTER_WINSYS_BASE_LIB="x11/libclutter-x11.la" @@ -265,7 +236,6 @@ AS_CASE([$CLUTTER_FLAVOUR], [opengl-egl-xlib], [ - cogl_gl_headers="GL/gl.h" CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL" CLUTTER_EGL_BACKEND="generic" @@ -274,8 +244,6 @@ AS_CASE([$CLUTTER_FLAVOUR], SUPPORT_EGL=1 SUPPORT_EGL_PLATFORM_POWERVR_X11=1 - COGL_DRIVER="gl" - CLUTTER_WINSYS=egl CLUTTER_WINSYS_BASE=x11 CLUTTER_WINSYS_BASE_LIB="x11/libclutter-x11.la" @@ -290,13 +258,10 @@ AS_CASE([$CLUTTER_FLAVOUR], [wayland], [ experimental_backend="yes" - cogl_gl_headers="GL/gl.h" CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_WAYLAND" SUPPORT_WAYLAND=1 - COGL_DRIVER="gl" - CLUTTER_WINSYS=wayland CLUTTER_SONAME_INFIX=wayland @@ -308,7 +273,6 @@ AS_CASE([$CLUTTER_FLAVOUR], [eglx], [ - # the GL header is defined in the COGL checks above CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL" CLUTTER_EGL_BACKEND="generic" @@ -317,8 +281,6 @@ AS_CASE([$CLUTTER_FLAVOUR], SUPPORT_EGL=1 SUPPORT_EGL_PLATFORM_POWERVR_X11=1 - COGL_DRIVER="gles" - CLUTTER_WINSYS=egl CLUTTER_WINSYS_BASE=x11 CLUTTER_WINSYS_BASE_LIB="x11/libclutter-x11.la" @@ -327,7 +289,6 @@ AS_CASE([$CLUTTER_FLAVOUR], [eglnative], [ - # the GL header is defined in the COGL checks above CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_EGL" CLUTTER_EGL_BACKEND="generic" @@ -352,8 +313,6 @@ AS_CASE([$CLUTTER_FLAVOUR], AS_IF([test "x$have_tslib" = "xyes" -a "x$have_evdev" = "xyes"], [AC_MSG_ERROR([Can't enable both tslib and evdev events])]) - COGL_DRIVER="gles" - FLAVOUR_LIBS="$FLAVOUR_LIBS $TSLIB_LIBS $EVDEV_LIBS" FLAVOUR_CFLAGS="$FLAVOUR_CFLAGS $TSLIB_CFLAGS $EVDEV_CFLAGS" @@ -369,8 +328,6 @@ AS_CASE([$CLUTTER_FLAVOUR], SUPPORT_EGL=1 SUPPORT_EGL_PLATFORM_GDL=1 - COGL_DRIVER="gles" - # The cex100 is a small specialization of the EGL backend CLUTTER_WINSYS=egl CLUTTER_SONAME_INFIX=cex100 @@ -404,14 +361,9 @@ AS_CASE([$CLUTTER_FLAVOUR], [osx], [ experimental_backend="yes" - cogl_gl_headers="OpenGL/gl.h" CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_OSX" AC_DEFINE([HAVE_CLUTTER_OSX], [1], [Have the OSX backend]) - AC_DEFINE([COGL_HAS_OSX_SUPPORT], [1], [Cogl supports the OSX window system]) - - COGL_DRIVER="gl" - AC_DEFINE([HAVE_COGL_GL], [1], [Have GL for rendering]) FLAVOUR_LIBS="$FLAVOUR_LIBS -framework Cocoa -framework OpenGL" @@ -421,14 +373,8 @@ AS_CASE([$CLUTTER_FLAVOUR], [win32], [ - cogl_gl_headers="GL/gl.h" CLUTTER_STAGE_TYPE="CLUTTER_TYPE_STAGE_WIN32" AC_DEFINE([HAVE_CLUTTER_WIN32], [1], [Have the Win32 backend]) - AC_DEFINE([COGL_HAS_WIN32_SUPPORT], [1], [Cogl supports the win32 window system]) - AC_DEFINE([COGL_HAS_WGL_SUPPORT], [1], [Cogl supports OpenGL using the WGL API]) - - COGL_DRIVER="gl" - AC_DEFINE([HAVE_COGL_GL], [1], [Have GL for rendering]) FLAVOUR_LIBS="$FLAVOUR_LIBS -lopengl32 -lgdi32 -lwinmm" FLAVOUR_CFLAGS="$FLAVOUR_CFLAGS -D_WIN32_WINNT=0x0500" @@ -446,21 +392,10 @@ AS_CASE([$CLUTTER_FLAVOUR], win32, eglx or eglnative])] ) -AS_IF([test "x$SUPPORT_X11" = "x1"], - [ AC_DEFINE([COGL_HAS_X11_SUPPORT], [1], [Cogl supports the X11 window system])]) -AS_IF([test "x$SUPPORT_XLIB" = "x1"], - [ AC_DEFINE([COGL_HAS_XLIB_SUPPORT], [1], [Cogl supports X11 using the Xlib API])]) - AS_IF([test "x$SUPPORT_GLX" = "x1"], [ - AC_DEFINE([COGL_HAS_GLX_SUPPORT], [1], [Cogl supports OpenGL using the GLX API]) - - AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context]) - AC_DEFINE([HAVE_CLUTTER_GLX], [1], [Have the GLX backend]) - AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context]) - AC_CHECK_HEADERS([GL/glx.h], [], [AC_MSG_ERROR([Unable to locate required GLX headers])]) @@ -478,7 +413,6 @@ AS_IF([test "x$SUPPORT_WAYLAND" = "x1"], AS_IF([test "x$SUPPORT_EGL" = "x1"], [ AC_DEFINE([HAVE_CLUTTER_EGL], [1], [Have the EGL backend]) - AC_DEFINE([COGL_HAS_EGL_SUPPORT], [1], [Cogl supports GLES using the EGL API]) ]) AS_IF([test "x$CLUTTER_EGL_BACKEND" = "xgeneric"], @@ -487,28 +421,11 @@ AS_IF([test "x$CLUTTER_EGL_BACKEND" = "xgeneric"], AS_IF([test "x$CLUTTER_EGL_BACKEND" = "xcex100"], AC_DEFINE([CLUTTER_EGL_BACKEND_CEX100], [1], [Use CEX100 EGL backend])) -AS_IF([test "x$SUPPORT_EGL_PLATFORM_POWERVR_X11" = "x1"], - [ - AC_DEFINE([COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT], [1], - [Cogl supports OpenGL[ES] using the EGL API with PowerVR X11 platform typedefs]) - AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context]) - ]) - -AS_IF([test "x$SUPPORT_EGL_PLATFORM_POWERVR_NULL" = "x1"], - [ - AC_DEFINE([COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT], [1], - [Cogl supports OpenGL[ES] using the EGL API with PowerVR NULL platform typedefs]) - AC_DEFINE([COGL_HAS_FULL_WINSYS], [1], [Cogl can create its own OpenGL context]) - ]) - # winsys conditionals for use in automake files... AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "x1"]) AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "x1"]) AM_CONDITIONAL(SUPPORT_XLIB, [test "x$SUPPORT_XLIB" = "x1"]) AM_CONDITIONAL(SUPPORT_EGL, [test "x$SUPPORT_EGL" = "x1"]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_POWERVR_X11, [test "x$SUPPORT_EGL_PLATFORM_POWERVR_X11" = "x1"]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_POWERVR_NULL, [test "x$SUPPORT_EGL_PLATFORM_POWERVR_NULL" = "x1"]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_GDL, [test "x$SUPPORT_EGL_PLATFORM_GDL" = "x1"]) AM_CONDITIONAL(SUPPORT_OSX, [test "x$CLUTTER_WINSYS" = "xosx"]) AM_CONDITIONAL(SUPPORT_WIN32, [test "x$CLUTTER_WINSYS" = "xwin32"]) AM_CONDITIONAL(SUPPORT_CEX100, [test "x$SUPPORT_EGL_PLATFORM_GDL" = "x1"]) @@ -517,186 +434,9 @@ AM_CONDITIONAL(SUPPORT_STUB, [test "x$CLUTTER_WINSYS" = "xwin32" -o \ "x$CLUTTER_WINSYS" = "xosx" -o \ "x$CLUTTER_WINSYS" = "xwayland"]) -dnl === COGL driver backend ===================================================== - -AS_IF([test "x$COGL_DRIVER" = "xgl"], - [ AC_DEFINE([HAVE_COGL_GL], [1], [Have GL for rendering]) - NEED_SEPARATE_EGL=yes - ]) - -cogl_gles_version_define="" - -AS_IF([test "x$COGL_DRIVER" = "xgles"], - - [ - AS_CASE([$glesversion], - - [1*], - [ - cogl_gl_headers="GLES/gl.h GLES/glext.h" - - AC_DEFINE([HAVE_COGL_GLES], 1, [Have GL/ES for rendering]) - cogl_gles_version_define="COGL_HAS_GLES1" - - PKG_CHECK_EXISTS([glesv1_cm], - [BACKEND_PC_FILES="$BACKEND_PC_FILES glesv1_cm" - NEED_SEPARATE_EGL=yes - ], - [ - AC_CHECK_HEADERS([$cogl_gl_headers], - [], - [AC_MSG_ERROR([Unable to locate required GLES headers])]) - - # Check for a GLES 1.x Common Profile library with/without EGL. - # - # Note: historically GLES 1 libraries shipped with the - # EGL and GLES symbols all bundled in one library. Now - # the Khronos Implementers Guide defines two naming - # schemes: -lGLES_CM should be used for a library that - # bundles the GLES and EGL API together and -lGLESv1_CM - # would be used for a standalone GLES API. - AC_CHECK_LIB(GLES_CM, [eglInitialize], - [FLAVOUR_LIBS="$FLAVOUR_LIBS -lGLES_CM"], - [ - AC_CHECK_LIB(GLESv1_CM, [glFlush], - [FLAVOUR_LIBS="$FLAVOUR_LIBS -lGLESv1_CM" - NEED_SEPARATE_EGL=yes - ], - [AC_MSG_ERROR([Unable to locate required GLES 1.x Common Profile library])]) - ]) - ]) - - AS_IF([test "x$NEED_SEPARATE_EGL" = "xyes"], - [ - PKG_CHECK_EXISTS([egl], - [BACKEND_PC_FILES="$BACKEND_PC_FILES egl" - NEED_SEPARATE_EGL=yes - ], - [ - AC_CHECK_HEADERS([GLES/egl.h], - [], - [AC_MSG_ERROR([Unable to locate required EGL headers])]) - - AC_CHECK_LIB(EGL, [eglInitialize], - [FLAVOUR_LIBS="$FLAVOUR_LIBS -lEGL"], - [AC_MSG_ERROR([Unable to locate required EGL library])]) - ]) - ]) - ], - - [2*], - [ - cogl_gl_headers="GLES2/gl2.h GLES2/gl2ext.h" - use_gles2_wrapper=yes - AC_DEFINE([HAVE_COGL_GLES2], 1, [Have GL/ES for rendering]) - cogl_gles_version_define="COGL_HAS_GLES2" - - PKG_CHECK_EXISTS([glesv2], - [BACKEND_PC_FILES="$BACKEND_PC_FILES glesv2"], - [ - AC_CHECK_HEADERS([$cogl_gl_headers], - [], - [AC_MSG_ERROR([Unable to locate required GLES headers])], - [[#include - ]]) - - FLAVOUR_LIBS="$FLAVOUR_LIBS -lGLESv2" - ]) - - PKG_CHECK_EXISTS([egl], - [BACKEND_PC_FILES="$BACKEND_PC_FILES egl"], - [ - AC_CHECK_HEADERS([EGL/egl.h], - [], - [AC_MSG_ERROR([Unable to locate required EGL headers])]) - - AC_CHECK_LIB(EGL, [eglInitialize], - [FLAVOUR_LIBS="$FLAVOUR_LIBS -lEGL"], - [AC_MSG_ERROR([Unable to locate required EGL library])]) - - FLAVOUR_LIBS="$FLAVOUR_LIBS -lEGL" - ] - ) - - NEED_SEPARATE_EGL=yes - ], - - [AC_MSG_ERROR([Unknown argument for --with-gles])] - ) - ] -) - AM_CONDITIONAL(USE_TSLIB, [test "x$have_tslib" = "xyes"]) AM_CONDITIONAL(SUPPORT_EVDEV, [test "x$have_evdev" = "xyes"]) -AM_CONDITIONAL(USE_GLES2_WRAPPER, [test "x$use_gles2_wrapper" = "xyes"]) - -dnl The value of this variable will directly go in the install -dnl cogl-defines.h header -COGL_DEFINES=""; -dnl Space-separated list of symbols that should be defined in -dnl cogl-defines.h -COGL_DEFINES_SYMBOLS=""; - -if test "x$SUPPORT_X11" = "x1"; then - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_X11 COGL_HAS_X11_SUPPORT" -fi; - -if test "x$SUPPORT_XLIB" = "x1"; then - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_XLIB COGL_HAS_XLIB_SUPPORT" -fi; - -if test "x$SUPPORT_GLX" = "x1"; then - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLX_SUPPORT" -fi; - -if test "x$SUPPORT_EGL" = "x1"; then - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_SUPPORT" -fi; - -if test "x$NEED_SEPARATE_EGL" = "xyes"; then - AC_DEFINE([HAVE_STANDALONE_EGL], 1, [Have standalone EGL library]) -fi - -if test "x$SUPPORT_EGL_PLATFORM_GDL" = "xyes"; then - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_GDL_SUPPORT" -fi - -AS_CASE([$COGL_DRIVER], - [gl], - [COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GL" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS CLUTTER_COGL_HAS_GL"], - [gles], - [COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS CLUTTER_COGL_HAS_GLES" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS $cogl_gles_version_define" - ], - [AC_MSG_ERROR([Unknown cogl driver $COGL_DRIVER])]) - -dnl Copy all of the words in COGL_DEFINES_SYMBOLS as separate #define -dnl lines in COGL_DEFINES -for x in $COGL_DEFINES_SYMBOLS; do - COGL_DEFINES="$COGL_DEFINES -#define $x 1" -done; - -AC_SUBST(COGL_DEFINES) - -AS_IF([test "x$cogl_gl_headers" = "x"], [AC_MSG_ERROR([Internal error: no GL header set])]) - -dnl cogl_gl_headers is a space separate list of headers to -dnl include. We'll now convert them to a single variable with a -dnl #include line for each header -COGL_GL_HEADER_INCLUDES="" -for x in $cogl_gl_headers; do - COGL_GL_HEADER_INCLUDES="$COGL_GL_HEADER_INCLUDES -#include <$x>" -done; -AC_SUBST(COGL_GL_HEADER_INCLUDES) - -AM_CONDITIONAL([COGL_DRIVER_GLES], [test "x$COGL_DRIVER" = "xgles"]) -AM_CONDITIONAL([COGL_DRIVER_GL], [test "x$COGL_DRIVER" = "xgl"]) - dnl Instead of using AM_CFLAGS to ensure dnl COGL_ENABLE_EXPERIMENTAL_2_0_API is defined while compiling clutter dnl and cogl code we use a define in config.h instead. This helps ensure @@ -705,10 +445,6 @@ dnl using the define also. AC_DEFINE([COGL_ENABLE_EXPERIMENTAL_2_0_API], [1], [Can use Cogl 2.0 API internally]) -dnl Cogl can be experimentally be built standalone and there are a few -dnl tweaks we need to make in the Makefiles when building standalone -AM_CONDITIONAL(COGL_STANDALONE_BUILD, [false]) - dnl === Clutter configuration ================================================= CLUTTER_CONFIG_DEFINES= @@ -753,50 +489,12 @@ AC_SUBST([CLUTTER_WINSYS_LIB]) dnl === Clutter substitutions kept for backwards compatibility ================ AC_SUBST([CLUTTER_FLAVOUR]) -CLUTTER_COGL=$COGL_DRIVER +CLUTTER_COGL=undefined AC_SUBST([CLUTTER_COGL]) -dnl === Cogl substitutions ==================================================== -AC_SUBST([COGL_IMAGE_BACKEND]) -COGL_WINSYS=$CLUTTER_WINSYS -AC_SUBST([COGL_WINSYS]) -AC_SUBST([COGL_DRIVER]) - dnl === Image loading backend ================================================= IMAGE_PC_FILES="" -# Peek which winsys the user wants so that we can couple the osx winsys with -# quartz imageloader. -AS_IF([test "x$COGL_WINSYS" = "xosx"], [COGL_IMAGE_BACKEND=quartz], [COGL_IMAGE_BACKEND=gdk-pixbuf]) - -AC_ARG_WITH([imagebackend], - [AC_HELP_STRING([--with-imagebackend=@<:@gdk-pixbuf/quartz/internal@:>@], - [Select COGL image loading backend])], - [COGL_IMAGE_BACKEND=$with_imagebackend]) - -AS_CASE([$COGL_IMAGE_BACKEND], - - [quartz], - [ - experimental_image=yes - AC_DEFINE([USE_QUARTZ], 1, [Use Core Graphics (Quartz) for loading image data]) - ], - - [gdk-pixbuf], - [ - AC_DEFINE([USE_GDKPIXBUF], 1, [Use GdkPixbuf for loading image data]) - IMAGE_PC_FILES="gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQ_VERSION" - ], - - [internal], - [ - experimental_image=yes - AC_DEFINE([USE_INTERNAL], 1, [Use internal image decoding for loading image data]) - ], - - [AC_MSG_ERROR([Unknown argument for --with-imagebackend])] -) - dnl === X11 checks, only for X11-based backends =============================== X11_PC_FILES="" x11_tests=no @@ -995,29 +693,6 @@ AS_CASE([$enable_debug], AC_SUBST(CLUTTER_DEBUG_CFLAGS) -m4_define([cogl_debug_default], [minimum]) -AC_ARG_ENABLE([cogl-debug], - [AC_HELP_STRING([--enable-cogl-debug=@<:@no/yes@:>@], - [Control COGL debugging level @<:@default=cogl_debug_default@:>@])], - [], - [enable_cogl_debug=cogl_debug_default]) - -AS_CASE([$enable_cogl_debug], - - [yes], - [COGL_EXTRA_CFLAGS="-DCOGL_GL_DEBUG -DCOGL_OBJECT_DEBUG -DCOGL_HANDLE_DEBUG -DCOGL_ENABLE_DEBUG"], - - [minimum], - [COGL_EXTRA_CFLAGS="-DCOGL_ENABLE_DEBUG"], - - [no], - [COGL_EXTRA_CFLAGS=""], - - [AC_MSG_ERROR([Invalid value for --enable-cogl-debug])] -) - -AC_SUBST(COGL_EXTRA_CFLAGS) - dnl === Conformance test suite ================================================ AC_ARG_ENABLE([conformance], @@ -1044,7 +719,7 @@ AS_CASE([$enable_profile], AS_IF([test "x$GCC" = "xyes"], [ PKG_CHECK_MODULES([PROFILE_DEP], [uprof-0.3]) - CLUTTER_PROFILE_CFLAGS="-DCLUTTER_ENABLE_PROFILE -DCOGL_ENABLE_PROFILE $PROFILE_DEP_CFLAGS" + CLUTTER_PROFILE_CFLAGS="-DCLUTTER_ENABLE_PROFILE $PROFILE_DEP_CFLAGS" CLUTTER_PROFILE_LDFLAGS="$PROFILE_DEP_LIBS" AS_IF([test "x$enable_debug" = "xyes"], [CLUTTER_PROFILE_CFLAGS+=" -DUPROF_DEBUG"]) @@ -1150,11 +825,6 @@ CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_PROFILE_LDFLAGS $GLIB_LI AC_SUBST(CLUTTER_CFLAGS) AC_SUBST(CLUTTER_LIBS) -dnl For Makefile.am compatibility with the standalone build of Cogl: -AC_SUBST([COGL_DEP_CFLAGS], [$CLUTTER_CFLAGS]) -AC_SUBST([COGL_DEP_LIBS], [$CLUTTER_LIBS]) -AC_SUBST([COGL_PKG_REQUIRES],[$CLUTTER_REQUIRES]) - dnl === GObject-Introspection check =========================================== @@ -1243,14 +913,6 @@ AC_CONFIG_FILES([ clutter/cally/cally-$CLUTTER_API_VERSION.pc:clutter/cally/cally.pc.in - clutter/cogl/Makefile - clutter/cogl/po/Makefile.in - clutter/cogl/examples/Makefile - clutter/cogl/cogl/Makefile - clutter/cogl/cogl/cogl-defines.h - clutter/cogl/cogl/cogl-1.0.pc:clutter/cogl/cogl/cogl-1.0-clutter.pc.in - clutter/cogl/pango/Makefile - clutter/egl/clutter-cex100.h tests/Makefile @@ -1266,8 +928,6 @@ AC_CONFIG_FILES([ doc/reference/Makefile doc/reference/clutter/Makefile doc/reference/clutter/clutter-docs.xml - doc/reference/cogl/Makefile - doc/reference/cogl/cogl-docs.xml doc/reference/cally/Makefile doc/reference/cally/cally-docs.xml doc/common/Makefile @@ -1291,14 +951,13 @@ echo "Clutter - $VERSION (${CLUTTER_RELEASE_STATUS})" echo "" echo " • Global:" echo " Prefix: ${prefix}" -echo " Flavour: ${CLUTTER_WINSYS}/${COGL_DRIVER}" +echo " Flavour: ${CLUTTER_WINSYS}" echo " Target library: ${CLUTTER_WINSYS_LIB}" # Compiler/Debug related flags echo "" echo " • Compiler options:" echo " Clutter debug level: ${enable_debug}" -echo " COGL debug level: ${enable_cogl_debug}" echo " Compiler flags: ${CFLAGS} ${MAINTAINER_CFLAGS}" echo " Profiling enabled: ${enable_profile}" echo " Enable coverage tests: ${enable_gcov}" @@ -1315,26 +974,6 @@ echo " • Extra:" echo " Build introspection data: ${enable_introspection}" echo " Build conformance test suite: ${enable_conformance}" -# Cogl flags -echo "" -echo " • Cogl Backend:" -echo " Driver: ${COGL_DRIVER}" -echo " GL header: ${cogl_gl_headers}" - -if test "x$COGL_DRIVER" = "xgles"; then - if test "x$use_gles2_wrapper" = "xyes"; then -echo " GLES version: 2.0" - else -echo " GLES version: 1.1" - fi -fi - -if test "x$experimental_image" = "xno"; then -echo " Image backend: ${COGL_IMAGE_BACKEND}" -else -echo " Image backend: ${COGL_IMAGE_BACKEND} (WARNING: Experimental)" -fi - # Clutter backend related flags echo "" echo " • Clutter Backend:" diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index ab9b86b..5c120d9 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = cogl clutter cally +SUBDIRS = clutter cally -DIST_SUBDIRS = cogl clutter cally +DIST_SUBDIRS = clutter cally diff --git a/doc/reference/cogl/Makefile.am b/doc/reference/cogl/Makefile.am deleted file mode 100644 index 01bc8e9..0000000 --- a/doc/reference/cogl/Makefile.am +++ /dev/null @@ -1,151 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# We require automake 1.6 at least. -AUTOMAKE_OPTIONS = 1.6 - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE=cogl - -# The top-level SGML file. You can change this if you want to. -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml - -# The directory containing the source code. Relative to $(srcdir). -# gtk-doc will search all .c & .h files beneath here for inline comments -# documenting the functions and macros. -# e.g. DOC_SOURCE_DIR=../../../gtk -DOC_SOURCE_DIR=../../../clutter/cogl/cogl - -# Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS=--type-init-func="g_type_init()" - -# Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS=--deprecated-guards="COGL_DISABLE_DEPRECATED" - -# Extra options to supply to gtkdoc-mkdb. -# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml -MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space=cogl - -# Extra options to supply to gtkdoc-mktmpl -# e.g. MKTMPL_OPTIONS=--only-section-tmpl -MKTMPL_OPTIONS= - -# Extra options to supply to gtkdoc-fixref. Not normally needed. -# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS=\ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ - --extra-dir=$(GDPIXBUF_PREFIX)/share/gtk-doc/html/gdk-pixbuf - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=\ - $(top_srcdir)/clutter/cogl/cogl/*.h \ - $(top_builddir)/clutter/cogl/cogl/*.h -CFILE_GLOB=$(top_srcdir)/clutter/cogl/cogl/*.c - -# Header files to ignore when scanning. -# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h -IGNORE_HFILES=\ - cogl-atlas.h \ - cogl-atlas-texture-private.h \ - cogl-bitmap-private.h \ - cogl-buffer-private.h \ - cogl-color-private.h \ - cogl-feature-private.h \ - cogl-framebuffer-private.h \ - cogl-gtype-private.h \ - cogl-index-array-private.h \ - cogl-indices-private.h \ - cogl-journal-private.h \ - cogl-matrix-private.h \ - cogl-object-private.h \ - cogl-path-private.h \ - cogl-pipeline-fragend-arbfp-private.h \ - cogl-pipeline-fragend-fixed-private.h \ - cogl-pipeline-fragend-glsl-private.h \ - cogl-pipeline-opengl-private.h \ - cogl-pipeline-private.h \ - cogl-pipeline-progend-glsl-private.h \ - cogl-pipeline-vertend-fixed-private.h \ - cogl-pipeline-vertend-glsl-private.h \ - cogl-pixel-array-private.h \ - cogl-primitive-private.h \ - cogl-primitives-private.h \ - cogl-private.h \ - cogl-program-private.h \ - cogl-shader-private.h \ - cogl-sub-texture-private.h \ - cogl-texture-2d-private.h \ - cogl-texture-2d-sliced-private.h \ - cogl-texture-3d-private.h \ - cogl-texture-private.h \ - cogl-texture-rectangle-private.h \ - cogl-vertex-array-private.h \ - cogl-vertex-attribute-private.h \ - cogl-vertex-buffer-private.h \ - cogl-blend-string.h \ - cogl-clip-stack.h \ - cogl-context.h \ - cogl-debug.h \ - cogl-defines.h \ - cogl-deprecated.h \ - cogl-handle.h \ - cogl-internal.h \ - cogl-matrix-mesa.h \ - cogl-matrix-stack.h \ - cogl-spans.h \ - cogl-profile.h \ - cogl-util.h \ - driver \ - tesselator \ - winsys - -EXTRA_HFILES= - -# Images to copy into HTML directory. -# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES = \ - fill-rule-non-zero.png \ - fill-rule-even-odd.png \ - quad-indices-order.png \ - quad-indices-triangles.png \ - cogl_ortho.png - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -# e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files = \ - blend-strings.xml - -# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded -# These files must be listed here *and* in content_files -# e.g. expand_content_files=running.sgml -expand_content_files = \ - blend-strings.xml - -# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. -# Only needed if you are using gtkdoc-scangobj to dynamically query widget -# signals and properties. -# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) -# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) - -INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/clutter -I$(top_srcdir)/clutter/cogl -I$(top_builddir)/clutter/cogl -DCOGL_ENABLE_EXPERIMENTAL_API $(CLUTTER_CFLAGS) -GTKDOC_LIBS=$(top_builddir)/clutter/libclutter-@CLUTTER_WINSYS@-@CLUTTER_API_VERSION@.la $(CLUTTER_LIBS) - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include $(top_srcdir)/gtk-doc.make - -# Other files to distribute -# e.g. EXTRA_DIST += version.xml.in - -EXTRA_DIST += \ - fill-rule-non-zero.png \ - fill-rule-even-odd.png \ - quad-indices-triangles.png \ - quad-indices-order.png \ - cogl_ortho.png diff --git a/doc/reference/cogl/blend-strings.xml b/doc/reference/cogl/blend-strings.xml deleted file mode 100644 index 0b37757..0000000 --- a/doc/reference/cogl/blend-strings.xml +++ /dev/null @@ -1,129 +0,0 @@ - - -]> - - - -Material Blend Strings -3 -COGL Library - - - -Material Blend Strings -A simple syntax and grammar for describing blending and texture -combining functions. - - - -Cogl Blend Strings - -Describing GPU blending and texture combining states is rather awkward to do -in a consise but also readable fashion. Cogl helps by supporting -string based descriptions using a simple syntax. - - -
-Some examples - -Here is an example used for blending: - -"RGBA = ADD (SRC_COLOR * (SRC_COLOR[A]), DST_COLOR * (1-SRC_COLOR[A]))" - -In OpenGL terms this replaces glBlendFunc[Separate] and -glBlendEquation[Separate] - -Actually in this case it's more verbose than the GL equivalent: - - -glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - -But unless you are familiar with OpenGL or refer to its API documentation -you wouldn't know that the default function used by OpenGL is GL_FUNC_ADD -nor would you know that the above arguments determine what the source color -and destination color will be multiplied by before being adding. - - -Here is an example used for texture combining: - -"RGB = REPLACE (PREVIOUS)" -"A = MODULATE (PREVIOUS, TEXTURE)" - - -In OpenGL terms this replaces glTexEnv, and the above example is equivalent -to this OpenGL code: - - - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); - glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); - glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); - glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_COLOR); - glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); - glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_COLOR); - - -
- -
-Here's the syntax - - -<statement>: - <channel-mask>=<function-name>(<arg-list>) - - You can either use a single statement with an RGBA channel-mask or you can use - two statements; one with an A channel-mask and the other with an RGB - channel-mask. - -<channel-mask>: - A or RGB or RGBA - -<function-name>: - [A-Za-z_]* - -<arg-list>: - <arg>,<arg> - or <arg> - or "" - - I.e. functions may take 0 or more arguments - -<arg>: - <color-source> - 1 - <color-source> : Only intended for texture combining - <color-source> * ( <factor> ) : Only intended for blending - 0 : Only intended for blending - - See the blending or texture combining sections for further notes and examples. - -<color-source>: - <source-name>[<channel-mask>] - <source-name> - - See the blending or texture combining sections for the list of source-names - valid in each context. - - If a channel mask is not given then the channel mask of the statement - is assumed instead. - -<factor>: - 0 - 1 - <color-source> - 1-<color-source> - SRC_ALPHA_SATURATE - - -
- - -
- - -
diff --git a/doc/reference/cogl/cogl-docs.xml.in b/doc/reference/cogl/cogl-docs.xml.in deleted file mode 100644 index c6f2942..0000000 --- a/doc/reference/cogl/cogl-docs.xml.in +++ /dev/null @@ -1,206 +0,0 @@ - - -]> - - - - Cogl Reference Manual - for Cogl &version; - - - 2008 - OpenedHand LTD - - - - 2009 - 2010 - Intel Corporation - - - - - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free - Documentation License, Version 1.1 or any later - version published by the Free Software Foundation with no - Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. You may obtain a copy of the GNU Free - Documentation License from the Free Software - Foundation by visiting their Web site or by writing - to: - -
- The Free Software Foundation, Inc., - 59 Temple Place - Suite 330, - Boston, MA 02111-1307, - USA -
-
-
- -
- - - Cogl - a modern 3D graphics API - -
- About Cogl - - Cogl is a modern 3D graphics API with associated utility - APIs designed to expose the features of 3D graphics hardware - using a more object oriented design than OpenGL. The library has - primarily been driven by the practical needs of Clutter but it - is not tied to any one toolkit or even constrained to developing - UI toolkits. - -
- - - - - - - - - - - - - - - - - -
- - - Cogl experimental API - -
- About the experimental API - - Cogl has some experimental API developers are welcomed to play - with. The main drawback when using those is that there is no API - stability guarantee, functions flagged as experimental could be changed - or removed in future versions of the library. To use this experimental - API you will need to define - COGL_ENABLE_EXPERIMENTAL_API before including - <clutter/clutter.h> or - <cogl/cogl.h>. - -
- - - - - -
- - - Cogl deprecated API - -
- - About the deprecated API - - Cogl has evolved from once being a thin abstraction over - OpenGL and GLES where a lot of OpenGL's state machine style APIs - were simply rebranded as Cogl API into the more distinguished API - style we have today. The result of this evolution though is that - some of the APIs are considered deprecated and because we plan to - remove them at the next opportunity we have to break the API - developers should aim to avoid these functions to keep their code - working with future major versions of Cogl. - -
- - - - - - - - - -
- - - Glossaries - - - - - - Index of all symbols - - - - - Index of deprecated symbols - - - - - Index of new symbols in 0.8 - - - - - Index of new symbols in 1.0 - - - - - Index of new symbols in 1.2 - - - - - Index of new symbols in 1.4 - - - - - Index of new symbols in 1.6 - - - - - License - - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General - Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) - any later version. - - - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for - more details. - - - - You may obtain a copy of the GNU Library General - Public License from the Free Software Foundation by - visiting their Web - site or by writing to: - -
- Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA -
-
-
- -
diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt deleted file mode 100644 index 359bfac..0000000 --- a/doc/reference/cogl/cogl-sections.txt +++ /dev/null @@ -1,660 +0,0 @@ -
-cogl -General API -CoglObject -cogl_object_ref -cogl_object_unref -CoglUserDataKey -cogl_object_get_user_data -cogl_object_set_user_data -COGL_INVALID_HANDLE -CoglHandle -cogl_handle_ref -cogl_handle_unref - - -CoglFuncPtr -CoglPixelFormat -CoglBufferTarget -CoglBufferBit -CoglAttributeType - - -CoglFeatureFlags -cogl_get_features -cogl_features_available -cogl_get_proc_address -cogl_get_option_group - - -cogl_push_matrix -cogl_pop_matrix -cogl_scale -cogl_translate -cogl_rotate -cogl_transform -cogl_frustum -cogl_perspective -cogl_ortho - - -cogl_get_modelview_matrix -cogl_set_modelview_matrix -cogl_get_projection_matrix -cogl_set_projection_matrix -cogl_set_viewport -cogl_get_viewport - - -cogl_clear -cogl_set_backface_culling_enabled -cogl_get_backface_culling_enabled - - -CoglFogMode -cogl_set_fog -cogl_disable_fog - - -cogl_set_source -cogl_set_source_color -cogl_set_source_color4ub -cogl_set_source_color4f -cogl_set_source_texture -cogl_get_source -cogl_push_source -cogl_pop_source - - -CoglReadPixelsFlags -cogl_read_pixels - - -cogl_flush -cogl_begin_gl -cogl_end_gl - - -COGL_TYPE_ATTRIBUTE_TYPE -COGL_TYPE_BLEND_STRING_ERROR -COGL_TYPE_BUFFER_ACCESS -COGL_TYPE_BUFFER_BIT -COGL_TYPE_BUFFER_TARGET -COGL_TYPE_BUFFER_UPDATE_HINT -COGL_TYPE_BUFFER_USAGE_HINT -COGL_TYPE_DEBUG_FLAGS -COGL_TYPE_DRIVER_ERROR -COGL_TYPE_FEATURE_FLAGS -COGL_TYPE_FIXED -COGL_TYPE_FOG_MODE -COGL_TYPE_HANDLE -COGL_TYPE_INDICES_TYPE -COGL_TYPE_MATERIAL_ALPHA_FUNC -COGL_TYPE_MATERIAL_FILTER -COGL_TYPE_MATERIAL_LAYER_TYPE -COGL_TYPE_PIXEL_FORMAT -COGL_TYPE_READ_PIXELS_FLAGS -COGL_TYPE_SHADER_TYPE -COGL_TYPE_TEXTURE_FLAGS -COGL_TYPE_VERTICES_MODE - - -COGL_DRIVER_ERROR -CoglDriverError -cogl_attribute_type_get_type -cogl_buffer_bit_get_type -cogl_buffer_target_get_type -cogl_debug_flags_get_type -cogl_driver_error_get_type -cogl_feature_flags_get_type -cogl_fixed_get_type -cogl_fog_mode_get_type -cogl_handle_get_type -cogl_indices_type_get_type -cogl_material_alpha_func_get_type -cogl_material_filter_get_type -cogl_material_layer_type_get_type -cogl_pixel_format_get_type -cogl_read_pixels_flags_get_type -cogl_shader_type_get_type -cogl_texture_flags_get_type -cogl_vertices_mode_get_type -COGL_AFIRST_BIT -COGL_A_BIT -COGL_BGR_BIT -COGL_PIXEL_FORMAT_24 -COGL_PIXEL_FORMAT_32 -COGL_PREMULT_BIT -COGL_UNORDERED_MASK -COGL_UNPREMULT_MASK -
- -
-cogl-clipping -Clipping -cogl_clip_push_rectangle -cogl_clip_push_window_rectangle -cogl_clip_push_from_path -cogl_clip_push_from_path_preserve -cogl_clip_pop -
- -
-cogl-primitives -Primitives -cogl_rectangle -cogl_rectangles -cogl_rectangle_with_texture_coords -cogl_rectangles_with_texture_coords -cogl_rectangle_with_multitexture_coords -cogl_polygon -
- -
-cogl-paths -Path Primitives -cogl_is_path -cogl_path_new -cogl_get_path -cogl_set_path -cogl_path_copy -cogl_path_move_to -cogl_path_close -cogl_path_line_to -cogl_path_curve_to -cogl_path_arc -cogl_path_rel_move_to -cogl_path_rel_line_to -cogl_path_rel_curve_to -cogl_path_line -cogl_path_polyline -cogl_path_polygon -cogl_path_rectangle -cogl_path_round_rectangle -cogl_path_ellipse - - -CoglPathFillRule -cogl_path_set_fill_rule -cogl_path_get_fill_rule -cogl_path_fill -cogl_path_fill_preserve -cogl_path_stroke -cogl_path_stroke_preserve -
- -
-cogl-bitmap -Bitmaps -CoglBitmap -cogl_bitmap_new_from_file -cogl_bitmap_get_size_from_file -cogl_is_bitmap -CoglBitmapError -COGL_BITMAP_ERROR - -cogl_bitmap_error_get_type -cogl_bitmap_error_quark -
- -
-cogl-texture -Textures -CoglTextureVertex -CoglTextureFlags -cogl_texture_new_with_size -cogl_texture_new_from_file -cogl_texture_new_from_data -cogl_texture_new_from_foreign -cogl_texture_new_from_bitmap -cogl_texture_new_from_sub_texture -cogl_is_texture - - -cogl_texture_get_width -cogl_texture_get_height -cogl_texture_get_format -cogl_texture_get_rowstride -cogl_texture_get_max_waste -cogl_texture_is_sliced -cogl_texture_get_gl_texture -cogl_texture_get_data -cogl_texture_set_region - - -COGL_TEXTURE_MAX_WASTE -
- -
-cogl-texture-3d -3D textures -cogl_texture_3d_new_with_size -cogl_texture_3d_new_from_data -cogl_is_texture_3d -
- -
-cogl-shaders -Shaders and Programmable Pipeline -CoglShaderType -cogl_create_shader -cogl_is_shader -cogl_shader_source -cogl_shader_compile -cogl_shader_get_info_log -cogl_shader_get_type -cogl_shader_is_compiled - - -cogl_create_program -cogl_is_program -cogl_program_attach_shader -cogl_program_link -cogl_program_get_uniform_location -cogl_program_set_uniform_1f -cogl_program_set_uniform_1i -cogl_program_set_uniform_float -cogl_program_set_uniform_int -cogl_program_set_uniform_matrix -
- -
-cogl-offscreen -Offscreen Buffers -cogl_offscreen_new_to_texture -cogl_is_offscreen -cogl_set_framebuffer -cogl_push_framebuffer -cogl_pop_framebuffer -cogl_set_draw_buffer -cogl_pop_draw_buffer -cogl_push_draw_buffer -
- -
-cogl-fixed -Fixed Point API -CoglFixed -COGL_FIXED_BITS -COGL_FIXED_Q -COGL_FIXED_MAX -COGL_FIXED_MIN - - -COGL_FIXED_FROM_FLOAT -COGL_FIXED_TO_FLOAT -COGL_FIXED_FROM_INT -COGL_FIXED_TO_INT -COGL_FIXED_FROM_DOUBLE -COGL_FIXED_TO_DOUBLE -COGL_FLOAT_TO_INT -COGL_FLOAT_TO_UINT - - -COGL_FIXED_EPSILON -COGL_FIXED_1 -COGL_FIXED_0_5 -COGL_FIXED_30 -COGL_FIXED_45 -COGL_FIXED_60 -COGL_FIXED_90 -COGL_FIXED_120 -COGL_FIXED_180 -COGL_FIXED_240 -COGL_FIXED_255 -COGL_FIXED_270 -COGL_FIXED_360 - - -COGL_FIXED_MUL -COGL_FIXED_DIV -COGL_FIXED_MUL_DIV -COGL_FIXED_FAST_DIV -COGL_FIXED_FAST_MUL -COGL_FIXED_FRACTION -COGL_FIXED_FLOOR -COGL_FIXED_CEIL - - -COGL_FIXED_2_PI -COGL_FIXED_PI -COGL_FIXED_PI_2 -COGL_FIXED_PI_4 -COGL_RADIANS_TO_DEGREES - - -COGL_SQRTI_ARG_10_PERCENT -COGL_SQRTI_ARG_5_PERCENT -COGL_SQRTI_ARG_MAX -cogl_sqrti - - -cogl_fixed_atan2 -cogl_fixed_atan -cogl_fixed_cos -cogl_fixed_log2 -cogl_fixed_pow -cogl_fixed_pow2 -cogl_fixed_sin -cogl_fixed_sqrt -cogl_fixed_tan -cogl_fixed_div -cogl_fixed_mul -cogl_fixed_mul_div - - -CoglAngle -COGL_ANGLE_FROM_DEG -COGL_ANGLE_FROM_DEGX -COGL_ANGLE_TO_DEG -COGL_ANGLE_TO_DEGX -cogl_angle_cos -cogl_angle_sin -cogl_angle_tan - - -cogl_double_to_fixed -cogl_double_to_int -cogl_double_to_uint -
- -
-cogl-color -Color Type -CoglColor -cogl_color_new -cogl_color_copy -cogl_color_free -cogl_color_init_from_4f -cogl_color_init_from_4fv -cogl_color_init_from_4ub -cogl_color_set_from_4ub -cogl_color_set_from_4f - - -cogl_color_get_red -cogl_color_get_green -cogl_color_get_blue -cogl_color_get_alpha - - -cogl_color_get_red_byte -cogl_color_get_green_byte -cogl_color_get_blue_byte -cogl_color_get_alpha_byte - - -cogl_color_get_red_float -cogl_color_get_green_float -cogl_color_get_blue_float -cogl_color_get_alpha_float - - -cogl_color_set_red -cogl_color_set_green -cogl_color_set_blue -cogl_color_set_alpha - - -cogl_color_set_red_byte -cogl_color_set_green_byte -cogl_color_set_blue_byte -cogl_color_set_alpha_byte - - -cogl_color_set_red_float -cogl_color_set_green_float -cogl_color_set_blue_float -cogl_color_set_alpha_float - - -cogl_color_premultiply -cogl_color_unpremultiply -cogl_color_equal -
- -
-cogl-vertex-buffer -Vertex Buffers -cogl_vertex_buffer_new -cogl_vertex_buffer_get_n_vertices -cogl_vertex_buffer_add -cogl_vertex_buffer_delete -cogl_vertex_buffer_submit -cogl_vertex_buffer_disable -cogl_vertex_buffer_enable -CoglVerticesMode -cogl_vertex_buffer_draw -cogl_is_vertex_buffer - - -CoglIndicesType -cogl_vertex_buffer_indices_new -cogl_vertex_buffer_draw_elements -cogl_vertex_buffer_indices_get_for_quads -cogl_is_vertex_buffer_indices - - -cogl_vertex_buffer_indices_get_type -
- -
-cogl-matrix -Matrices -CoglMatrix -cogl_matrix_init_identity -cogl_matrix_copy -cogl_matrix_equal -cogl_matrix_free -cogl_matrix_frustum -cogl_matrix_ortho -cogl_matrix_perspective -cogl_matrix_multiply -cogl_matrix_rotate -cogl_matrix_translate -cogl_matrix_scale -cogl_matrix_init_from_array -cogl_matrix_get_array -cogl_matrix_get_inverse -cogl_matrix_transform_point -cogl_matrix_project_points -cogl_matrix_transform_points -
- -
-cogl-material -Materials -CoglMaterial -CoglMaterialLayer -CoglMaterialLayerCallback -cogl_material_new -cogl_material_copy -cogl_is_material -cogl_material_set_color -cogl_material_set_color4ub -cogl_material_set_color4f -cogl_material_get_color -cogl_material_set_ambient -cogl_material_get_ambient -cogl_material_set_diffuse -cogl_material_get_diffuse -cogl_material_set_ambient_and_diffuse -cogl_material_set_emission -cogl_material_get_emission -cogl_material_set_specular -cogl_material_get_specular -cogl_material_set_shininess -cogl_material_get_shininess -CoglMaterialAlphaFunc -cogl_material_set_alpha_test_function -COGL_BLEND_STRING_ERROR -CoglBlendStringError -cogl_material_set_blend -cogl_material_set_blend_constant -cogl_material_set_point_size -cogl_material_get_point_size -cogl_material_set_layer -cogl_material_remove_layer -cogl_material_set_layer_combine -cogl_material_set_layer_combine_constant -cogl_material_set_layer_matrix -cogl_material_set_layer_point_sprite_coords_enabled -cogl_material_get_layer_point_sprite_coords_enabled -cogl_material_get_n_layers -CoglMaterialFilter -cogl_material_set_layer_filters -CoglMaterialLayerType -cogl_material_layer_get_type -cogl_material_layer_get_texture -cogl_material_layer_get_min_filter -cogl_material_layer_get_mag_filter -CoglMaterialWrapMode -cogl_material_set_layer_wrap_mode -cogl_material_set_layer_wrap_mode_s -cogl_material_set_layer_wrap_mode_t -cogl_material_set_layer_wrap_mode_p -cogl_material_get_layer_wrap_mode_s -cogl_material_get_layer_wrap_mode_t -cogl_material_get_layer_wrap_mode_p -cogl_material_wrap_mode_get_type -cogl_material_set_user_program -cogl_material_get_user_program -cogl_material_set_depth_range -cogl_material_get_depth_range -cogl_material_set_depth_test_enabled -cogl_material_get_depth_test_enabled -cogl_material_set_depth_test_function -cogl_material_get_depth_test_function -cogl_material_set_depth_writing_enabled -cogl_material_get_depth_writing_enabled -cogl_material_foreach_layer - - -cogl_blend_string_error_get_type -cogl_blend_string_error_quark -
- -
-cogl-buffer -Buffers -cogl_is_buffer -cogl_buffer_get_size -CoglBufferUsageHint -cogl_buffer_set_usage_hint -cogl_buffer_get_usage_hint -CoglBufferUpdateHint -cogl_buffer_set_update_hint -cogl_buffer_get_update_hint -CoglBufferAccess -cogl_buffer_map -cogl_buffer_unmap -cogl_buffer_set_data - - -cogl_pixel_buffer_new -cogl_pixel_buffer_new_for_size -cogl_is_pixel_buffer - - -cogl_texture_new_from_buffer - - -cogl_buffer_access_get_type -cogl_buffer_update_hint_get_type -cogl_buffer_usage_hint_get_type -
- -
-cogl-vector -Vectors -cogl_vector3_init -cogl_vector3_init_zero -cogl_vector3_equal -cogl_vector3_equal_with_epsilon -cogl_vector3_copy -cogl_vector3_free -cogl_vector3_invert -cogl_vector3_add -cogl_vector3_subtract -cogl_vector3_multiply_scalar -cogl_vector3_divide_scalar -cogl_vector3_normalize -cogl_vector3_magnitude -cogl_vector3_cross_product -cogl_vector3_dot_product -cogl_vector3_distance -
- -
-cogl-gtype -GType Integration API -cogl_gtype_matrix_get_type -
- -
-cogl-deprecated -General API (Deprecated) -cogl_check_extension -cogl_viewport - -cogl_get_bitmasks - -cogl_set_depth_test_enabled -cogl_get_depth_test_enabled -
- -
-cogl-clipping-deprecated -Clipping (Deprecated) -cogl_clip_push -cogl_clip_push_window_rect -cogl_clip_ensure -cogl_clip_stack_save -cogl_clip_stack_restore -
- -
-cogl-texture-deprecated -Textures (Deprecated) -cogl_texture_ref -cogl_texture_unref -
- -
-cogl-material-deprecated -Materials (Deprecated) -cogl_material_ref -cogl_material_unref -cogl_material_get_layers -
- -
-cogl-vertex-buffer-deprecated -Vertex Buffers (Deprecated) -cogl_vertex_buffer_ref -cogl_vertex_buffer_unref -
- -
-cogl-shaders-deprecated -Shaders and Programmable Pipeline (Deprecated) -cogl_shader_ref -cogl_shader_unref - - -cogl_program_ref -cogl_program_unref -cogl_program_use -cogl_program_uniform_1f -cogl_program_uniform_1i -cogl_program_uniform_float -cogl_program_uniform_int -cogl_program_uniform_matrix -
- -
-cogl-offscreen-deprecated -Offscreen Buffers (Deprecated) -cogl_offscreen_ref -cogl_offscreen_unref -
diff --git a/doc/reference/cogl/cogl_ortho.png b/doc/reference/cogl/cogl_ortho.png deleted file mode 100644 index 2c2a1fd20be98e26e1ef6f3eb2bc664970f5fc62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12650 zcmb_@cRbbq`}g}CP6p2^64 z`FzLk`+5An_x;y>9uJkH^Ios(^}L?r5~Oll?kqkvK7t@;735{r5Co+SUm|#DcqjM$ zwi*0|a#oX*LGr)RF2FZu9OQMK5#-#xlP^@3ROSPC^YlZ7TQ^P*W2jN0JPyyvrV)ez zQIM6^a2sAp^3W$8C~Fa7oI2{mx*Ld~OWp9P<{R72OKHk$kS(ivmRWibl|8-@QtF$z zc>a7y)-Nr+g9!9p4Hdfcxmam3D{24I8FFdPE7F1TgaO2USQ)3|Sm&))Htf%)US6j(@b5nrO~2ql7K!KJ0bjrgA29w&VL&l{8V_4P;vITEGl z<5PDx7ptd7Gs=Rfa3&=sUB7;PF&BL&MKUk}7g02GbK7f;WP^8BR#qG$5$uq-$FA}% zP2ctzk|5cN>qx4`*RNkiMMe8GFv(Irb`}<=h0Y*R!C_%%6FRhv$lX>-2PRojzG~eA z1C&9sRypV^hSeVm3;p2WZKqmd5#e0qS!0}tGwUcLq9SNgsB=pb%Ru~6p5^4&Rh+!y z;)La=5&m2`-z_}}+MNf9{DOkxwO%9j^}dSfqQb)18RQ`@Gjm#Pt)#lTdZ{%*mT)j* z((Q9ZMBm!lL?6z-Oi3|PP&lJOgq8bHQu5QOa&eGZ#Y``?uC6XCYyQvCfsp+;*X7I1 zk*yxP%c@@Yaghwn<;%INt9AzTly3Xm50sTdD=S50zI1nQ6n9GAFCLPRkWi6A4C+69 zLKl=F=Z(&E_4caAQI5M!pB);DCc@D}97KMDg+Q5j{(DvGp4tH`H(DWR=s@ z{QivITb=o+(! zINcJS5Emy6_bP{Z?BVhKHfGQBPe~Tm$!T+QrhTp>;j{owm!zVSQsk>w@bli@UZZL^ zMhQC;6Ex>KeNj=-7t?FeiqXT!&Z#a|3N9Uoqy3%DO(!KKrJ?l4H*el_yFvfiS$}e- zJ?8f9+c^)r;2%B*E9E;&12Hi%N-VGX`}b2KOM7^DV6na-Aq2v* z)1xv>5ijVaYTdVHH#avUjsx?{F+2tzw`XFE%q=XQ1)RL{45|dLUF(^cpwFowd!s@{ zP2D!*goA@~j#k)Vy7}yS(9Mb)JVo>Vr_ae;zkVl4^pY#JU9U6Cp5tO)_S2`Q&ZG)@ zZgmLJd#4jZiIZ)t5-!1Q!+LK?d=4NQE_o+>{Ol0^=myV-@cXkSYsP{}8(EclpFVxEvbNUc(vp$+ zg8NjH@Awwz`*?x4q`lFnI17F50#j1*7C{Hm-KhY ziGyT&zRSY7bi$Pmx}siM4Js=R$(N%2j6Y_$`Rhgb!3)dqQoZDX7HY__E%XAPR=)n3 zj?D+Sdd?hTBY9O-2{Lbd^-7w#Pn|mD<>jTWjS`nT&G_lr-Kp8x*~P`XMn+e>ew3D% z_geBhg!ET5b#)QPkWIPe_y#wIp$b^8T`NjWMXIheH8t_@@N{9-eac}SP5f}+ft9FW zsHv$1Z3gR23ds^1r#D_jM*dnEc~)?*?r^ic|GgeLWmtphweX8#WscL$^xk{Yy^pxr z+2_}Mjy*Iq`hIWCT`~9=6(5hU%kq7KTZ6MSJ3HuR+QQOO?oG^kqF9CZ(c>mI-ng&6 zzP|naT9~=0*ROeWi%h@gXx>la6&4m&ZH!MyI7cTwKRLO+w{gG8LQ7lwSzw?7%PYNd zI}uUQ@e0TLBu&{gP&{E_VJ3xC=4Y*f_1wghRoFde9&BuE{8}ATFR1h{NNk*3Sb$2t zwGa@dy0NvTe&{syvo(@b;A>Np*+NhHv# z6B9>N@#xvpr%wq92~EQvy1H7Jn@hTHn!*Nsc8=b#(rL!$Xuu~uJ-w;9`CGgIffySf zUu2WXnZQqf{`{#sTCsop_;GD*?Vy~E;K7#&=8lezk#hT%j60d{-qA{W#wxSQ$;llY z9NaO}*Jg@%mzgOfAn?7v|67Wb58QBRY3YLp4*=P3+_=F-ahaF*LwY)<;0J+~l~_o`#KhRx*iQLR{rvfGYqsO);MaY&!@cQncXxN~e0^y= z+wp1il-r+Xc4v|PAwp~_`tb8D;k!-v?epNdViB2J%2M#NZI zXJO?-D6h;qRT}vm2?WaAGh;0EyAA7oodL*Tg2_Vvwr#VW!IJA zz@6IFiMo`iC>9Au35lbcU*nBsG2D7u`uf!mdRc8KV&dY4D2+V*Y~kzzf`TTC45w2% zuW)l;Y-c%r`n0|MT13l`jUY4$Lc+YfJXyTT%1SdcGpK6mLlbNzFB=*fq>c~O{WQ~Zu$r3DZ{FN9 zGNLb|Atw(sF2YHTF0cGu8WdNyEx4x*w>19Z+*CI?BnI>Y3Osbla<9TnNsI4^(j6+9v(ny zDnr0a74|3rx1J`HFFpfF(BgLr*!Zt#DA_qUV8N7G`M9}nv5)|AWTvMx2JjeGe=#pU zFSEP5%fZ31R(Jg835H;{BVlfJ_0O2=MD**|uVZ3_`1$oKozjbo`2+;W86VEHMepvq z@JF;p7k$vl3k@X<=&E#{17d-P`)R1y;^M`Nb^D9CH$o`POig8FWgUbQ-@Rj@2#JRN zl#&uY_~R{pwI=d{1QVAlRxS4U@icbABe5I#rBcH7j# z;xdt5|Hz0nJdvHC36sLT?ld_Tl2+Kjm?jjmdbqz-aDrO_-VfVW&MQCEpWIy;fdbK4 zMWDMs*qVwCN#6+Gy3Rm6`z`69t(TuEk2p1fii#?0%+v1-X6k&9EIB#3UYX6tuV3Y5 zWwRS@gFMwGrxEgS0_Bl}PXJ;+e*DPQF8H%MVh?*C_EJb#SfHB@!u!S%^+qM@CMWM= z9%GX+&W^(slyQ$ON`IW}$L|-&sU8%T)C1S;8+A|AWHqq5)VwmJ`Zf-7Yx(@72oJK* z+V`@#xfvjUhKfohTLa47;klqR192)hQjHc(qNAlvjE;UZ-^C~;Rrl%@$@-aXJS^tn zbHI|fZ{HsLTAQeLFV4#&)blwLl7YoUWuYT=)bZG(p+7Z${%owyOMCI6)WI^JV8U2$ zFHW)_onKKihE>#+SVd5WlZS)P;#)~sSy@pLy3#6Q_E2TSk&iOZdX>CPmTgKr}UhDE7iM;3LMzv{}#a&of z*b+|P@y8Jo zAhDx{dOnq#Y-(l}(Q3*W9lWyn+jBk0d}?7qA+r~F^0UT>gkLupi2L&8c)4v+g*u5T zDS#<`Jw0fFn=jg9uJBP2iiuSLO*-Z82*AHJ*XggvpF8|DSz_edw|uytqN2?t*YOB- zlzwup+b*7l6b}O#KJe#CeLG|0N!X-zqZOzfy|#3vm|7^N<>lp|j!HpMS6(KmLV^sw%N(jed!vz8TsH zz zK&Xk${rl5%bD7hey!V?41qx-=bHX?qZk?c6@CbS^UgW{5bAXDgt5Befsu1PK@UUWU zKGORFj;Q&zq4??O=%~Jd!P3%Fdhq!8`0ccAxGhml+l+CJu4Ucp5fKp>3?`N`I3&bC zU;l&{!PU=OF(+^wM6)d|EZp*PEIbuXz!31{$rEZCnzXlX#l^*ggM-!7)ft;nAx$4W ze_sod9jyr)sj^=I6X1a{hy_yIkKissCkkC%Jox|o& z1@fpO&)-hk+5;T%nbhi;l#lWSDJUqWZIZK+@UfmKOsFWghJrHFd?Xx_pFCD{QGf?2 zeA>)(>C(*lRHNxN;5@?<6Dc>-W@cuN{v51%N~Xv%t&G<|?GiEejg2M6#fk9q%ciT5 zl90HGkF%wC7Fm7IX(ituv9C)KcUNO4vl}V9C3^g@&&jNVhK}yrw{Ncn9`)G+{RQ|O z7#KJ{m^gkB9$o-Nfsa32W;+r_BLpS%T=qwU|LL)@v8n#cG_Vb6S&61f@vQ*gq3k{w z+Hy%AA8tKb>c2Olpr9b;vRq$w!rG>%dxwTNBINN22sp?T<>kMuj#YK0NQIk`?(Ym3 zvEA*D7qHIKScE+V!lLBif*KoJW|iw2C%g7H@u8K%+DE@u4XDFrmzEM@V?pbHfS8$_ zB&MWvo%$3AJ2f>mwZ0x(vA|j1+w0s{`jiwcM2?4#Z*ncpLEA7J4VRgppAYEQ@}kc3 zcMsI++IY?2>M(57e1pprA(u$bBy_kudUQ0O7S2MVU~g|fKB%Fk)s|iVElI4%#I-@!)D80i}6IJVwX>)@~vAOWNk@euJ7zhN=uvewFdj{vqlCHQ`6EOZgonL>qE=Z zbI}(4WPk78d17J*xap>u+n??-MX+~ZrCCVKT+g08YnC~WUKAvJm*hJ1TqPWM=Wc z&F=DE|N8oe<%`Fi!oA1#)0?LV+%8pACp4;KjPc(jy?OIyI}sE!;1Zp<+d4d55J|9Q zBQFDU1{%7!u+S05Czt;^^lpBlyHf_|9tCgB*Ca9RkCIM3lax%P!Ob87cjM=Yk*-!-OgFw3E{lR#JZyqgz3IywS`nLLe+K575s ziTF$r&u?eKF=7)E=H}-7uOrcZdf~`0TD^u;mg%)Do<7RbD%@9|f{-6Vwoba z7^KwXZ3FdrnST-m4BNnyR3bmdA+=j1g!gGV`ER?K@sVv zsJ}EH()U^* zbX3l*6yu4^;Ka%(ObZL=zwfqyjTN571)JL(y3$R=Snd=H*Vf!3MeWrPCsow z_E8{=wRJX>B1ksH=g)7T7oZK@#go(1FRf0as<{%u-XNN}*>(6oAiBMQ{>4_91UTU$KFA)Okqcuq{oc-%kT`hPQ0;yo6> zGlOVTapa-S!!a>6<=YS;U7Du z)UU5oQ!-3up*igcDnK}X{HWN=cLw(fh!^UxQ_(nwY0Q%XJiZC|R2ME}OUl`rnwm;W zqbR1cDk=uSK!7%=B2q6!9cJ^*@_Py9xp0o};=p-a3_ZSMT-8fxFv}R=go74{ezS|3EwWW@axbDQTu*qIo%n*BlHC zARum=*6BVZq@-|^^D-a{z>IS0ZYYU%G|$tns`StCkwfOu&}DjV7Cd`)TJo&1Eee+E zC^nW#pAZb7w$4tYn#Tg8GzcY}`c9%S2r)2AG}YDp(`!T=e|!ct=)F2B!W1EF@huUU zQeR(RVj}Iexa#{YM1EM_ZtXX4=0Wo6>gwIK2_NuZ!PRwjbXlW67^<+7;Rk*)=C$M>PL}Wh zsWsb~LQhIs3{(etyX{2n5wt9~?fLUbw_y*uxVV7-30jksduFQf+0f7sNzmuv;m3_n z&x(kM0N*eyv5Y7!-HBk9tFEcJZ(;(Lcdgro2~P|SJV+7}CJX=f?`;hX#>hHiY5o2E z!8TQ|BeLT(wy`1PMA*ZprtU$B*)$YXRUNFa^CoocZf$LCZsz3Wjh0%+ELZt&v|QYQ zx3;%!?Cf3y2g~4fB#MBxeh;?7?()z>Q3-DYyMl9R&; z4-3rmW#NqTAWG7Pd0$^>Gl!jGRe3iHnZ?V>^WBucb<2#G3Oq7>o?kzjLh!#OT8^rU z01^6^V-cPEeY#v)z!n8h0c2O0{7=M^-3NT1TCW3eJOSD&_4A8D5(KO%QabBgR^lJl ziwOz+DjhIXPd`gNM1hba4sz^dCeyccOanmffqy<$>qW!ZH!(5M*T)hepCQZ;*pd0F z4E@2S7RU#Pb2@VJrnxOj9(^4s5F?}Tu;%cR1|V*W=F0ipz9IONzpDc2P`=ExL~I-! zK}{yWf@kLDz_kVss{m{mSW^4yjZ;Cg!9hXU`S}1vf4La8PQ99|qm}B0hJS!XLy16# z>gxk7lyut%R^Y!l5nN#0zB>!1?4?VW)cNl_;o+k7HL&Me7;Cz^x*n`?pzemsvnw)U0di(p7G;)LW$4|{IF7BB}`t;c| z$B^oP`(Hj!_#8_>|BaTWuKPWka87a$OP$dJlB017TcNrhPEm1#os5;072=!FM>62Y zfnadtAm}Xf1)r011g&F!!k0~|dcKaX=iwY%`sqEFefy&_2rO%Ocvb_7{kqKTg6^m7bY-y5O_3 zaISAK^VRDoC#I+Zzf|d%vsBJk@9DKrkcqD2?sC!Zs{o|H)+y4-g8*WoYOU74Bz=;8 z#X$*d*1LBh8KQ}hFDWml|LtGrJoh3cg+U4I zLrB!|@08;>#cvp02ckqvbMyXzfoDowB^x+#?F~|*^AxmA1apq4YjIzv98#a6d{=Yo ztqW?J&5NgqP`;=9itzy)0Mwr7p|IK8zkW>*u01V75KFp~5U#jbU7Z}vJhz%gT*R0w zK;{iRjQAYnBC5C{d4c|h!!G`|-{YGChp!ZoC!4EoIn7MVgYRJjF4tA$>@@1KRL(o)a zHffa9o2X&#Ohx*hIq6x99M z2W16uA*W<!9MHrkXrAD0Yw4dHgB=6hP&M4>A8AtqrI@HFF1jHgU!-~|RQNM$g@CV z0`@JKxX?X-H$z1H`ZYzhA}(T};rH>QsAv*TggkgyKo-H4g<6JBdHf>2qO#KNN7 zUB)c;!p*~@<@0B8pFf@(KboM;0K#Yd)w>&vyDUp2Ja!oZUUTU_(GEgVLpXgOt^Fei zfQ|X=BII}OYHB29Ny*87#y!^VjkLe!zRbfjUh*Ikf?F3z-!sJ+dZS}wlVe@`7C%u-iV8}~Ur z!Vpk=O%UoF8#{tc-T09cE*f|%+?`D@-L8}kSp5` zw58w?Zr+hPf@C>p#oWy7JYE1~58V0{>yXS{*2+`aIClBJMd%!0Up%gSs+E)CodW*p=aPqG0U+6|l9o=Hus2gmH<*@44jF9Jq)jLDqRE z(nmL+WY4dyV%~mQypEl6A+&(%wBtDZclSeK}aUJtn#_SqpKxu-0; zKhJUkwCHX*)Xu)h=g*%lvlc+tfzJcH-t?M#%ZrO>zxwv}+=>ceLBal(mX@9#l9LGm zceo8u_>dt7$-V_mKe~#9C2ymYOa0baf zktl4r0|;YoJ}Y(n`wjpK*S_WL+us&?Gr=PQA##V|WJmm`NV?8K5)u-Usm6p%qGjm= z=hKiZ-{x!F-EuQjk5qAF=>dW?hHJDPx4R=kHBiqb@qO{L2-==YiqgTYrs`Tc(~!dh z@!c)QoZR~SLp=n(MR?{PY-Ewcr;(Ml^X&hOvcPG;WBg~Bbya*F-$(whFiR|%Z{utQ z9t;j0qfS1%jrZ4)s$qtRH-G$c#XtIc*MrHGKDT>?I^aaGM#uv|;o2iG^1!S?k)I2_ zLO`Gtgb?Sfw8K^41wQL%2gvE^Cx(Yb7v)Y27FjZ4ku8P_DumOQPyGzBASXyJkR^F{ z*hE{w&>ek`LG-&OpWjbAh1cHR4)IWDM+Y|t$Hw+HKObKsI`S$NApt?i6-ej~e{Vs{ zyWgaEg`M3E5{_2W&8!sIdVt!xckhCrF*h|mN#>iHFb9^Vl}@uqo9$Po3(KINgOXWT zSb$VV%58lT8tre-KVW@(O*e;~*osi`JL~II?czu*3(2in;0Q+Lc1aI~I5-|au?+4) z4MJKfDketocgOlpy4porTJNKs0o5y1baaMBMp9ai*8O>J)Ur<#(N;WM=;=vUN=i&z z9j_77s$}k<2``2Dk@Rj$V6m|Em07p?vem)Kf}R87CMzcgA6|rnQ3#T68IBK4yW-== z@j4&+5ib~QNk|xh9t?)qe|4%q^uj36mgye&^vRHwkG;>zda3RQcB09MI9(^q7V-0I zNLPYz{C_#tr4;p)EAHw#;IQ%X8pAZt3WUOH>`}1f3;}RCKnx4(O(7%q_V!k0B^A5H zlS&od0-ovu3^lnlnG}YHhud(Rc!*B}18-ol_2B-JM~R78!+zq|5P_MTF#&%5&;2Sm z$P0E=OukW_Bxu~nJByGv0Ik-{)#BKZn%Z!~V|-8|6+j%POebIz>+jzPgeHCN%PBHz zTidZBvvy&=JXrAyR8*mLqpi9G2=(C$u=*o!XGY4i5IviooJ?Il{uw4Tj>Xf|)Kmxu zkygnj()>?P+wh;B_Fg-9+DK{xC$Gn@4Mcws9JIByoiO_gH@-YwdJJ;lqCn7|%h0ON;(j4V&5@KbZMdF!i7&|m=Qwz|4hoSd92E$3fdQX-al zC<<@`%twxaI8ogF8o)FFbsqtzw>s=#AUVMMV7enYG0_uZUU0P~Bx(xVq6Na0S;Jd~ zJ$|iTVq=37iv9ID{c5+uckfJrTz*Rwp(UDwtOCS3Y#aO9-x&`B&`8F<*e6%B4ag@y ztRJYA*-v;c4_=+&UZ%g0pPQZ@*f|HrHx0}H$@Lc)*;`wCK&AyV3Y8TV%9qN*P0LPE-U zHC2HV1pWuu(1ns`iHIa0Es{~YK2b3;GOF-FQtxpZ+u7CH3>6hh!l2!g0~8Yf9$lbZ z4Zg0=?AHqpqDU6G+c$>()z1lB6iYtGzkCWkGZDnruNxXX;E`W2sXfuzv)SgM#37Q3 zY26tn$!&QU--QPdP=b)xNc7M)+Yo2`tG~U-5>93VbT1)+Mu0kL1WDNK?hPDhcF!eq zj-YvD<>duHFOjAHPUR3JDN15fRzwEP!;*eD4P7BipF~XTMds^@yNEgI5e9!X7DQdn ze}atZk}SPfpsCEZDwd`}WIt=s4-S*M#K}v?OYR$pMN$K&(bKpmEoU_cLWQ@z3y^uh zEEyE8Lmdh$=YfkL^N+*-sSKNCr!9#2;=Y1?3tQ_KG)`EHCJNAwsh2rb)YVVSJ&<)U z8o{ks1~I$G+w%5BmQTO440|{e&DrDD~O7rI#<8Q8=lya12z9?M{?bblVwtXrqtRh;uGt}CP>!A*0$ze<5N&vfSOnCmV6l=-UliP>GsvDSAn6zkmuEy_9GZp zfeA7h8JVA7!OHB`umK_N=Xh0I9P)HN*H!(1m;dq`%fP(+o8`EKQ(5u_I5W&Y!Q~I; z*VIUq^-XkkLVG9%^#sy{k>7dtYe`87sBdt;dKb1q7q+!22E0s2(9_a_nXAz(^H4J! zP`Hypg@umb_gYxYl}~twNZ6!@tV8fp*+@ERU2Il$G@l568F9 zaE@3Pn|J)!`VH}}9@y0`EHJg!6igl+9i79EgE&a*+T+8O59H~B$E&8Rn=O8Z7(Y-4 z?*q)iFaahOqZdHB#L(sV*Vq&oTs_bMh9+j@IuLI0Qw6wRije8&1y1M=X`zgD) zcngXJxCEr^me$tRR#taQEYDL=+N=zhUNNeTl4sH9aea3IT<+;Y6jH)+SwTkT34c;E zMC~v)_}cF}<~T@&-NxFwQO4Ctn3nu-92`D+Nl%zZ7OsJZO>K55qNCY;dtMdD7?>fT zn%Ec^>Q968yF%%;4NSyW3?JzoVpfrW*=qpZ zQ*XmL(Ey}f%qm8IG47A}U#>RIr#Z>baa;#cqk+92YXY?2nA7*<$DFCs%9r-%1AOPx zd|$u06xUujpLXWVnVd7rjA4?T60Z^xV2^3q02bk6;nVdvXTzeN+HZFko_v5OHB-QO z4Mv6Jxc9|-zj%gEcwC)Mi7M?w`KEXjGz1;f|(dd diff --git a/doc/reference/cogl/fill-rule-even-odd.png b/doc/reference/cogl/fill-rule-even-odd.png deleted file mode 100644 index 1e4fbb0f2a2dc04953609dfb942f48db046e46c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3121 zcmb7Gc|4Tc8-HiPkU=SBWEr`%a7}j*VGOcWqTHJrVPu&ZvX1OiV~I~mDUxN<$dbB7 zY6c;Dv@k<B)-w{bp(ui5|AX7016?3|7KF+7 z{)6924RwRCvIx%l7ZxdEs+W51pL)Ga>ZqSNtOtk<3rIl=zU!LnJ=qC;g%$K#*tud|YePErg3$5j8yC zGrwz&n`NK{4gx|=rw_cq;p{9sTk&#zN^R?587+7{-wtr5!qqd?ME zD(?zWlYuUX)qixAZg9ULYSiAC>Y;lQA#^wJc_r=lHwEr{pwj)2CJfj;IhP(2ST@ZW+c}uA*N*xm($z?(scfC=>~+5`;W9p zR%aLW2UCGSVTsejsnkuH78M3$4To%C!XrbhFgZ7M@*#BkiluF|b_pT3G2UTm^{JmY z{_oaPX3r~>5ClmWcy0gI%J1)q3)=$#teQLD1!3JsZ$xHiY_5-DP*fZo3q)b8zsb2( zyZN+#_$uAEP-+e?!tMQonAF#Y zOESX9L#X=e6C0lTB#hYtyGOOQCutR#T zhqc~SRqqJnzRg`adVjX=ik{$l?o4yclBud^ZQ2>3IJE!4y`Aj|>}Rhoq^Awnq-rwq zaP2l7iwFBmt~!4zT2@gBxz1{-d~c`Ae-oe#>IIiMMZ>ikXokGrz}`t6bMa&y!3}cn z+ZkHYh&U92+?Fcja|S^FNZyg~;C^QGPoDH1jG|@Uyd?CzK-#v5!=})-q-JQo zz&-s;`^Wav*i^O4qIuTpE*B*ZHmrMg>AP~9d+WP1O*26&U$^3(TJWn`8rw5v7dl=I zjE@c4Cx-w-`tgARZGvrdIQOO_5%=0y)w2z@uiy@nWDTvj!rqIX8xk9|hy^KK1#Qys zUn@+mBu}87kICOiVt1kaXNE(5jz$VSXFZ7JCRF7YgzWiah6i?Zt>E6`_hM9q6Kkux zqETMxIew6j#@LT4(&p%!^@X+F_42~z7zEkfl0W0zhCoHfu`)D)a}#}wm4o|`X1@@tUjpFo`K#8#+TnEDL2OiKQ1dZl^lf9XHpW!-ne2~#Q`{n_^Gnu zq1~=krS?xZ5f}|HlzGdbseq!&S4}BONATGjDZvmh8fNx2y&f5DDOCj0saW`^1wZC4 zNpoBR?tD^nI*pgFyNQznHOO%+?Xv_GpZsrtlm&;Rp?>9fJpVe^dqLq#$c{zbI z?lC)DnL}B=1vg00!yC$X#wnlaPe?N=Fx7pjO9cX}wvP2T7<@+UKb4>-$CK;ae-?N< zj4#ut^UW=7*`4$tg|xecB!sV#?t@U4;;byi8k)c+2hdcAksYs$a8r~H~~yZ&1-_p(`2(|BGvf}~b}X6jR!sz?JWhFwPg8OU3`CDtp3Ikq)EYK+*_ zM0!}0q)}km;3B(Xw#aH!zgr02el!xo62LY_?=+VxinJ`Zcp98nneSe!hkWSS33Aoh zB17;uc5Le)41MSmWhd45(nzp@uv+LbF|>kazderfYB{G4b)wu>c!!xSaB`gh~)yLmi>&rIsdx5{!82y-ieu_K9n(Xo30 zT$fIS+O>BhChWp0{Q@h5FPK|{7z!U+1ll$jmn6=sjy{o4iZ{k3v2fdqSOA#r^-5-Y zMN?N*xLp&DYqZ>-*;ovbXn9Sp-AzpYkQ{(Fz9_n23pH#$+=%+i0n0WpJ(tyg_|lhJPQ-WLfej!oL{G0EnVT3Zxq=K3fDAlzU18 zB7LdQ23%NY7&xVqvrUU*sPA)l?xZmlLe*pn!H%g%bP)?Y1$pzSnjp%N5JQIY_~DM6}bf#RywtLIa;6 zDt$W5@y05%9KFkul(6nHMC=+KU!%du+8B+`hPHy`PyDgIf$aFcx)q;}4uhH~72$b> z+cTL51{ST3)9@Q>&zGGdppCr}#iXLM7iKn|kuLNkdE#j=gZ(xep7~`g{v$-fMa5ds z+ib$3IhKYb$!IUaMCDw$;*e>X_QsVoFuRt0qpyuIU7{uKWcZY&7EN9S%Rh5muT zV_6hnKDf3-C*9QfqM#%|xD7y^>pA%Fm#X>y=oX}RUH+J{bZd|NM2l#eoz;mWr541v F{{i05cM$*p diff --git a/doc/reference/cogl/fill-rule-non-zero.png b/doc/reference/cogl/fill-rule-non-zero.png deleted file mode 100644 index 2d8ad314c4baacc70c84b83b0b83b35e6a93a01c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3143 zcmb7Gc|25WA3w7g#$H5JmK2gKVKRlr(rarN?M#c(7=y7iqDwKD=th_OCJn~k-k2~eBOKie4q3AopYYw{`}7GJkR%6oQJc5tfnjg01B=y zPDcO$N(A3KWf0)qVVpAuJ|L7M&JF;JxAikPL0oWmb^_KUS3&*5+aL!S=Hg8O067&2 zL4a(=W{@cz;fg&ZEkLNt>uF0nrRIYyjfg|1A{;}>WI{*;;CP8}K7w#jCyEpipyTX{ z#hr{-R0katxjNY&yCRq#?#eDUR7T)t-!3=qjVbGTW1ah(=5;8qW^f?SRnvI!{zfbk z^!dL*6+iGim`*{t9ryQde}|;YBLH?)YW}$fVyiTuoE(M#bQs^ClG=~9liU_PV^jcT z9J6Nj_#Bd^Ahae{2Bc*(0w}YbdU-_vjEm<-EZ(=>4TwFt5*33U|_+*wk2V@IIPI1J9qG9&FhqYPs<{Owk(GXUHVfTU6#C3Et<%L_6=H<15vC<%!;(hsX)-ee7?~z^61JjzMu`bR_DOJ&_x1S9e^@o{fEQ_x1tt9~LkKv1r zKTgBN3Taje#m$EeVFgwTw)l!36fso${Y+)$E;>Yqv9hs~jozY!zEyv&S)Q6{8xki) z_HaYE7RpmO9k0$lPDBx(E$oQt7X*J^*u({Yjs}?k0pqkrJKO?@{?l;vrhw5w%bOJI zWk5QMYXrOZRi*IV-NnQ7>e&)3n8mEfYp!p)Xj65nc;m}h&4t(Y$G}9QC^w?UAYYC< z2+HyN?%%R}5ttdR^CPajqj?YN;K>1n1^v18(;hxAM=vX+C1?OG-iy@Cf1`-BbTuP7 zk^snGR9s{wu+iu6u>uw-Pu;>h3-!5$W7mBx&#~+_IZF#AFQN27yZ6)+m(-`NGRQFR zXG$_k`#!lFs&E?)4;;0#n%_Br{pC;0ol@?T$gFbEv9MTll{?J!9g8Un5BuK5 zp=mpM_r5DzojW|(47HzB4z)|7r`0rWSdLZisET}Xv8xo1Smv2`K?MgVF!4=SaS?Vx zJ7=DW&yA~;aZ@);OiZ|uGF|CrN88YXp=`kMM2*s!ms&dtu8A~d;9#{>v(jqT zx@`Eu-fo-5QvrT03lo_>5b{Eerw*9VhxtW%+vekB-bQH_O8+#a>*R+GfypLrQc&@E zyO7+pUzi)zIztrvn+8jdkI!UWjSC#PN>5uB`e}t^#E~e0B(2(;{Tw)T$~Ng|$=w4= zo=4R<9*TuH1W-*+UY)k}et!%s1MuE1ZOpmJL|_sWbkq<=#djpV-}!LB-U0>gEw9Q% zipcG8$$QUbfTsmB%xJl%n~@jpgjp6(_w|>Bn{ET!{maKn9#qgZ`YJ>N=pB=T9DoT7 z?FsBrb)cw>GCzjT)~iHUletkJz&!?7D5F&EYrR~T;$JNf&?@|4f{p&s$h~%W1W=Yb z%(waF!vJ5vn1TK=;QQb&^+;5|)sV2410Gq-L24B(_e8>PVBfw(h2X_4MABC>ML1WR ze%Yt!B*LNu>+@0A9k${VsLUcxh@O0)IAfmH_z~LVS9>4(P*W1Td8{k6ib$wW#_hEr z-=QRDIaR2p4joB6ulS_agFBe~u-^xmuUoA?Pj*8Sq;66X2^uZlyA9TM0(Z^=^9>KK zBOzD}tl3yAE!2n&ILY~AG=*KkI`qm<=Ht!B_t$0oF!m`yJ>ly|ZF^hasLxPz(Q9l7 zw6CeBWyQi9}G8cnU;qAB1ZjW^r zzYdxnIF!8#VXH_@qZGri%ujyHP?ORZaIEi41K* z3$ph~S8Oi~R_Q#_Ere4~kb*{3+n>NIurA_@5U>+3JbE59yL6hnw5#l^7`+Z&p5|N+ zoXK3-*exo6P{UBi4CS_PQ4p+)BpqhUo(>$DyA4t@YmyC~c<<$opfH%CQ*tH+%L0I@t}8JX!cHlY{~Nd&BjKk_IhKs>pHlj%o&TVxu7icI1xS zX69R56*6EKi2}utS450qRih*s|D5#5HpTTQYP=8`LaS5-7SjVR;!n2KD7-?~aX`P| z{=E()aDT3h66r;C~pU3x`5ag5}DUC57 z`*PaSAB2^yW1Ho$9l4>TK)*bt0Ak9?AQg#9v=WhMk%SVSgmjo_s_EdgWr+RK77dD| zo9YrVt8c! zAQJ1xg2TH%-fzZfdqs@$XA9TL4N#tHO(2d-G)-O+N9VL^ndL{4XnVylH7%U><)oRP zotJAV{$tNvJn6h9{*e y<{bqu5{34YKxrUl;;`YAegRT~^Z(xwRI|HEi+|4z8yuaqp`EUN3?>YD0bGLKuxu0{-=X?2YL4F8* zGkp*UgdmfMAsXAMk>7N6G#VdV_DN&3SzhGBx|)}z8_U!9dQ4InOH<$Tmw>&t-%i&A zO;dc1rGzr5DQPFp#DUV%(j4i@39OhC%s5BJ8QSe}yqTu4kxV>rIK52WpK&!Z&XhAX zy!E&})F>?W5L@^Wm4DGz_qg_k8}Xo45Yo`6zQHD*w02q#jL_L=bqf`*tz}>3d-;yT z@l8gBLX@t)?fLV%jwn=I((+Qro~}KZ@-IgQ_>G|z(XL!*B~dgnJ{Js)$`)>&H21AH^dlX44w#C+1g;<;EGvmQ0(n5L=S3lwOpc)Au8xWkvk8u(|;X2`R=g*VUY$U6O!;wVJ?MH! zGw-hxN|%U42T(GETIc-~6hN;iQo|Gb`7K5t8P4~)-@)B5QOx!`wg8*om`xogv*K}* z8Po$}`|0B8UQ!ndT@MzW*na0FAm=wGP%W{z6lz4`2ZPmO)t;fBU0Jrw4BE(u`(V<; zi7{=w56d;lbn=m&YOptKKu0iqVL4UDn3lO>)-fcXZY8MizwdCJ0aJ2_QgFRoT55MJ zE>Auk`gTjvcQstZ&dD-5_sxN^8EHQMtTsgQT561$X`NCL+f{Ie$|K%OA;v6_)|-dx z;JZu(Jxn&0OSRhU+!!~L2r6>ZFB3bS|L9PEJMZ%6F6O%nTM@haBkl7#~p~2V1!6=KhsWT z*jwPTdO$gf6n_)8feg#_c4qbgMA~;@U28U=2Y`XoZVW{WTnhd>EcqIbP?d3NK4MvG z?^;mo3;A>{6z4EkE?r3-?j3~Wqlaz-1@S?hNd_w@v_PDxu*qSW)v1jGFxh!voGXGLqY^9rQ|S*JPP9ZKXU#DQ9>33kodHLelNpoNSla)QX6ed{WmA zwCDP=e$(T=UBG8IyCId!dl-q0-@R!5u}E`eWqfc#&E@m3H&qvM z>dk11E+CAb@%5KE-vL8&5B&|u^)>0eMN%SRPtmrb6>xY3tAtcvk(=GR@lA}+vOBXf>ma)RGOeoVo z(>Az~yf2~0cXpRjNbWCm6HkEbf_)E$B0KTGe8qbwHho`M-TTAMzE>_kAcayxRxKX< z+r3jaz%<7x&y7ERe^GLE+lQ2kB{4rrO+)H|4Sm(( zb>LYNf6o?+`fS8*dgR$jTQ)#2*EHH^eZU9jwZR+@~o;h>wt!zy4$5$ z(1ypD=b7`o6!*#R>V4!-K=9(`bzQlN5*+6H%lMu+hf*0 z?Q@|gZ9+~|?b+ipa%3?6M)!WA6zZs>6Fq|mMI@0z3eYD#CbKCM?0C)HQyq8PJcJ=# z@>PL~`P5tu$I6@umUo>r%197p?J^otK-vI8itU+D*$%%a6xD_7kcFa1$ygEhI;znH^OvBu7- iLUDTR^7K~=tFVxb$A9t|_ej$G^gv{vAfm{Na{f;SUWiKo diff --git a/doc/reference/cogl/quad-indices-triangles.png b/doc/reference/cogl/quad-indices-triangles.png deleted file mode 100644 index 18c42c845ed165d3b15dbd431f905be823416276..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8018 zcmXw82|UyP|KH4zGs%5tqH?y8ifK8roRyL!d@;#LlKa|xBloO>k)s;A97W`wq){81 zkX&MLlAl^duTjZ!{x+Wic{QJ+JFrVw+ zJ7={!h9hySv+Lpc#$7{8c>|jxL&Kq+jQdL_dy_i#DxowRGI}bwq|nU+*Ggc1U4y&XC{Iy|CXvDHU+pFj>u z8_CNIwMC{uLrBYZS8e&z2o$E^hOFtMa~udqqXMO;*Z&7nQAX`z9Tq0~wlWNPEMfl6 zJy|p%+8}Kg4PQH~3_F*#tX~V$tDJ*Lvo6WF!OQ58687INxkt05kn)bJqX^9uKVRL{ zt582^<;e@8%^OBLw;Z6)q4)0%dF-@N$5k8Ykynm{%2$x6ZR(|aeM8)x*o`)BN=C8o z7sz^*W2P<=N&~jb&!JB=rsB988H36Qz6}%c?Y38RRo{ zu7(ysQ>-KQ-R)AzzQCBd;!dBTpCFuFGSIFW#nB$m&~@V;kpH+od7Sw1lFSL1saDf1 zsyt!tdyc3<<>CL9{CL%a90S(xU$`k=ys=r%j8Wj-cwC+aZ>jnRhh&RM9Z+z5rpIGd zC&}?!nKjW>ox z;FwL$-g(hK6<=*P2tiK9d4rdDH+K0-x)(oRIE;<`@y#Nj-JdQ^t#u}>Bx-kAN7UwS z(#NtsL4iWy|88ZT$@QTp5@LdC<3w1fWqL?iK`7_wM8kV>+ zZshf)lu!M(Zu;$rFq@d>@=qVFcT(M9>{Wv=CwTa+B5GLO@2a9P=nifo!aKHpnob9o zr@tLVU&cwzP@|D->4D7?g>^zqz}>Im71g4shOp+6w? z6RkZ>H2dX9sF*j>PbPcE-P}x*=tX0dnoVCtVg9cqF;aF}BAr1Rj4AJFBo;z5gMA)M zA4JMShjd;X6mq^TuKMN2Ka7vR2^ioae}ZquJ~vWgJ?jO?!xuJC?gWH;K{ zpQ~S^=tlacz6A;BR8m4Z1swgef@wa+a;2%&7QY&tGD1!GnM9Rt#BdME@9!VaHjGCPp(8Lo1Vn;0>bij~1cHk^y5yYfY4a#5{ixjNr|{i(;>azSv5x z8oe5WW#vZu>j@NR4igHz2SZ^d`_f0>``hDTvmFM)U43cO$z!!Yrw*g^opU0;&Rylm z$-BO=4p^^7>r3+f@~{brd`)5YPUpu_m|{^H{iqk()?-iJ{$f~4>w7s{ei^AP{!!9- zwL9)&=HQVyBL~U z(0aZ%?(Ay8%ij7J>-DOZB=Wo6t3o;HKiW@Q#f2028Ti@_QC#)Dku%RzZ#G!6gr>Fl zT0W^xU*BNWz4?X4bI zLk+tcX_luH*7{C!Wgj_>A8OQqz&6>|L6l;?Sss$QZh zG!->oDX34Q+DifMtRbtg>)%7}3rCsL0|n!v)m#urA@w4kU*#qm zV!HLb!YfVRO5gl(MQhH5mZ6?@KM3#P+h;NV%cXyI5`Kv%{mydzr3g_u65gUiap7}u z+rsT}Yg#4kE_rr({PXaXOujttlb!R{*gVk#s7mMg+MdxjiKWqs&HH2cUMp@z#eN#g zzA!z8tLCZLhn~H5gnfA90aFuO@NLCqr%bmiE1Qz8dUtvxPm{s-p=iQPYVqIm_%=`)xEdOM9wSC>l2xGDViCq*M|;!*6co#cP`EQB)Cl#-v{&Az;tX>m$L$(-hWl71#LU?Tl`Hv8uN5S@n?lq(NY)bT@SLG_%=l(mT zFv^=eU6){5Q9H=^_M|nE*Ea6{8N!WenVbB2Vu2YHMM=Lre&#Wg?-WTL{?8YAEbomQA*EiV&TWfAG~k$c^b){SDwRuOHwiuA`iP=l;)T|l^*{h zlbvnSzJr)REn8Knl->OSCbpY8rC+5&Zo0FKj5?0FX1ffZC#Ar8jtUWHpRB`Vv0E)A z%K5+*&oP$r!aN!D`_908itANe+wXOZ!~W=nDmkp1)sbEH3*j{?P7%WV%WaYTX-U*9 zg29xLPU)L!8ZXjiZ|O6Ysr%@C>5_;vzH_t*&XO=sXNHoQpXxLc%Rh#^^2doJ4SVMe zmBKh2iN2r!MQlo(&r2uNNmj#^(turN(UDStjZzhnchb(ypBQ{j%CfxEQ%mClD${4M z>tlX*qRx|~`IYo5UC)H=kb_~ncn-j_`bnX5Q;C$l29mso$-C)-SUYvF&3R1(&BV*gQ}t{w9&?>wwu$^6vD=~&6$myH$w|3 zk2%ylZ&H~`Kb`Ce$7VsEji(&`N|Am2kV$ zI~_t+YE4|N%k1GGZEK#Ny|;t(zw<* zUBSiuVPS2ntfNBjkF$)T&M|+&JLb<<)idz3Phs(eb|~{}&sC=J?0U{Ww&6Jb0A%HD z=JN-}{LzWj(D{8Obca0gTB%IV?qyXGr^^VFe-oWj_gN*xVrLIl)|E+$qja3dd%6g} z=5KypVx(xGH&MF^h!H)3ZQ?2}s2DRg?^EQSem@7{7eJA;-Bplt-)egQB^8u zcNLVSye%m_gtEBy?>^bgM3@U?PIB@=ScXUQ;qqJ zeICtYCM1Md%QQI7ki}>sk2pK|3h3gSkad;Z(JzTxlPiFi9xt zsS|u}&icg}nrW7%T15#KClza@>#3^+xw&hw9}ydP^+p&We_^pj`|j>`$}IhDiTl&b zU&ha4SO#IdUwYuamh6+rdZP&8QnP!UD)|ZxZW)Nhx&R0HZ_I+rpQz5kjlFO}CEG}} zUI_o)we2dxyjc_2pvhGd6}t1jm`h4?`gjVswG=s@raUt2$aPg{y=Kd;{GJUDW(wR_ zAh42>=Z)j`_0rFzyT!eYZwJ@+*(m+;O278piTHPkMcc*r$VpC=5M-&a zop2%kz_+Nj3-FyWrssZuy-94?iT)W_u-r*}Nm|}jAs6T&5`NVEI7kDZwkrVonhE;y z#tS0KWZn;1|Am1&3CJT}OD!nY_)l47YP&1w<D8>B z>?wk9y&0>Tzt0K@b;=zOK<1(wD+`5R0&j%Iq}29%s>z-jRuQ|Jsdd!}4Z43Sa1W}= zhzB!+cg!oYZxS6lZW(JF+_NrrN}>K37{EgyE02z-1<8zfel`Z@Xdz6}O&jWK6E-~e zsJ$HB+4h3pN{*llT|14*fxm8JblysB@58Xx$<^;B=72@PuC^D6RylF2QYZRJu|#{5 zjSGJv$6sJIe+Bc@%RFBp$)0JwF;>ijog1(8Nv8sDH`v#ZE{AGg6rvC&srD9tvt?GsXGt#PKTXui4|PDAGR@Y?W5;qMMPtokGYcl&(wB06Q2f3dP&@k z?Q710g=LK86F>3Yzr{b@nK^XcK@jj9mbMn0FCK30Wo`%}jU-SHE$Fs(IMQ89Ge)!B z47Obl#}}ZKwX9$SH^?Ip%Hdn%pRHdiwO-?R_a24+{z2Qsg&T37p2}PH6EI=J< zL+)_`kk8)#(5P<*Hk56WkSN3ora9w6Dk&n^?cy&?3%Coh8;QodIhB;3Ss)-!U@VR; zXPX`EELFXlBqrykQ~IpX1~Gin(4$aAghvPD^c^T{UgmNw)hy0GPE2s|4XqVd?ey2X zM!xvrhY1aeN|#>-gXD&qUz<@w4F7A7jC`oVgj~eqoN@+Ixls8lrVF8MsqO0XRt@d9 z@G1|DR#eIP^pe}I7tBUvw~lLN_MLUuOST+OvbUF{0t-E0p$}R*pBCWgW3H3tcG@4@ z*+Gt+|4wMK*I?3Q!9|x#Tf39SvjwnDkOQzSO)EEOnL(ux1MdJXC~LK5#prKqZNAsqea3^qr&Ljck+ornZf!^#wYaEf&>C@Q}PsLGr#U^)93mQ zp+RXr@NkQ$xcTD0kk{WB8`d_MG>dzITlodxtC_B@I?ZF;@%<|ibpYKqgF?!a{>Sb2 zXdaFl=xF|e!hJ=J)fNHEpETRh z$g;U7UMm~8d)^y!Nn%d_dER#5N^k6QJOxk72Wsi<1&xxgnJ#kdo_M%ih3NbROuoFB zjmh5eG9Y|cq4GQ$T+J1YVWpR+6Vpyj^r92b= z4KUY1z{6rCA(oRw4uYs$6xwGBEZJ6T(iMDxmqfz-+=&$J+`p(8i+`sfMV%%HG4Wnr z<|`m{TW;uj725O7#0E_z$BGl%kc<#72njnS5*`WKrr-P;eh*?eZdK;b1ri^uS-0#2y+M%98V2k$ZHXsm}4GA}ia-If5rGSO&D3Cwb!G zMHE*B*~~NcyXkw)!CY4ltB2hdTs+8$ZujSgyeCUM+*Tx9m;Ipq*8L;kEPb*LIIBS0 z3OwOCRJo+4_VNaZHI!!sj@EAfFd>`iQXJZMAKWhpu_=;qr2aud6l6Y*qD|V4R_Bd! zU&DD)0_0HcfHP1N6R?g!$$vC_UDzsM6mojQFL3q#wiNFj7n`%}C5gdjGg8~jK=v|7 z!D#f}MK`#wp?ei2Pfj+oG@iPO@P{gJCFd!}@e@!~KT*(HNJJWaPIvemNjSrz9;^n~ z04+@stk3uvF+XqfkpP^ArKOj_f-*}ibJ@*Zf_)h{P6RW_Sdu?neb00k2fH*2s7--? zNLDse5qP%m0HO--gJ05ZUt*iIKiV_?)|5&Z5 z0k&!atk#LF{K1@gwynls_T$6vXmBGP0FWpSJ%>J};Ib2|3l51rYc?WPklSdptr~T3 zQ(yEsQZc_}_J9G-@JxiySMjzN7MaTwDvY4a?KPSF*-97g1t$;g(JfP*ivz54x9@B? zDDpMLrf5O#W(^S~^P0iXN!u1G4e|;!q!>hoHC78MS?**>wCNvXRfg4deKnXICY)g4 zKT?Z{r!#{M(7IdGM3h9}U5cw0uBRmQUb<#F6ik7OiL`vcZ81X4Vzst^(Jv_WQPJ6K zMBXjm6KE?-96W)EqgoT@AYiE5UN44j)n8Er*-|8IKF$+A{E<;@HTQfjX~_i!GeGfl;d;`!yx7YH_`Bu~Jl3+8lGn1}UFC;yenDe4IoTL-@lsWH=2f<;1S1 z1A5!?ya`vHz3wOSThIMDg_+fNmTNk-3){@w$9rj?RV6GIRe1(<k9pa>q4SEj#${{_$g^#c!m$8MaXoP^One`A90Q=upqFcn=(I15rG#%H8Y@RY zB-wirjeO5VHi%%NwVhwMdSLG%sXGbOqYJmcwZeT>0uw01EF0O(Qws6Edq3RT*jI6Q zJ^-VXOn2o9EfB3sK%l#xs9qHXn_NQC4FiAkYr+v})Q=oa%?|G7OQ5*=;oP`F4Z{{# zAKCpm2ROPJm&m|_8Lt>r9ODY+Jaqi{8@a_0un=4Y%jcbBYVHE%T!u6tMz`F7-n9GT zvYB0qb&=Z-M*&9}fPl~#7BWnUeU~e_ub5DysC-4)tjj#O=aCU# zbOJR){b#bzR`h97R%^kbKy7;0MpKUvcVqagw}7O? z)cwU~#G=lT62X4QLUIqpl9rABOfG(tTT~4j>h1sQ_$EgnF-wr8g*wKKLq(Q6l2v68 zs0sFk(U$LH0bKEwBJX84wtY01Y@L6SSmXs5LYS;Jtq>*E_6(>j+Yov5#lS=vF<))k zHEM;C33{k3p#ary{qq1i4ztfHLZ%=w(g$+|mJWNDJ#g{=l`_4nKekk*YsZiWj$UHy z3l0VA!C)Bq!vc4Bi(i#FXTMFMVr(_pS#2wS+K#YH8#1>dns>Ek|3iSswoKxN0oWLh zZqKuz3xCC(d2APTA;WwdI0?sC!yNCGcrKjkC}~%UUq34h_0nK^E*wY+6ZF1rp z(Q2S+^tglHwsPF^Q@=dDRd`T8qPvHxx?a_b5 z`2a^S`+ISe+wJ76|_i z41-B~^*9gXrpJ*x@3c&i@97SjJLuq6qS@itjNbKECBCO? zsNy(7S&m2ECNIXmwrbs#_$QqzzxLm&k|*C~cro3hNe_%MJ9!O2>+)hgc;I>{&RO== zk-^UXxF75e88PgdQ{Dy~GpvVfExD_mT%NUwnok~YItB51P#ZahER}*wLHO91di${+ z@vhq_bxOnF_+{JysMtg!<7egFuf#&t_CEQ;BAX?1BuJY_(KX7rFQgVGrUpY#;8&PmwrpS|;HQ{XWpU&hAf;$`)|_x=UL z&K}^Y5a0ZVi#>v8k{?k@2|mTH&?t33r9{(?9Yo82!UEPWVhcj5Jy(_&US8~}XgVl~ zQW$0Wn|_JkRPOQ@`!IUFLDEfEY9pU1OZ&))rWZv_=n4F1QB7mX)fP90R$onzovdzl zb~}MlBS+h<@P1?dv7Ku1_$^a~eWlcH^Y&5UY{v+-1|44*V3l)!SUHD(tK0Nre5+Ku ze=|$t9WmiJ%gdeNs8k&k5E<2Eln(36TBctD4;|5n`qY@i>-`dao&Fi+&5sHPI_zFY ze#`li@`yTDRI{5mI)x$vt7aN()@tcu%&znO?7A?*UzS$ei)mJue~%=t2ot_9@J_2_ z6Df)!GxzDy^-ySby?ei`|)BVLMU#2a1-h+*2+tVac8QfQ7r4M%VSY z_#oygB=fJtZBXP&6$;oh7#r10kF`(Do+;J(;8mN$u?QKFl z!qp-FSz%_oU4G5@0qJu_@*HgGP#56c9#7n}apkpv%Hj-yBBG5|3f1#2{V_gwHS&Rc7pjQS-p1@OUoBo`n=Zj$-ScJevTRw@sn=i*BT^ zbSQ{BlPxDc$BDiN2a-st?-XnH!EGENM}Is!ZBZ&^hRD1Nl(jR45;w@EGIyZr2CTJdV#geOD(hB$t*(P^~TSfg5Hg zPXIZwrAKfgS|z_s#r$e9evy8|ufpc4n+muj-kcoTEl~!UooQQGi#@-BjZkS({0%<; OhF~r1%*&3u6aNpuN&@u& diff --git a/tests/conform/test-cogl-texture-pixmap-x11.c b/tests/conform/test-cogl-texture-pixmap-x11.c index f9b4099..abdef12 100644 --- a/tests/conform/test-cogl-texture-pixmap-x11.c +++ b/tests/conform/test-cogl-texture-pixmap-x11.c @@ -7,9 +7,7 @@ static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; #ifdef COGL_HAS_XLIB #include -/* This gets installed to a different location so a real application - would use */ -#include "cogl/winsys/cogl-texture-pixmap-x11.h" +#include #define PIXMAP_WIDTH 512 #define PIXMAP_HEIGHT 256 diff --git a/tests/interactive/test-box-layout.c b/tests/interactive/test-box-layout.c index 5e46b28..e354faf 100644 --- a/tests/interactive/test-box-layout.c +++ b/tests/interactive/test-box-layout.c @@ -23,7 +23,7 @@ #include #include -#include "pango/cogl-pango.h" +#include #define INSTRUCTIONS \ "Press v\t\342\236\236\tSwitch horizontal/vertical\n" \ diff --git a/tests/interactive/test-table-layout.c b/tests/interactive/test-table-layout.c index c3c1877..d0a0312 100644 --- a/tests/interactive/test-table-layout.c +++ b/tests/interactive/test-table-layout.c @@ -5,7 +5,7 @@ #include #include -#include "pango/cogl-pango.h" +#include #define FONT "Sans 12" -- 2.7.4